Linux: Run a process as daemon in background from SSH

When a process supports daemon mode, you can either run it in a screen instance or init.d script.

If you had to kill off a rogue daemon and need to start it again via SSH, you can restart the daemon with a very simple addition to the command:

For example you have /bin/daemon_process with the parameters "--daemon --log-path=~/logs/blah/"

You can execute it with:

/bin/daemon_process --daemon --log-path=~/logs/blah &

The extra & at the end makes it spit output to the current terminal, but it wont wait for the daemon to finish.

Source

Android: Issues with opening files in Cyanogen Mod 7

Some people contacted me with problems trying to open files in my CodePeeker app on CM7. The OI File Manager built into the CFW is returning something unexpected, causing the app to fail in opening files.

This resulted in a few "1 star - DOES NOT WORK" ratings...

This is MADNESS! Why!?

The reasoning behind this is because OpenIntent's OI File Manager wasn't returning data according to the Android specifications.

They've written a small blurb about it and provided the backward compatible code here.

I didn't realise this but apparently I've covered a neater version of the code in a previous post.

If you ever need to test it, install the app on your emulator. The old version of OI File Manager v1.1.4 can be found on Google Code.

Testing

You can test the normal behaviour with File Expert, a great app for browsing files. Astro File Manager sucks with ads + confusing user interface. You can grab the APK for the emulator here.

srvgq
Crisis averted!

Sources

Python: Make transparent areas in PIL image to white (or any other solid opaque colour)

I had some issues with transparent PNG images causing some strange effects when resized and saved with Python's PIL Image library.

image image

image image

As you can see, those jarring effects are hard to ignore.

The issue was I was ignoring the alpha channel during conversion and PIL didn't quite know what to do with it.

It is a bit more work, but the results speak for themselves. Even the GIF image quality was improved after using this method!

image image
You'll have top view them at 100% to see the difference.

Update 6/12/14:

I found a better way of colouring the images which had NO loss in quality (updated code above)

345_shirt_438cef451b28326350794f77d38fe83d_B 345_shirt_438cef451b28326350794f77d38fe83d

(Shirt design "Majin Power!" by ddjvigo)

You can easily see which one is rendered with the new code as the difference is quite noticeable.

There was a bug which replaced the whole pixel with white, which is wrong because it could be any other colour with transparency < 255.

