Archive

Posts Tagged ‘hacking’

Using printf format %P with find in RPM spec file

February 4th, 2013 No comments

While creating a spec file for an RPM, I needed to generate the list of files installed by the RPM. Solution is simple, use the UNIX command find. Right..

My first attempt was the following:

%install
# copy the files
( cd %{buildroot} ; find -type f -print "/%P\n" ) > INSTALLED_FILES

If you do the above, you’ll find that all entries in INSTALLED_FILES are wrong: file name have ‘ATCH’ at the end. Why is this? Because %p is a special macro in RPM spec files.

You can try to escape %P in an RPM spec file. If you manage that, let me know, I couldn’t.

Here is the solution I came up with after lots of hacking: it defines the pattern used in the find command as a macro.

%define findpat %( echo "/%""P" )

%install
# copy the files
( cd %{buildroot} ; find -type f -print "%{findpat}\n" ) > INSTALLED_FILES

I hope you never have to do this though.

Tags: ,

Find out if every element of a list is part of another, with Python

August 26th, 2010 5 comments

Update 2010-08-27: Comments indicated that what I did here is not the best solution. Like noted in my original post, a set would be better in this case. I eventually used set(r).issubset(set(l)). Marius also pointed out to set(r) <= set(l), but I like the issubset one more.

I wanted to check if every element of one list or tuple is part of another one using Python. A set has the issubset()-method, but I couldn't find anything build-in for a tuple. It was, however, rather quickly done:

>>> r = (1,2)
>>> l = (3,4,1,5,2)
>>> False not in [ e in l for e in r ]
True
>>> r = (1,9)
>>> False not in [ e in l for e in r ]
False

Why I'm posting this? I just found it cute code, somehow.

Tags: , ,

Using Globals in Pylons.. everywhere

August 26th, 2010 No comments

In Pylons v1.0 you can define global variables by adding them to the Globals-class. If you want a variable called spam and you want it to be globally available, your lib.app_globals.Globals-class would look like this:

class Globals(object):
  def __init__(self, config):
    self.cache = CacheManager(**parse_cache_config_options(config))
    self.spam = False

To use it in a model-module for example, you have to import app_globals from the pylons module, like this:

from pylons import app_globals as g

print g.spam

It took me a while to figure this out.. And I’m starting to like Pylons somehow.

AppleScript exporting photos from Aperture

August 26th, 2010 No comments

The following AppleScript will:

  1. Prompt for a destination folder

  2. Ask for an album name, which will be a folder in destination folder
  3. Get currently selected photo(s) from Aperture
  4. Store the image files using the Image ID of Aperture
  5. Store some META information in a text file, with similar name as image file

The export format is PNG 1024x1024. I needed only that, so I hardcoded it.

Note dependencies: You need the renameFile, joinList and splitString functions found in earlier blog entries.

property defExportSetting : "PNG - Fit within 1024 x 1024"

on apertureExport(fldAlbum)
 tell application "Aperture"
  set imageSel to (get selection)
 end tell
 
 set out to {}
 repeat with img in imageSel
  tell application "Aperture"
   set kwList to (get id of every keyword of img)
   set imgDate to value of EXIF tag "ImageDate" of img
  end tell
  set imgId to id of img
  
  set imgName to name of img
  set imgTags to my joinList(kwList, ",")
  
  copy "Name: " & imgName to end of out
  copy "Tags: " & imgTags to end of out
  copy "ApertureId: " & imgId to end of out
  
  set dstFileMeta to (fldAlbum & imgId & ".meta") as string
 end repeat
 
 tell application "Aperture"
  set dstFile to (export imageSel using export setting defExportSetting to fldAlbum)
 end tell
 set dstFile to my renameFile(dstFile, imgId)
 copy "File: " & (POSIX path of dstFile) to end of out
 tell application "Finder"
 end tell
 
 set fp to open for access file dstFileMeta with write permission
 write (joinList of out given delimiter:return) to fp
 close access fp
 
