Friday, June 8, 2012

Chrome Extension Boilerplate

Not too long ago I wrote a simple Chrome Extension for my brother-in-law to help him quickly fill out some online forms for work. While I learned the basics of Chrome Extensions, I was hoping to find some kind of super-simple example that I could use as a starting point, but wound up just doing everything from scratch.

After I finished the project, I decided to create my own boilerplate.

It is very simple - it only contains elements for a content script, and includes jQuery. Clone the repo, change the name of the extension in the "manifest.json" file and get to coding in the "main.js" file. Have fun!

Link to repo

Friday, April 27, 2012

Updates to Google Voice scripts

Google changed the way contacts are downloaded, which broke the mass contact feature of a couple of the scripts. I was able to spend a few minutes this morning taking care of those issues, so everything should be back the way it was before.

You can find the latest version of the Google Voice scripts on my github page here:

https://github.com/hillmanov/gvoice

Enjoy!

Saturday, October 8, 2011

Login problems solved!

Thanks to another reader (known only to me by 'First Last') the login issues have been resolved!


It turns out that the problem was much more simple than I originally thought. 'First Last' pointed out that the query string parameter 'service' needed to be passed along with the value of 'grandcentral' (which is the name of the company that Google acquired in order to bring us Google Voice). 


The change has been made, and the latest versions of the various Google Voices script can be downloaded from my github repo.


From now on, my scripts will be available at that location. It is much easier for me to maintain, and for users of github is it much easier for you to keep up with the latest version and contribute back if you wish (which would be nice!).

Saturday, October 1, 2011

Login problems

Some of you may have already noticed, but the gvoice scripts I wrote no longer appear to be working. The script will either crash or report that it cannot login.

I am aware of this issue and have looked into it. Google changed the login screen again, and despite my efforts over the last few days I am unable to find out how to authenticate programmatically as I was before.

If any of you have figured out how to do this, I would love to know!

To the rest of you: hang in there. I know that this script has been very important and useful for many people. Once I figure out how to get around this I will put an update up here and in the git repo.

Wednesday, January 5, 2011

gvoice.py - Updated!

After too long of a wait...here is an update!

Big thanks to Mike who helped me by showing me where to get the newly required "tok" variable when downloading the contact list.

I haven't been able to setup py2exe on my current computer yet, so I do not have a standalone .exe version yet (any volunteers?) but the following files are now up to date:

- gvoice.py
- gvAllInOne.py
- gvMassContact.py

Get them all by downloading this Zip file

Happy texting!

Saturday, January 23, 2010

Python - Easy jQuery lightBox Gallery

If you ever have to put images up on the internet, I recommend using the excellent jQuery plugin lightBox.

Not long ago, a relative asked me to help her with her website. It was made by the previous webmaster using Microsoft Publisher, and was a pain to maintain. Updating the site was especially cumbersome when she needed several images put up in a gallery. It took a long time to resize all of the images and put them in a table - normally around an hour or more. I rewrote the site in PHP and created a neat tool to automatically create a lightBox gallery for me - all I needed to do was drag and drop the folder with the original images in it onto the script file and I had my gallery ready to go! I thought I should share the script for those who may find it useful.

Fist off, however, you will need to install the Python Image Library (PIL). This handles the resizing part of the script.
You will also need jQuery included on your page, as well as everything needed for lightBox.