(Here's the old code if anyone was wondering)

Sources

Django: Set datetime.now() in a Form

A tricky little devil this one. For instance, you've got a "created" date in your form and you need it to be set to the current date whenever the page is displayed.

So immediately you go and do this

class SomeForm(forms.Form):
test_datetime = forms.SplitDateTimeField(initial = datetime.datetime.now())

First load, sweet it works. But load the page again, and you'll realise the date is still the same! FUUUUUUUUU!

1283775594667

It seems that the initial date/time is resolved when the server is first initiated. So, how do we fix that?

Easy!

class SomeForm(forms.Form):
test_datetime = forms.SplitDateTimeField(initial = datetime.datetime.now)

Can you spot the difference?

uhERp

Just remove the () from now(). That's it! If we pass it a function, it'll evaluate it on display.

PostgreSQL: Fix for "Error connecting to the server: server closed the connection unexpectedly. This probably means the server terminated abnormally before or while processing the request."

image

Error connecting to the server: server closed the connection unexpectedly

This probably means the server terminated abnormally before or while processing the request.

If you're running Windows, PostgreSQL and you've seen this, it's probably driving you bonkers!

No matter what programming language you use, what interface library or even the default client, you'll get this damn cryptic error!

Thankfully, the solution is simple. Postgre is fine, your setup is not broken.

NOD32

If you've got Nod32 antivirus, then it is known to have some incompatibility issues. Apparently you have to find "postmaster.exe" and add it to the exclusions list.

That can be done via "Setup" > "Advanced Setup Tree" > "Antivirus and Spyware" > "Exclusions" > "Add".

NetLimiter

Otherwise, you'll also have issues if you have NetLimiter.

image

I'm still rocking the old v1.30 so these instructions will vary with the newer ones.

  • Find the "postgres.exe" entry
  • Click on the "Info" tab at the bottom
  • Click "Ignore all traffic"

This worked like magic for me, so I hope it helps you too!

7386_1df8

Now back to practicing things that matter, like walking on air!
PS. SHE IS HOT!

Sources

PostgreSQL: Alter table field CHAR length

So the annoying thing about character fields is that they have a limit.

When you try to save the row and the data is too long, it'll fail.

So to increase the limit, run this query:

ALTER TABLE tablename
ALTER COLUMN url TYPE varchar(500),
ALTER COLUMN description TYPE varchar(300);

That's it! The fields url/description will now have the lengths of 500/300 respectively and maintain the original data.

notsochewyballoonsp1
BOOM! Headshot!

Source

django: Filter by field value in row on model

A bit hard to describe in words, but easier in an example.

Say for instance I have these values in my database table.

id | rowA | rowB
----------------
1  | 3    | 1
2  | 3    | 2
3  | 3    | 3
4  | 3    | 4
5  | 3    | 5

To find the rows where rowA >= rowB, you just use the F class.

from django.db.models import F
Model.objects.filter(rowA__gte=F('rowB'))

So easy but never crossed this before!

0D00v

Source

git: Ignore dirty or untracked submodules in diff or status commands

Git 1.7.0 added a feature which marks submodules as dirty if an untracked file is in it.

--- a/article
+++ b/article
@@ -1 +1 @@
-Subproject commit aba7c80124b0ac07299f224f1bf7ddd4c9a095e3
+Subproject commit aba7c80124b0ac07299f224f1bf7ddd4c9a095e3-dirty

...

diff --git a/south b/south
--- a/south
+++ b/south
@@ -1 +1 @@
-Subproject commit 6512510da9a408b178730f38fcac664483451ab0
+Subproject commit 6512510da9a408b178730f38fcac664483451ab0-dirty

Personally find it annoying because the files there just patch files or something I'm saving for later.

git status

# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#   (commit or discard the untracked or modified content in submodules)
#
#       modified:   article (modified content)
#       modified:   south (untracked content)

So you can see that "article" has files thats been modified, while "south" has files which are untracked.

To ignore this, you have to add the --ignore-submodules flags to your diff and status commands.

git status --ignore-submodules=dirty
git diff --ignore-submodules=dirty

Sources

Android: Managing AsyncTask, progress dialog and screen orientation

For my app Moustachify Everything, I was getting quite a few 1-star ratings when users got a black screen for the results.

It took me a while to figure out why it was happening. Because I test on WiFi, the images upload quite quickly.

When testing with 3G, I accidentally rotated the screen and the progress dialog was cleared, leaving me with just a black screen and an ad.

When the AsyncTask completes, it updates the image (in the old Activity) but the image in the current Activity is still black.

To fix this, you'll need to keep track of your AsyncTask. It sounds longer than it actually is, but you'll learn some new tricks on the way.

The AsyncTask

If using an anonymous instance of AsyncTask, extract it out into it's own class or into an inner class of the activity. You'll need to be able to store a reference to it somewhere.

Important things to do are:

  • Keep a reference to the current activity
  • Keep an instance of the ProgressDialog

The Activity

Using onRetainNonConfigurationInstance(), we pass the new Activity the existing information about the AsyncTask.

This is how we update the "current activity" within the AsyncTask.

Important things to note are:

  • Keep an instance of your AsyncTask
  • Implement onRetainNonConfigurationInstance()
  • During onCreate(), check getLastNonConfigurationInstance()

A working example

public class SomeActivity extends Activity {
private ProgressAsyncTask m_progressTask;

// This is purely a data storage class for saving information between rotations
private class LastConfiguration {
Drawable drawable;
ProgressAsyncTask progressTask;

public LastConfiguration(Drawable drawable, ProgressAsyncTask progressTask) {
this.drawable = drawable;
this.progressTask = progressTask;
}
}

private class ProgressAsyncTask extends AsyncTask<String, Integer, Bitmap> {
private ProgressDialog progressDialog;
private Activity m_activity;

protected ProgressAsyncTask(Activity activity) {
setActivity(activity);
}

public void setActivity(Activity activity) {
m_activity = activity;

progressDialog = new ProgressDialog(m_activity);
progressDialog.setMessage("Growing your mo ...");
progressDialog.setCancelable(false);
progressDialog.setMax(100);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

progressDialog.show();
}

// Just some example code to update your progress dialog
protected void onProgressUpdate(Integer... values) {
progressDialog.setProgress((int) ((values[0] / (float) values[1]) * 100));
};

// Once we're done, make sure you reference the activity
@Override
protected void onPostExecute(Bitmap result) {
ImageView img = (ImageView) m_activity.findViewById(R.id.imgResult);
img.setImageBitmap(result);
progressDialog.hide();
}
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.result);

// See if we've got any information from the existing Activity
LastConfiguration lastConfiguration = (LastConfiguration) this.getLastNonConfigurationInstance();

// Screen was rotated, re-apply data we already have
if (lastConfiguration != null) {
ImageView img = (ImageView) findViewById(R.id.imgResult);
img.setImageDrawable(lastConfiguration.drawable);
m_progressTask = lastConfiguration.progressTask;
// Update the task because it is currently pointing to a stale activity
m_progressTask.setActivity(this);
}
// New instance of SomeActivity, fetch image
else {
m_progressTask = new ProgressAsyncTask(this);
m_progressTask.execute("http://www.url.com/to/file.jpg");
}
}

// Remember the information when the screen is just about to be rotated.
// This information can be retrieved by using getLastNonConfigurationInstance()
public Object onRetainNonConfigurationInstance() {
ImageView iv = (ImageView) findViewById(R.id.imgResult);
return new LastConfiguration(iv.getDrawable(), m_progressTask);
}
}

Source

Android: Fix "Error generating final archive: Debug certificate expired"

Now this was surprising. I had to update a project and I guess it's been over a year since I've started Android development.