end apertureExport

on run
 set dstFolder to (choose folder with prompt "Choose an destination") as text
 set dlgAlbum to display dialog "Album name" buttons {"OK", "Cancel"} default answer "Picture pool"
 
 set dstAlbum to (text returned of dlgAlbum) as text
 
 tell application "Finder"
  if not (exists alias (dstFolder & dstAlbum)) then
   make new folder at alias (dstFolder) with properties {name:dstAlbum}
  end if
 end tell
 set fldAlbum to (dstFolder & dstAlbum) as alias
 
 apertureExport(fldAlbum)
end run

This script is safe, but I don’t take any responsibility when it screws up you Aperture library. It shouldn’t really, I coded it on my main library: hardcore!

Splitting as string and joining a list using AppleScript

August 26th, 2010 3 comments

Two small helper AppleScript functions for joining a list and splitting a string given delimiter. Sure, quite an easy task, but it involves setting a global delimiter. Bit like FS in shell. I hope this helps a few folks out there starting out with AppleScript.

to joinList(aList, delimiter)
 set retVal to ""
 set prevDelimiter to AppleScript's text item delimiters
 set AppleScript's text item delimiters to delimiter
 set retVal to aList as string
 set AppleScript's text item delimiters to prevDelimiter
 return retVal
end joinList

to splitString(aString, delimiter)
 set retVal to {}
 set prevDelimiter to AppleScript's text item delimiters
 log delimiter
 set AppleScript's text item delimiters to {delimiter}
 set retVal to every text item of aString
 set AppleScript's text item delimiters to prevDelimiter
 return retVal
end splitString

Here a few lines showing how to use them:

set tmp to my splitString(oldAlias as text, ":")
set imgTags to my joinList(kwList, ",")

Again, no comments! Enjoy!

Renaming a file using AppleScript

August 26th, 2010 No comments

The following AppleScript function renames a file. If you thought this to be a simple thing, try to write it without looking here below. I spend a lot time on this, I might not even use it, but here it is for other mortals wishing to lose weight exercising AppleScript:

to renameFile(oldAlias, newFileName)
 tell application "Finder"
  set f to item (oldAlias as text)
  tell f
   set ext to its name extension
   set nFn to (newFileName & "." & ext)
   set its name to nFn
  end tell
 end tell
 set tmp to my splitString(oldAlias as text, ":")
 set the last item of tmp to nFn
 return my joinList(tmp, ":")
end renameFile

No comments in code, I do not want to spoil your fun!

I needed while writing an export script for Aperture. Here is how I used it after a photo was exported from Aperture:

tell application "Aperture"
 set dstFile to (export imageSel using export setting defExportSetting to fldAlbum)
end tell
set dstFile to my renameFile(dstFile, imgId)

My first thurderstorm shooting

June 13th, 2010 1 comment

About 2 hours and more than 500 shots later I finally did it: I shot lighting! One needs patience, lots of nerves and luck. I didn’t readup on how to do it before, but in the end I pretty much figured it out. The full battery ran out, that much I was using the camera.

Exposure time is not so important, especially when you are exposed to the light polution of the city. I kept it low, from 6 to 10 seconds. I tried with 30 seconds (maximum) but it was just to bright.

Thunderstorm over Kraków

What I found, is that getting the Aperture correct is the way to get it right. Increase it when the storm is further way, decrease when it’s closing in. In the end, when the storm reached our block of flats, I did set it around f/5.6 and f/6.3. This was good. I was continously shooting every 6 seconds keeping the trigger down (didn’t have my cable handy).

Thunderstorm over Kraków

Except for the camera technique, there were a few more challenges, e.g. the actual danger when the storm got closer: keeping windows open is no good. Also the incoming rain was making everything wet. Great fun however, even though only 20 shots did contain actual lighting.

Thunderstorm over Kraków

My gear at the time of shooting: Canon 450D equipped with the EF24-105mm f/4L IS USM lens. I thought putting my 30D to work too, but I lacked a second tripod.

