Re: Batch import



incigel gmx de, 2008-10-14 09:50:35 +0200 :

> I would like to use f-spot to just import the pictures from an
> inserted memory stick into the database without any user interaction
> and graphical ui from the command line (headless
> system). Unfortunately, I have not found any information on how to
> do this e.g. with f-spot-import nor a documentation of available
> command line parameters that could be helpful.
>
> Does f-spot support such kind of batch import, at all, and is there
> a documentation somewhere?

I have an importer script that tries to do that.  I used to do it in
Perl by accessing the database directly, but I rewrote it in C# to
make use of the F-Spot classes, so I don't have to care about the
database schema any more.  Unfortunately, there is a drawback: part of
the code in F-Spot assumes that there's an X11 server running and
available, so although the program is runnable through the command
line with no GUI, it still needs to be run under X to work.

  Old script can be found at
http://roland.entierement.nu/pages/sync-digicams.html, my new importer
is below (beware: it needs F-Spot to be patched with
http://bugzilla.gnome.org/show_bug.cgi?id=507919).

// Download pictures from a camera and import the files into F-Spot, non-interactively
// Roland Mas <lolando debian org>
// Based on code from F-Spot by Larry Ewing and others

using System;
using System.IO;
using System.Collections;
using FSpot;
using FSpot.Utils;
using Gdk;
using Mono.GetOptions;

namespace camsync2 {
	struct Config {
		public string camera;
		public string tagname;
		public string rawtagname;
		public string destdir;
		public string camera_name;
		public int max_remaining ;
	}
	
	class MainClass	{
		static Tag tag;
		static Tag rawtag;
		static Config config ;
		static Roll roll ;

		static void ReadOptions (string[] args) {
			CamsyncOptions options = new CamsyncOptions ();
			options.ProcessArgs (args);
			options.Validate();
			
			string configfile = Path.Combine(
				Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
				"camsync.conf");

			if (options.config != null) {
				configfile = options.config ;
			}
			
			Nini.Config.IConfigSource configsource = new Nini.Config.IniConfigSource (configfile);

			config.camera = configsource.Configs["default"].Get("default_camera");
			if (options.camera != null)
				config.camera = options.camera ;
			if (config.camera == null) {
				Console.WriteLine("No camera specified, exiting");
				Environment.Exit (1);
			}
			Console.WriteLine ("Default camera : {0}", config.camera);
			
			if (options.tagname != null) {
				config.tagname = options.tagname ;
			} else if (configsource.Configs[config.camera].Get("tag_name") != null) {
				config.tagname = configsource.Configs[config.camera].Get("tag_name") ;
			} else if (configsource.Configs["default"].Get("tag_name") != null) {
				config.tagname = configsource.Configs["default"].Get("tag_name") ;
			} else {
				Console.WriteLine("No tag specified, exiting");
				Environment.Exit (1);
			}				

			if (options.rawtagname != null) {
				config.rawtagname = options.rawtagname ;
			} else if (configsource.Configs[config.camera].Get("raw_tag_name") != null) {
				config.rawtagname = configsource.Configs[config.camera].Get("raw_tag_name") ;
			} else if (configsource.Configs["default"].Get("raw_tag_name") != null) {
				config.rawtagname = configsource.Configs["default"].Get("raw_tag_name") ;
			} else {
				config.rawtagname = config.tagname ;
			}				

			if (options.camera_name != null) {
				config.camera_name = options.camera_name ;
			} else if (configsource.Configs[config.camera].Get("camera_name") != null) {
				config.camera_name = configsource.Configs[config.camera].Get("camera_name") ;
			} else if (configsource.Configs["default"].Get("camera_name") != null) {
				config.camera_name = configsource.Configs["default"].Get("camera_name") ;
			} else {
				Console.WriteLine("No camera name found, exiting");
				Environment.Exit (1);
			}				

			if (options.destdir != null) {
				config.destdir = options.destdir ;
			} else if (configsource.Configs[config.camera].Get("destination_dir") != null) {
				config.destdir = configsource.Configs[config.camera].Get("destination_dir") ;
			} else if (configsource.Configs["default"].Get("destination_dir") != null) {
				config.destdir = configsource.Configs["default"].Get("destination_dir") ;
			} else {
				Console.WriteLine("No destination directory found, exiting");
				Environment.Exit (1);
			}				

			if (options.max_remaining != 0) {
				config.max_remaining = options.max_remaining ;
			} else if (configsource.Configs[config.camera].GetInt("max_remaining") != 0) {
				config.max_remaining = configsource.Configs[config.camera].GetInt("max_remaining") ;
			} else if (configsource.Configs["default"].GetInt("max_remaining") != 0) {
				config.max_remaining = configsource.Configs["default"].GetInt("max_remaining") ;
			} else {
				config.max_remaining = 0 ;
			}
		}
		
		static void RegisterPhoto(Uri uri) {
			Pixbuf thumb ;
			
			Photo photo = Core.Database.Photos.GetByUri(uri);
			if (photo == null) {
				if (roll == null) {
					roll = Core.Database.Rolls.Create();
				}
				Console.WriteLine("Registering URI \"{0}\"", uri);
				photo = Core.Database.Photos.Create(uri, roll.Id, out thumb);
				photo.AddTag (tag) ;
				if (ImageFile.IsRaw(uri.LocalPath)) {
					photo.AddTag (rawtag) ;
				}
				Core.Database.Photos.Commit(photo);
				Core.Database.Tags.Commit(tag);
				Core.Database.Tags.Commit(rawtag);
			} else {
				// Console.WriteLine("URI \"{0}\" already registered", uri);
			}
		}
		
		public static void Main(string[] args) {
			ReadOptions (args);
			
			Console.WriteLine("Starting up");
			Gtk.Application.Init();
			Console.WriteLine("{0} photos currently registered in database", Core.Database.Photos.TotalPhotos);
			Console.WriteLine("Got here");
						
			tag = Core.Database.Tags.GetTagByName (config.tagname);
			if (tag == null) {
				Console.WriteLine("No tag \"{0}\" found, exiting", config.tagname);
				return ;
			}
			rawtag = Core.Database.Tags.GetTagByName (config.rawtagname);
			if (rawtag == null) {
				Console.WriteLine("No tag \"{0}\" found, exiting", config.rawtagname);
				return ;
			}
			
			Gnome.Vfs.Vfs.Initialize ();
			Core.Database.Sync = true ;

			GPhotoCamera cam = new GPhotoCamera ();
			cam.DetectCameras ();
			Console.WriteLine ("Found {0} cameras", cam.CameraList.Count ()) ;
		
			bool camera_found = false ;
			int cam_id = 0 ;
			while ((! camera_found)
			       && (cam_id < cam.CameraList.Count ())) {
				string camera_name = cam.CameraList.GetName(cam_id);
				if (camera_name.Equals(config.camera_name)) {
					Console.WriteLine("Found camera \"{0}\" at rank {1}", camera_name, cam_id);
					cam.SelectCamera(cam_id);
					camera_found = true ;
					cam.InitializeCamera();
					
					foreach (GPhotoCameraFile f in cam.FileList) {
						int file_id = cam.FileList.IndexOf (f) ;
						string destfile = config.destdir + f.Directory + f.FileName ;
						
						string dir = Path.GetDirectoryName (destfile) ;
						if (!Directory.Exists (dir)) {
							Directory.CreateDirectory (dir) ;
						}
						if (File.Exists (destfile)) {
							// Console.WriteLine("File \"{0}\" already exists", destfile);
						} else {	
							Console.WriteLine ("Saving file {0} as {1}", file_id, destfile) ;
							cam.SaveFile(file_id, destfile);
						}
						Uri uri = UriUtils.PathToFileUri (destfile);
						RegisterPhoto (uri);
					}

					Console.WriteLine ("{0} files on camera", cam.FileList.Count);
					if (config.max_remaining > 0) {
						for (int file_id = 0 ; file_id < cam.FileList.Count - config.max_remaining ; file_id++) {
							Console.WriteLine ("Deleting {0}", file_id) ;
							cam.DeleteFile (file_id) ;
						}
					}
					
					cam.ReleaseGPhotoResources () ;
					break ;
				} else {
					Console.WriteLine("Found other camera \"{0}\" at rank {1}", camera_name, cam_id);
				}
				
				cam_id++ ;
			}
			if (! camera_found) {
				Console.WriteLine("Camera not found");
			}
			
			int tmp = Core.Database.Photos.TotalPhotos;
			Console.WriteLine("{0} photos currently registered in database", tmp);
			Console.WriteLine("Done");

			Environment.Exit (0);
		}
	}
	
	public class CamsyncOptions : Options {
		//--config, -f
		[Option ("use configuration file", 'f', "config")]
		public string config;

		//--camera, -c
		[Option ("import from the given camera", 'c', "camera")]
		public string camera;

		//--destdir, -d
		[Option ("base directory for destination files", 'd', "destdir")]
		public string destdir;

		//--tag, -t
		[Option ("tag name", 't', "tag")]
		public string tagname;

		//--rawtag, -r
		[Option ("raw tag name", 'r', "rawtag")]
		public string rawtagname;

		//--camera-name, -n
		[Option ("camera name", 'n', "camera-name")]
		public string camera_name;

		//--max-remaining, -m
		[Option ("maximum number of photos to keep", 'm', "max-remaining")]
		public int max_remaining;

		public CamsyncOptions () {
			base.ParsingMode = OptionsParsingMode.Both;
		}

		public bool Validate ()	{
			foreach (string s in RemainingArguments) {
				Console.WriteLine ("Unknown option {0}", s);
				return false;
			}
			
			return true;
		}
	}
}
  Patches welcome, as well as pushing patch #507919 upstream, and
patches to remove the X11 dependency.

Roland.
-- 
Roland Mas

Plant a radish, get a radish, never any doubt!
  -- Bellamy & Hucklebee, in The Fantasticks


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]