Apparently Android SDK only signs the debug certificate for a year. This can be a bit annoying because you have to uninstall all your testing apps after you create a new debug certificate.

  • First up, open up Windows Explorer and paste in "%HOMEPATH%\.android"
  • Locate "debug.keystore" and delete it
  • Now back in Eclipse, hit Project > Clean in the menu
  • You should now have a new debug certificate.

If you want to make the certificate last longer, see the Androidian link below for steps on creating your own certificate.

Source

Django: A simple order and distinct query

A common query in SQL would be:

SELECT DISTINCT type FROM Item ORDER BY type;

In Django however, it's a little tricker since we've got the ORM.

Items.objects.order_by('type').values_list('type', flat = True).distinct()

Unusual? Yes. Impossible? No.

Excel: Creating a dropdown list in cells

I've seen this a couple of times but never got around to figuring out how it works.

image

  • First, type up the cells which will be used as reference.
  • image 
  • Select the cells you want to apply the "dropdown list" to
  • Click on Data > Validation
  • Change "Allow" to "List"
  • Click the little weird icon in "Source"
  • image
  • Select the cells containing the list of items
  • image 
  • Confirm by clicking the little weird icon on the right.
  • image
  • Click OK
  • Now the dropdowns should be enabled.
  • image

Source

Python: Setting up PostgreSQL support in Windows Python

Took me some time to get this working but I finally got it!

You can grab the Python 2.4 to 3.2 binaries (for both x86 and x64) from StickPeople.

  • I used WinRAR to extract the contents of the EXE by right clicking the file.
  • Move the contents of "PLATLIB\psycopg2"
  • To "your_python_folder\Lib\site-packages\psycopg2"

Source

Windows Live Messenger: Disable "File Transfer Warning" notification when trying to send a file

All I want to do is send a fucking ZIP file to my friend.

image

I'm not going to install an antivirus just so I can send files. Security in airports I can understand. Over-zealous security on my computer? Please go away.

I don't have an antivirus. Seriously. Common sense has kept my work computer safe for over 3 years now.

My solution? Fuck installing an antivirus and just run the command prompt.

  • Tools > Options > File Transfer
  • Tick "Scan files for viruses using"
  • Paste in "cmd /k exit" into the textbox
  • Click OK

image

Solution works brilliantly. No black box flickers, you can send files without any complaints and no registry hacks to allow file types.

Source

Diablo 2: Getting PlugY to work on patch v1.13d

Sad to say it, but I've been hooked on a 11yr old game again. The latest patch however is not compatible with many hacks and mods. At time of writing, the latest patch is 1.13d.

One of the most popular mods being PlugY, which increases your stash size and allows you to get Ladder/Online Only rune words in single player mode.

To get it working, you'll need to downgrade. Sorry, I don't know of any other way.

Ingredients needed for this cube recipe are:

Rather than reinstalling, simply download and install D2SE. When you run it, it'll let you select which version you can switch to.

image

  • Select "1.13c LOD Vanilla". This will reset your install back to v1.13c.
  • Click on "Start D2" to make sure the game still works. Since you're on v1.13d, the save games should still show up even though you're using 1.13c.
  • Now Exit.
  • Install PlugY as normal by extracting the contents of the zip file into your D2 folder.
  • "PlugY.exe" and "PlugY.ini" should be in the same folder as "Diablo II.exe"
  • Edit "PlugY.ini" to your liking.
  • Run the game using "PlugY.exe"
  • If it's attached, you should see the PlugY version in the bottom right corner.
  • Load a game and if it doesn't crash after the loading screen finishes then you've got yourself a winner!

By the way, get my Diablo 2 Runewords Android app!

Sources

Opera Browser: Change next tab keyboard shortcut

I like to use the keyboard where possible. In Firefox, I set my Ctrl+Page Up/Down buttons to switch between tabs so I don't have to reach for my mouse as much.

However, when I tried to do this on Opera... god damn wut!? This is one of the cases where it's harder than it should have been.

Firstly, find the settings dialog by:

  • Going to Opera > Settings > Preferences (Ctrl + F12)
  • Advanced > Shortcuts
  • if you haven't already, under "Keyboard setup" make a duplicate of "Opera Standard". I named mine "Opera Standard (modified)".
  • Select the new scheme then press "Edit".

image

Try not to gasp when you see this hideous dialog.

Type in "page" to start filtering the options.