MySQL client tool and how to output newlines

May 13th, 2010 No comments

This blog posts explains how to add a new line in strings in MySQL Stored Procedures and how to output the result using the MySQL client tool.

Today I was fooling around with some stored procedure making it more fancy and stuff. What I wanted was the OUT variable to contain a newline. Easy of course, using CONCAT:

mysql> SELECT CONCAT('foo','\n','bar');
+--------------------------+
| CONCAT('foo','\n','bar') |
+--------------------------+
| foo
bar                  |
+--------------------------+

Now, if youconcat strings in a stored procedure, it doesn’t work as expected when you run it through the MySQL client tool mysql:

DELIMITER //
CREATE PROCEDURE sp1(OUT pres VARCHAR(6000))
BEGIN
  SET pres = CONCAT('foo','\n','bar');
END;
//
DELIMITER ;

SET @res = 'foo ';
CALL sp1(@res);
SELECT @res;

When we execute it, we get this:

shell> mysql -N test < foo.sql
foo\nbar

What on earth is wrong? After some looking, we found a not so often used option called --raw. This produces the the desired effect:

shell> mysql -Nr test < foo.sql
foo
bar

But that’s not all! Use \G when selecting the OUT-variable and it is also working. The output is not so useful though.

Ah.. The things you find out while having the day off..

Tags: ,

If you could send 1 SMS to everyone on Earth, what’d it say?

May 9th, 2010 2 comments

Imagine you are sitting at some high-tech computer and you are given the opportunity to send everyone on Earth 1 SMS. What would you say using only 140 characters?

It’s an unlikely event, but it’s technically not impossible. Not everyone will receive it at the exact same moment, but it will eventually reach almost everyone on this planet. SMS is probably the most direct way to contact people. Forget e-mail, forget Twitter or Facebook, gosh, forget Television! Most people on Earth have a some mobile communication device and they have it usually all the time with them.

It’s an exercise. It’s fun. It is also powerful, maybe scary. But if you could send 1 SMS to everyone on Earth, what would it say?

Tags: ,

Simulating server-side cursors with MySQL Connector/Python

April 26th, 2010 2 comments

Last week, my colleague Massimo and I discussed how to handle big result sets coming from MySQL in Python. The problem is that MySQL doesn’t support server-side cursors, so you need to select everything and then read it. You can do it either buffered or not. MySQL Connector/Python defaults to non-buffered, meaning that you need to fetch all rows after issuing a SELECT statement. You can also turn on the buffering, mimicking what MySQL for Python (MySQLdb) does.

For big result sets, it’s better to limit your search. You can do this using an integer primary key or some temporal field for example. Or you can use the LIMIT keyword. The latter solution is what is used in the MySQLCursorServerSide cursor-class. Using the SELECT it creates a temporary table from which the fetch-methods will get the information. It is something people have probably implemented in their applications, but I hope this new class will make it easier since it’s done transparently.

The code is not pushed yet, but expect it to be available in next release. Here is an example how you could use it. This code selects cities staring with Z, loops over the result getting the country (yes, this is a simple join made difficult):

cnx = db.connect(user='root',db='world')
    cur = cnx.cursor()
    curCity = cnx.cursor(db.cursor.MySQLCursorServerSide)
    
    curCity.execute("SELECT ID,Name,CountryCode FROM City "\
        "WHERE NAME LIKE 'Z%' ORDER BY ID")
    
    for city in curCity:
        cur.execute("SELECT Code,Name FROM Country WHERE CODE = %s",
            (city[2],))
        country = cur.fetchone()
        print "%s (%s)" % (city[1], country[1])
    
    cur.close()
    cnx.close()

I guess the main advantage is that you can use two or more cursor objects with the same connection without the need of buffering everything in Python. On the MySQL side, the temporary table could go to disk when to big. It’s maybe slower, but keeping big result sets in memory ain’t good either.

Comments are welcome!