Once you have that set up, you should be able to use my script: (I don't like the "all catching" except, but it was useful for debugging)

import os
from PIL import Image
import sys
import glob

try:
base_dir = '<insert the full path to the root directory of your site (eg. c:\\sites\\myawesomesite\\)>'
img_dir = base_dir + '<insert the folder where you keep your images (based off the base_dir defined above (eg. \\images\\)>'
thumbs_dir = img_dir + '<insert the folder where you want the thumbnails placed, relative to the images dir defined above (eg. thumbs\\)>'
originals_dir = img_dir + '<insert the folder where you want the originals placed, relative to the images dir defined above (eg. originals\\)>'
web_base_path = '<put the relative URL path to the images directory (eg. /images/)>'
web_thumbs_path = web_base_path + '<put the relative URL path to the thumbs directory (relative to the images dir defined above) (eg. thumbs/)>'

temp_gallery_file = base_dir + '<put the name of the file where you want the gallery code to be stored (eg. TEMP_GALLERY_FILE.html)>'

column_amount = 3 # Put how many columns wide you want the gallery to be

img_display = """\t\t<td>
<div class="image">
<a href="{0}" title="">
<img src="{1}" alt="" />
</a>
<span class="description"></span>
</div>
<br />
</td>
"""

if len(sys.argv) == 1:
sys.exit(1)

resource = sys.argv[1]

# Default width, if it is less, than the old width is used.
thumb_width = 200
max_orignal_width = 700

# Keep the aspect ration (based on the width of the image)
def aspectRatioSize(desired_width, original_size):
original_width = original_size[0] + .0
original_height = original_size[1] + .0
return (desired_width, desired_width * (original_height / original_width))

def getNextAvailableName(folder, img_name, ext):
index = 1
while os.path.exists(folder + img_name + '_' + str(index) + ext):
index += 1
return img_name + '_' + str(index)+ ext

gallery_file = open(temp_gallery_file, "w")

gallery_file.write("<div class=\"gallery\">\n")
gallery_file.write("<table>\n")
gallery_file.write("\t<tr>\n")

base_image_name = os.path.basename(resource)
images = [image for image in glob.glob(resource + "/*.*")]
# Loop through all images in directory, make thumbs and resize the original
for index, image in enumerate(images):
index += 1
print image
img_name, ext = os.path.splitext(os.path.basename(image))
im = Image.open(image)
img_size = im.size
thumb_name = getNextAvailableName(thumbs_dir, base_image_name, ext)
modified_large_name = getNextAvailableName(img_dir, base_image_name , ext)
original_name = getNextAvailableName(originals_dir, base_image_name, ext)

# Thumbnail
thumb = im.resize(aspectRatioSize(thumb_width, img_size), Image.ANTIALIAS)
thumb.save(thumbs_dir + thumb_name)

# Modified Large image
modified_large = im.resize(aspectRatioSize(max_orignal_width, img_size), Image.ANTIALIAS)
modified_large.save(img_dir + modified_large_name)

# Original
im.save(originals_dir + original_name)

if index != 1 and index % column_amount == 1:
gallery_file.write("\t<tr>\n")

gallery_file.write(img_display.format(web_base_path + modified_large_name, web_thumbs_path + thumb_name))

if not index % column_amount:
gallery_file.write("\t</tr>\n")

if index % column_amount > 0:
gallery_file.write("\t</tr>\n")

gallery_file.write("</table>\n")
gallery_file.write("</div>")


gallery_file.close()
except Exception as e:
print e
raw_input()



I also use the following CSS to make the gallery, once created, look the way I want.


.gallery .image {
margin: 0 auto;
text-align: center;
vertical-align: top;
}

.gallery .image .description {
font-size: 11px;
color: #000066;
text-align: center;
display: block;
line-height: normal !important;
}

.gallery td {
vertical-align: top;
}

.gallery table {
margin: 0 auto;
width: 90%
}

.gallery img {
border: none;
}


Once you have all your paths defined correctly, you can use the script by simply dragging the folder with the pictures you want in your gallery onto the script. Keep in mind, that in the current script, it will rename the pictures based on the name of the folder they are in (folder_name_1, folder_name_2, folder_name_3...). I needed something like this to avoid name collisions (it checks to make sure the name is unique).

Once the script finishes, the HTML that the script creates will be in the TEMP_GALLERY_FILE.html file (or whatever you named it). Copy and paste that into the site you want the gallery to be, and you are good to go.

I will be posting a demonstration video shortly.

Saturday, December 26, 2009

Python - Google App Engine + Boggle Solver + Web2Py

Click here to go right to the solver

Lately I have been experimenting with a Python web development framework called Web2Py, and so far I have been very impressed. As with any language/platform/framework, there are those who love it and those who hate it. I happen to be in the group that loves Web2Py. I also happen to like Django, another framework from which Web2Py received a lot of inspiration.

One thing that I really like about Web2Py is that it is extremely easy to get running - no installation is needed whatsoever. Download, start up the built-in server and get to developing. No configuration is needed either (You can visit their Home Page to find out more).

More importantly though is that it runs on the Google App Engine without any modification whatsoever. That is one of the things that made me choose it over Django when deciding which framework to use to put up my latest side project. Django does run on the Google App Engine - lots of people have done it, but there are too many complicated steps to get things going. Not the case at all with Web2Py.

Several posts back I posted my Boggle-Board solving code. It runs from the command line, and is not too user friendly. I decided to wrap a nice GUI around it and put it online. The resulting Boggle Solver can be found here.

Things to note about the solver:

  • I wrote this app because I was unhappy with all the other online boggle solvers out there

  • For the random boards, I use actual Boggle dice configurations not just random letters

  • Written completey in Python using the Web2Py framework, running on the Google App Engine

  • Uses a dictionary of 170+ words (I am pretty sure it is the Enable2k dictionary)

  • Visit my blog to see how the words are found



Enjoy!

PS: If you are a CS student somewhere and you have this same assignment: Do your own work.