image

  • Under "Application", search for "Switch to next page".
  • In the left column, double click it and paste in "ctrl + PageDown" (it's case sensitive!)
  • As for "Switch to previous page", paste in "ctrl + PageUp".

It should now look like this:

image

Alright! Confirm to exit and it should apply straight away.

I really hope Opera takes the time to polish these features as Firefox has become buggy and downright stupid after adopting the rapid release schedule.

Windows 7: Disable "To help protect your computer, Windows has blocked access to this file"

So I was using the work PC to extract some files I received in my email.image

Damn it I'm just trying to extract some files for work, stop treating me like a grandma!

Fuck this.

Right click on the file > "Properties" > "Unblock".

image

Try extracting again and it'll work.

To prevent files from being tagged as "unsafe", follow the instructions in my previous post Windows 7: Disable the "Open File Security Warning" message.

Source

Django: Display boolean field as True/False radio buttons

This sounds like such a trivial thing to do but it wasn't the most logical.

imageAlright, you'll need a tuple that contains the True/False value and labels and then a ChoiceField which uses it.

class CustomForm(forms.Form):
BOOLEAN_CHOICES = (('1', 'True label'), ('0', 'False label'))
# Filtering fields
is_true = forms.ChoiceField(choices = BOOLEAN_CHOICES, widget = forms.RadioSelect)

Oh what? We're done!

tumblr_lhrs2y4gG21qc45d0

Source

Django: Dynamic checkbox/select options in form

Usually when you create a form in Django, you have to know what items you want to allow as the initial values, otherwise it'll give you an invalid_choice error:

Select a valid choice. 'X' is not one of the available choices.

Normally it's fine, it's just some dope changing values on their browser and messing with your form by sending dodgy data.

But things get a little more complicated when you NEED dynamic choices in the form. For example, I want a form that will allow the user to list a bunch of cars with a given set of features. The "manufacturers" list we can generate using ModelChoiceField, but when you select one, it uses Ajax to dynamically change the "features" options.

note: This example is more verbose than it needs to be. That's just to help you understand what's going on. You can trim off the excess fat once you've got a hang of things.

Firstly, subclass the django.forms.MultipleChoiceField class.

class DynamicMultipleChoiceField(forms.MultipleChoiceField):
# The only thing we need to override here is the validate function. 
    def validate(self, value):
if self.required and not value:
raise ValidationError(self.error_messages['required'])

# Twig: This is part of the original code that we don't want.
# Validate that each value in the value list is in self.choices.
#for val in value:
# if not self.valid_value(val):
# raise ValidationError(self.error_messages['invalid_choice'] % {'value': val})

Now in your form, change the existing field of choice to use the new DynamicMultipleChoiceField:

class CarForm(forms.Form):
manufacturer = forms.ModelChoiceField(queryset = Car.objects.order_by('name'))
features = DynamicMultipleChoiceField(widget = forms.CheckboxSelectMultiple(), choices = [])

def filter_features(self, data):
items = Features.objects.order_by('name')
query = data.get('filter_manufacturer_id', 0)

if query:
manufacturer = Manufacturer.objects.get(pk = query)
items = items.filter(manufacturer = manufacturer)

self.fields['features'].choices = [ (item.pk, item.name) for item in items ]

What we've done here is set the field to be our DynamicMultipleChoiceField, but use the CheckboxSelectMultiple widget to render it.

When the manufacturer list changes, use Ajax to post the selected manufacturer information (your choice of either ID or name). Assuming you've set it up correctly, you can replace the whole choice field with the output from this view:

def ajax_features_field(request):
form = CarForm()
form.filter_features(request.POST)

return HttpResponse("%s" % form['features'])

All the view does is return the rendered HTML for just the features field. If you've customised the form, add a little wrapper  class/ID so you can use jQuery to easily replace the whole field.

tumblr_lfi3fzbYg61qahhxwo1_250
Feature: I want a car that can park like Japan!

Source

Python: How to write a CSV file

CSV is one of the oldest and simplest format for spreadsheets.

If you've ever found yourself having to dump out some data in this format, Python makes it hella easy to do so.

headings = ['Category', 'Systemtype', 'SystemModel', 'ModelID', 'Type', 'Manufacturer', 'ProductName', 'OrigProductName', 'Processor', 'ProcessorSpeed', 'Monitor', 'Memory', 'OperatingSystem', 'HardDrive' ]

# Open up the CSV writer
file = open("something.csv", 'wb')
writer = csv.writer(file, delimiter = ',', quotechar = '"')
writer.writerow(headings)

row = []
for field in headings:
row.append(p.get(field, '').strip().encode("utf-8"))
writer.writerow(row)

file.close()

As you can see, the csv module makes life really easy!

One thing to keep in mind is the encode("utf-8") bit is important, as the CSV module doesn't support unicode by default.

Sources

Android: Validate a URL string

Sometimes all we really need is to check if a URL is valid. You know, the standard "http(s)://domain.com/something/" pattern.

It took a while to find, but the API level 1 had it all along!

Just use URLUtil.isValidUrl() to test it.

// Validate URL
if (!URLUtil.isValidUrl(url)) {
Toast.makeText(this, "Invalid URL specified", Toast.LENGTH_SHORT).show();
return;
}

That's all folks!

 slidedog
Back to having fun!

Sources

Django: Fix "OperationalError: database is locked" error

If you're using the shell to do some testing, this error could cause you some grief and set you back by forcing you to start the terminal.

Thankfully, the solution is short.

Just paste in this snippet and it'll be rolled back to a usable state.

from django.db import transaction
transaction.rollback()

Sources

jQuery: Detect enter keypress

A neat little snippet which detects when a user has pressed "Enter" on the keyboard.

$('#id_query').keypress(function(e) {
var key = (e.keyCode || e.which);

if (key == 13) {
e.preventDefault();
alert("hi!");
}
});

Sources

Django: How to fix the annoying UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 1: ordinal not in range(128)

A somewhat tricky error to debug.

Take for example this:

>>> u"%s" % Product.objects.get(pk = 7431).manufacturer 
u'DéLonghi'

Now look at it again.

>>> "%s" % Product.objects.get(pk = 7431).manufacturer
'D\xc3\xa9Longhi'

Did you spot the difference? There's a "u" in front of the string. That "u" tells Python you want it to be a unicode string rather than an ASCII string.

>>> product = Product.objects.get(pk = 7431)

>>> "%s %s" % (product.manufacturer, product.name)

Will throw this exception

Traceback (most recent call last):
  File "<console>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 1: ordinal not in range(128)

Using the unicode string formatter:

>>> product = Product.objects.get(pk = 7431)

>>> u"%s %s" % (product.manufacturer, product.name)
u'D\xe9Longhi PLS130ARAUP'

Phew, that took a while to figure out. Now back to work!

image

Python: Check if an IP matches or in a valid range

While implementing a certain feature, we wanted to restrict it's functionality to a range of IP's only available in the office.

To do that, you first need to download netaddr from github.

import netaddr

def cache_purge_allowed(request):
client_ip = request.META.get('HTTP_X_FORWARDED_FOR', request.META.get('REMOTE_ADDR', None))

if client_ip is None:
return False

ip = netaddr.IPAddress(client_ip)
return (ip in netaddr.IPNetwork('203.34.46.0/23')) or (ip in netaddr.IPNetwork('192.168.0.0/16')) or (ip in netaddr.IPNetwork('119.225.10.1'))

The example searches through 2 IP ranges and then compares to an exact IP match.

Sources

Django: Model distinct() and order_by() not working nicely together

An interesting (and somewhat tedious) problem came up. We wanted to gather the most recently active blog authors sorted by post date.

Basically, it'd just be a distinct on the authors while sorting by latest post publication date.

In the words made famous by Jeremy Clarkson on Top Gear, "How hard can it be?". To be honest, quite hard.

Things were duplicated everywhere! After a few hours of tinkering, we found a solution.

from django.db.models.aggregates import Max

Author.objects.all_active_in_site().annotate(latest_published = Max('posts__published')).order_by('-latest_published')

It may look ridiculously simple, but it works!

Annotate sets "latest_published" to the date of the newest blog post (found using Max), removing duplications in the matching table.

Since it thinks there is only one blog entry per author, we don't get duplicates when joining.

Source

Python: Fetching HTTPS urls which require username/password authentication

It wasn't the easiest solution to find on the net, but a fairly simple one to implement.

Some solutions even suggest recompiling Python with OpenSSL installed. Sorry, too much trouble, not an option!

from urllib2 import URLError, HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, install_opener, build_opener

# Set up a HTTPS request with username/password authentication
try:
# create a password manager
password_mgr = HTTPPasswordMgrWithDefaultRealm()

# Add the username and password.
password_mgr.add_password(None, feed_url, "your_username", "your_password")
opener = build_opener(HTTPBasicAuthHandler(password_mgr))
file = opener.open(feed_url)

# After you get the "file", you pretty much work with it the same way as you normally would.
xml = etree.parse(file)

except URLError, e:
print 'URLError: "%s"' % e
raise

Brush your hands off boys, we're done here.

Now to solve more pressing issues...

ExtRS
How to get that damn toilet tissue?

Source

Python: Calling CLI (command line) functions from code

This was a tricky one for me. I was trying to use wget to download a file but it wouldn't work properly!

subprocess.call("wget --tries=3 --retry-connrefused http://dl.dropbox.com/u/446679/dog-bites-cat.jpg")

Once I ran it...

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/lib/python2.6/subprocess.py", line 470, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/usr/lib/python2.6/subprocess.py", line 623, in __init__
    errread, errwrite)
  File "/usr/lib/python2.6/subprocess.py", line 1141, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

