Tag Archives: Mono

Converting Picasa ini dates to directory dates

One issue I faced in the process of migrating from Picasa to Adobe Lightroom is that Picasa stores event dates in .picasa.ini files. I had spent many hours setting correct dates in my events (folders) and wanted to import them. So I wrote the following C# script (should work for Windows and OS X – I ran in via Mono).

Update: This code is on github @ https://github.com/DavidVeksler/EmbedPicasaProperties

The below will not be updated.

using System;
using System.IO;
 
namespace ConvertPicasaToFolderDates
{
        class MainClass
        {
                private const string IniFileName = @".picasa.ini";
 
                private static void Main(string[] args)
                {
                        string startFolder = @"/Users/davidv/Pictures/";
 
                        Console.WriteLine(startFolder);
 
                        UpdateFoldersInPath(startFolder);
 
                }
 
                private static void UpdateFoldersInPath(string folder)
                {
                        string[] directories = Directory.GetDirectories(folder);
 
                        if (directories.Length > 0)
                                Console.WriteLine("{0} folders in {1}", directories.Length, folder);
 
                        foreach (string directory in directories)
                        {
                                try
                                {
                                        string iniPath = Path.Combine(directory, IniFileName);
 
                                        if (File.Exists(iniPath))
                                        {
                                                Console.WriteLine("Parse " + iniPath);
 
                                                foreach (string line in File.ReadAllLines(iniPath))
                                                {
                                                        // date=29586.603900
                                                        if (!line.StartsWith("date=")) continue;
 
                                                        string dateString = line.Substring(5);
 
                                                        DateTime date = ConverPicasaDateToDateTime(dateString);
 
                                                        DateTime originalTime = Directory.GetCreationTime(directory);
 
                                                        if (originalTime != date && date.Year < 2010)
                                                        {
                                                                Console.WriteLine("{0} to {1}", originalTime, date);
                                                                Directory.SetCreationTime(directory, date);
// (For Mono SetCreationTime did not work correctly, so use SetLastWriteTime.)
                                                                Directory.SetLastWriteTime(directory,date);
                                                        }
 
                                                        break;
                                                }
                                        }
                                }
                                catch (Exception ex)
                                {
                                        Console.WriteLine(ex);
                                }
 
                                try
                                {
                                        UpdateFoldersInPath(directory);
                                }
                                catch (Exception ex)
                                {
                                        Console.WriteLine(ex);
                                }
                        }
                }
 
                // convert =29586.603900 to date time format
                private static DateTime ConverPicasaDateToDateTime(string dateString)
                {
                        var startDate = new DateTime(1900, 1, 1);
 
                        DateTime date = startDate.AddDays(Convert.ToDouble(dateString) -2);
 
                        Console.WriteLine("new date: " + date);
 
                        return date;
                }
        }
}

 

Running you first .Net app on OS X

Installing Mono will allow you to run .Net applications in OS X – as long as they are 100% .Net and do not use any native Windows API’s. However, if you try to simply double-click on a .Net exe, OS X will not know what to do with it, or if you have VMware or wine installed, try to open that executable in another application.

To open a .Net exe with mono, you must open a terminal window, switch to the application directory, and type “mono Application.exe.” If you get an error stating something like “System.DllNotFoundException: gdiplus.dll” it’s probably because your application uses System.Windows.Forms, which must run under X11.  To test X11, install the latest version and run the app again from the X11 terminal.  Did it work? Great!

You probably don’t want to open X11 and type a command in terminal every time you want to run a .Net application, so you can make a script to do it for you.  Open ScriptEditor (/Applications/Utilities/AppleScript/) and create a new script.  Type something like:

do shell script "mono /Users/YOU/Downloads/YourApplication.exe"

Save the script as an Application and you’re done!  Now you can run it just like any native OS X app.  You can try it with SharpChess – just download the exe version.  I was able to download the source of SharpChess, compile it with MonoDevelop on OS X and ran the exe I made on both Mono/OS X and Microsoft .Net/Windows.  Unfortunately, Mono’s implementation of WinForms does not use the native Cocoa API, so it doesn’t look very good – I’ll work on that later.

Customizing Terminal when compiling Mono apps

Pkg-config is a helper tool used when compiling applications and libraries.  If you want to build Mono apps from source using configuration scripts, you will need to put the Mono.pc path in your PKG_CONFIG_PATH environment variable.  If it’s not set, you will get an error like “configure: error: missing the mono.pc file, usually found in the mono-devel package” or “Failed to initialize the ‘Mono 3.5 Profile’ (mono-3.5) target framework”

Here’s how to customize your terminal prompt.   To add the location of mono.pc, edit .profile or .bashrc in the root of your home folder, and add this line

export PKG_CONFIG_PATH=/Library/Frameworks/Mono.framework/Versions/Current/lib/pkgconfig/"

Here is my full .profile file:

export PATH=/Applications/Windows/Darwine/Wine.bundle/Contents/bin:/opt/local/bin:/opt/local/sbin:$PATH
export PKG_CONFIG_PATH=/Library/Frameworks/Mono.framework/Versions/Current/lib/pkgconfig/
export DISPLAY=:0.0

(When using MacPorts, the path is /opt/local/lib/pkgconfig/)