What the hell? Everything is right!

Turns out I was missing a certain keyword in the call. Some functions require you to add in "shell = True".

subprocess.call("wget --tries=3 --retry-connrefused http://dl.dropbox.com/u/446679/dog-bites-cat.jpg", shell = True)

Source

Python: Download image file from URL and retrieve common properties

With the following snippets, you can get yourself:

  • Image width/height
  • Image mime type
  • File size

So, the code snippet!

from PIL import Image
import urllib2
import cStringIO
import os
from stat import ST_SIZE


file = cStringIO.StringIO(urllib2.urlopen(image_url).read())
filename = "/tmp/file_%s.jpg" % datetime.datetime.now().strftime("%s")

image_info = Image.open(file)
image_info.save(filename)
file.close()

file_info = os.stat(filename)

filemime = "image/%s" % image_info.format.lower() # JPEG, PNG, GIF
width, height = image_info.size
filesize = file_info[ST_SIZE]

From Doug Hellmann's blog:

The cStringIO version is written in C for speed, while StringIO is written in Python for portability.

Once you're done, remember to delete the temporary file.

os.remove(filename)

Sources

jQuery: Slide left and right like slideUp/slideDown but horizontally

So easy that I wish I found this information sooner!

To show:

$('#selector').animate({ width: 'show' });

To hide:

$('#selector').animate({ width: 'hide' });

Alternatively, you can also give a fixed width when showing it.

Other than that, OMG you're done!

OMG

Source

Django: Dynamic forms with dynamic fields

Ok, dynamic fields. Now we're digging into the dark depths of Django. Not something you can find in the documentation, well me anyway.

There are a few posts online about it but some are fairly old, before the Django "newforms" were introduced. All that means is if you tried that code it won't work.

This example shows us how to:

  • Pass an argument to the form upon creation (user variable)
  • Dynamically create fields upon creation
  • Modify the choices for an existing field upon creation

These should cover the use cases of most dynamic forms.

class ExampleDynamicForm(forms.Form):
normal_field = forms.CharField()
choice_field = forms.CharField(widget = forms.Select(choices = [ ('a', 'A'), ('b', 'B'), ('c', 'C') ]))

def __init__(self, user, *args, **kwargs):
# This should be done before any references to self.fields
super(ExampleDynamicForm, self).__init__(*args, **kwargs)

self.user = user
self.id_list = []

# Some generic loop condition to create the fields
for blah in Blah.objects.for_user(user = self.user):
self.id_list.append(blah.id)

# Create and add the field to the form
field = forms.ChoiceField(label = blah.title, widget = forms.widgets.RadioSelect(), choices = [('accept', 'Accept'), ('decline', 'Decline')])
self.fields["blah_%s" % blah.id] = field

# Change the field options
self.fields['choice_field'].widget.choices = [ ('d', 'D'), ('e', 'E'), ('f', 'F') ]

To use the form:

form = ExampleDynamicForm(request.user)

nickshock

It may look scary but it's not that bad.

Follow the formula and you'll be fine.

Note: Remember, the super().__init__() call should be made early on before any references to self.fields.

Sources

Django: Optgroup option groups for Select field widgets

To get your select choices to be grouped, you'll have to do a little trickery.

image

The resultant output in HTML is:

<select id="id_choice" name="choice">
<optgroup label="Audio">
<option value="vinyl">Vinyl</option>
<option value="cd">CD</option>
</optgroup>
<optgroup label="Video">
<option value="vhs">VHS Tape</option>
<option value="dvd">DVD</option>
</optgroup>
<option value="unknown">Unknown</option>
</select>

This example shows you how to provide a list of hardcoded options and it's straight out of the Django docs.

from django import forms

MEDIA_CHOICES = (
('Audio', (
('vinyl', 'Vinyl'),
('cd', 'CD'),
)
),
('Video', (
('vhs', 'VHS Tape'),
('dvd', 'DVD'),
)
),
('unknown', 'Unknown'),
)

class ExampleForm(forms.Form):
choice = forms.CharField(widget = forms.Select(choices = MEDIA_CHOICES))

That's it. Now you have the choices grouped in your form.

Now you can feel like a pro until you need dynamic choices!

Tablecloth_trick

Sources

Diablo 2 + Lord of Destruction: Play without CD

As of patch v1.12, Blizzard allowed the game to be played without CD since they were offering the digital copy of it from their online store.

--------------------------------------------------------------------------
- Patch 1.12
--------------------------------------------------------------------------

     Downloadable Installer Support

- If all required Diablo 2 '.MPQ' files are installed on the
  hard drive, the game will no longer require the CD to play.

   For users that originally performed a 'Full Installation'
   and wish to run without the CD, all '.MPQ' files should
   be copied from the Diablo 2 CDs to the Diablo 2 directory. 
   Most users will only need to copy D2Music.mpq from the
   Diablo 2 Play CD and/or D2xMusic.mpq from the Lord of
   Destruction CD.  Mac users will need to copy these music
   files and rename them to 'Diablo II Music' and
   'Diablo II Expansion Music' respectively.

So, assuming you've done a "full" install of the Diablo 2 game and that you've installed the expansion pack, you'll also need to copy over D2xMusic.mpq from the expansion CD to your installation folder (by default it should be C:\Program Files\Diablo II).

Something they forgot to mention is that you'll also need D2XVIDEO.MPQ as well. Otherwise you'll get the annoying "Insert Expansion Disc" message when you try to start the game.

image

It should work straight away once you've got those 2 files in your game folder.

Android: Uploading files from the phone to a web server via HttpPost

Alright, I'm getting sleepy so this post is straight down to business.

The early Android core libraries didn't come with very much in terms of HTTP and net socket support. The majority of the time they just said "use Apache's library, they're better".

Android has caught up, but if you want to keep existing devices happy, you'll still need the Apache libraries.

  • Under HttpClient 4.1.2 (GA), download 4.1.2.zip.
  • Create a folder in your project called "lib".
  • Open up the zip archive and look for "httpcomponents-client-4.1.2-bin-2.zip\httpcomponents-client-4.1.2\lib\httpmime-4.1.2.jar"
  • Extract it into the new lib folder.

In Eclipse:

  • Refresh your project
  • Right click your project
  • Select "Properties"
  • Go to "Java Build Path > Libraries > Add Jars"
  • Select "httpmime-4.1.2.jar".

image

Now you're ready to CODE!

HttpClient httpClient;
HttpPost postRequest;
MultipartEntity reqEntity;
ResponseHandler responseHandler;
File file;
FileBody fileBody;

httpClient = new DefaultHttpClient();
postRequest = new HttpPost(targetUrl);
responseHandler = new BasicResponseHandler();

// Indicate that this information comes in parts (text and file)
reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

file = new File(filename);
fileBody = new FileBody(file, "images/jpeg");
reqEntity.addPart("fileupload", fileBody);

try {
// The rest of the mundane data
reqEntity.addPart("username", new StringBody("twig"));
reqEntity.addPart("password", new StringBody("haha_as_if!"));

// Prepare to ship it!
postRequest.setEntity(reqEntity);
httpClient.execute(postRequest, responseHandler);
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
catch (ClientProtocolException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}

The file mimetypes you can get from my post Android: Get file mime type from filename.

2clfkn
Now you ride like a BOSS!

Source

Android: Allow user to edit/input text from an alert dialog

This little snippet is a simple one, but it makes the user experience a whole lot better.

Instead of implementing a new Activity/screen to enter in some text, just make it an AlertDialog() with an EditText view.

final EditText txtUrl = new EditText(this);

// Set the default text to a link of the Queen
txtUrl.setHint("http://www.librarising.com/astrology/celebs/images2/QR/queenelizabethii.jpg");

new AlertDialog.Builder(this)
.setTitle("Moustachify Link")
.setMessage("Paste in the link of an image to moustachify!")
.setView(txtUrl)
.setPositiveButton("Moustachify", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String url = txtUrl.getText().toString();
moustachify(null, url);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
})
.show();

This does all the magic. The example shows you how to:

  • Create the edit textfield and assign some properties
  • Build the dialog
  • Set the title/message for the dialog
  • Embed the text field
  • Do something after the user clicks OK or Cancel

Obviously you're gonna have to fill the positive button action with your own intentions.

Have fun!

Source

Android: Select and open an image from Android's image gallery

Well this certainly was harder than it should have been! The first three steps are pretty straight forward.

Set up an ID for the activity result.

private final int ACTIVITY_CHOOSE_PHOTO = 1;

Mission complete! On with the next phase. Now we need something to trigger the "chooser" activity.

Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
chooseFile.setType("image/*");
chooseFile.addCategory(Intent.CATEGORY_OPENABLE);

startActivityForResult(Intent.createChooser(chooseFile, "Choose a photo"), ACTIVITY_CHOOSE_PHOTO);

Simple enough. Of course, if we're expecting a result then we need to actually do something with it.

So in your Activity.onActivityResult() callback method:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch(requestCode) {
case ACTIVITY_CHOOSE_PHOTO: {
if (resultCode == RESULT_OK) {
String filename = parseUriToFilename(data.getData());

if (filename != null) {
moustachify(filename, null);
}
}
break;
}
}
}

OK, the first three steps are done. It's just copy pasting code anyway...

Now the magic calculations come into play to get the filename. Otherwise you'll get references to the media manager and other funky stuff we don't really care about.

Note: This is the exact same code you'll see in the post Android: Add your application to the "Share" menu as they use information from the same activities.

public String parseUriToFilename(Uri uri) {
String selectedImagePath = null;
String filemanagerPath = uri.getPath();

String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);

if (cursor != null) {
// Here you will get a null pointer if cursor is null
// This can be if you used OI file manager for picking the media
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
selectedImagePath = cursor.getString(column_index);
}

if (selectedImagePath != null) {
return selectedImagePath;
}
else if (filemanagerPath != null) {
return filemanagerPath;
}
return null;
}

Now that you've solved this problem, I'm sure there's another waiting for you under the lid somewhere in the near future...

1vcZA

Source

Android: Detect when a WebView has finished loading

To know when a WebView has finished loading, you can set a WebViewClient() handler and override the onPageFinished() method.

ProgressDialog progressDialog = new ProgressDialog(ResultActivity.this);
progressDialog.setMessage("Loading ...");

progressDialog.setCancelable(false);
progressDialog.show();

WebView wv = new WebView(this);

wv.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
progressDialog.hide();
}
});

wv.loadUrl(some_url);

This example shows a "loading dialog" while the webview loads in the background. It'll go away once the page has fully loaded.

1246086511568

Just like when the Jedi warriors have finished defeating enemies, at the end of the battle they force push a fat dude off his chair.

Source

Android: Retrieve "version name" from AndroidManifest.xml

I was getting sick of updating the version number on multiple places in my app when releasing updates; "About" screen, "version" variable and then in the Android manifest.

Since the application manifest already had android:versionName, why not use it?

try {
MyActivity.GAME_VERSION = getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName;
}
catch (NameNotFoundException e) {
// I don't think this ever happens, but let me know if it does!
MyActivity.GAME_VERSION = "0.00";
}

So easy, should have looked it up earlier!

122500549513
Now I'm laughing at version changes!

Source

Android: Resize a Bitmap image while dealing with immutable Bitmaps and OutOfMemoryError exceptions

When I was first debugging my image watermark code, I found it strange it kept running out of memory. Why!?

You're doing it wrong!

Firstly, I was trying to edit an immutable (non-editable) Bitmap. You need to generate a mutable copy of the bitmap before you can start modifying it.

Secondly, my method was very heavy on memory usage. It involved loading the original immutable +4mega-pixel image into memory, then creating a new mutable Bitmap of equal size and colour depth, copying it over using a Canvas.

Keep in mind, the Android VM only allows 16M of memory per app. Each pixel in your image using ARGB_8888 can use up to 4 bytes of memory.

To help you get a perspective of things, a 32bit image with 724x724 has 524,176 pixels uses up 15.9M of memory. If you squish the sizes a bit, that's not very much on a mobile device, especially when you factor in that you need memory for other things in your app such as GUI elements and references to your Activity.

What does that mean? It means you can't load that 8mb photo on that SD card in full resolution no matter how hard you try. Your app has to make some compromises and trim it down a bit.

Not to mention my third step was to imprint a logo over the mutable new bitmap, which means loading yet another image into memory.

turtle-power
This is what the current situation felt like...

Looking for an answer

The internet and StackOverflow are littered with questions on this issue. Most responses tell you to either reduce the colour depth, partially process the bitmap or call Bitmap.recycle() on the source image before creating a new Bitmap.

Now that doesn't make much sense if I'm trying to COPY an image from Bitmap A to Bitmap B because I need both of them in order to do that.

Option A - Bump up the API level

BitmapFactory.Options has a new flag inMutable that allows loading of mutable bitmaps in Honeycomb (API level 11), but I try to maintain as much compatibility as possible.

If you choose to go this way, you will lose some of your market share. See the Android documentation for more information about which API level corresponds to the Android platform versions.

Since I don't actually have any Honeycomb compatible devices, this simply wasn't an option.

Option B - Load a smaller image

My preferred solution is to "pre-scale" the source bitmap so it isn't so damn big. That means loading it in a smaller immutable resolution so you have enough memory to hold both bitmaps at the same time.

The ideal size is 630px, since that's what Facebook uses for the photo album pictures and most people seem to be happy with it.

The downside is that scales works best in the power of 2's, so you can load an image that is 1/2 the size of the original, 1/4th the size, 1/8th the size, etc.

So the method here is:

  • Open image and fetch it's dimensions
  • Scale the image accordingly so it'll meet our "maximum pixels" criteria.
  • Load a pre-scaled image.
  • Create a new mutable bitmap with the same dimensions
  • Copy it via a Canvas
  • Recycle the source bitmap
private Bitmap loadPrescaledBitmap(String filename) throws IOException {
// Facebook image size
final int IMAGE_MAX_SIZE = 630;

File file = null;
FileInputStream fis;

BitmapFactory.Options opts;
int resizeScale;
Bitmap bmp;

file = new File(filename);

// This bit determines only the width/height of the bitmap without loading the contents
opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
fis = new FileInputStream(file);
BitmapFactory.decodeStream(fis, null, opts);
fis.close();

// Find the correct scale value. It should be a power of 2
resizeScale = 1;

if (opts.outHeight > IMAGE_MAX_SIZE || opts.outWidth > IMAGE_MAX_SIZE) {
resizeScale = (int)Math.pow(2, (int) Math.round(Math.log(IMAGE_MAX_SIZE / (double) Math.max(opts.outHeight, opts.outWidth)) / Math.log(0.5)));
}

// Load pre-scaled bitmap
opts = new BitmapFactory.Options();
opts.inSampleSize = resizeScale;
fis = new FileInputStream(file);
bmp = BitmapFactory.decodeStream(fis, null, opts);

fis.close();

return bmp;
}

The rest of the code can be found here.

Option C - Stash the bitmap away in a file

Well, a very interesting and creative method from Sudar Nimalan that will allow you to copy the full resolution image into a mutable form. It is however much slower.

His method involves:

  • Loading the original bitmap
  • Stashing the bitmap to a MappedByteBuffer
  • Recycling the original bitmap
  • Creating a new mutable bitmap
  • Copying the bitmap from the MappedByteBuffer

It's not as hard as it sounds and the code sample is quite short. Worth a look at if you're keen on keeping the image resolution intact.

Sources

 
Copyright © Twig's Tech Tips
Theme by BloggerThemes & TopWPThemes Sponsored by iBlogtoBlog