Re: [Patch] Export to Original.
- From: Larry Ewing <lewing ximian com>
- To: Alessandro Gervaso <gervystar gervystar net>
- Cc: f-spot-list gnome org
- Subject: Re: [Patch] Export to Original.
- Date: Fri, 21 Jan 2005 15:13:26 -0600
Excellent! Thanks for hacking on this.
For now I'd suggest just dropping the second thread for the gallery
creation. I stripped out the thread and and (and a bunch of the
progress stuff but that could be added back by calling the main progress
dialog) and here is the result. It seems to work although I haven't
tested it much. Both this and the vfs dialog should probably validate
the input path to make sure it creates a valid uri.
Oh and next time can you create a unified diff? Just pass the diff
command a -u or if you are using cvs diff you can add the -u to your
~/.cvsrc. I'll attach the .cvsrc I use in case anyone is interested.
Do you want me to start committing this stuff to cvs or wait for updated
verisons from you?
--Larry
On Fri, 2005-01-21 at 01:13 +0100, Alessandro Gervaso wrote:
> Here it is.
> As I've told before I've had some trouble with the transfer-related
> progress-bar and I don't think I have enough knowledge of the gnome-vfs
> system to solve this.
> So I hope that someone could make it better.
> At this time the export module creates a local gallery, and exports it
> to the chosen VFS location (i uploaded two galleries on a webdav
> location) but the gui hangs here.
>
> I attach the needed files.
/*
* Copyright (C) 2005 Alessandro Gervaso <gervystar gervystar net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
//This should be used to export the selected pics to an original gallery
//located on a VFS location.
using System;
using System.IO;
using ICSharpCode.SharpZipLib.Checksums;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.GZip;
namespace FSpot {
public class OriginalExport {
IPhotoCollection selection;
[Glade.Widget] Gtk.Dialog original_export_dialog;
[Glade.Widget] Gtk.ScrolledWindow thumb_scrolledwindow;
[Glade.Widget] Gtk.Entry uri_entry;
//[Glade.Widget] Gtk.CheckButton meta_check;
[Glade.Widget] Gtk.CheckButton scale_check;
[Glade.Widget] Gtk.CheckButton open_check;
[Glade.Widget] Gtk.Entry width_entry;
[Glade.Widget] Gtk.Entry height_entry;
Gnome.Vfs.Uri dest;
int photo_index;
bool open;
string gallery_path;
FSpot.ThreadProgressDialog progress_dialog;
System.Threading.Thread command_thread;
public OriginalExport (IPhotoCollection selection)
{
Gnome.Vfs.ModuleCallbackFullAuthentication auth = new Gnome.Vfs.ModuleCallbackFullAuthentication ();
auth.Callback += new Gnome.Vfs.ModuleCallbackHandler (HandleAuth);
auth.SetDefault ();
auth.Push ();
Gnome.Vfs.ModuleCallbackAuthentication mauth = new Gnome.Vfs.ModuleCallbackAuthentication ();
mauth.Callback += new Gnome.Vfs.ModuleCallbackHandler (HandleAuth);
mauth.SetDefault ();
mauth.Push ();
Gnome.Vfs.ModuleCallbackSaveAuthentication sauth = new Gnome.Vfs.ModuleCallbackSaveAuthentication ();
sauth.Callback += new Gnome.Vfs.ModuleCallbackHandler (HandleAuth);
sauth.SetDefault ();
sauth.Push ();
Gnome.Vfs.ModuleCallbackStatusMessage msg = new Gnome.Vfs.ModuleCallbackStatusMessage ();
msg.Callback += new Gnome.Vfs.ModuleCallbackHandler (HandleMsg);
msg.SetDefault ();
msg.Push ();
this.selection = selection;
Glade.XML xml = new Glade.XML (null, "f-spot.glade", "original_export_dialog", null);
xml.Autoconnect (this);
IconView view = new IconView (selection);
view.DisplayDates = false;
view.DisplayTags = false;
Dialog.Modal = false;
Dialog.TransientFor = null;
thumb_scrolledwindow.Add (view);
Dialog.ShowAll ();
//LoadHistory ();
Dialog.Response += HandleResponse;
}
public Gtk.Dialog Dialog {
get {
return this.original_export_dialog;
}
}
public void Upload ()
{
try {
OriginalGallery gallery = new OriginalGallery(selection);
//Console.WriteLine("Started!!!");
// set the tmpdir and the galleryname using the given properties
gallery.StartProcessing();
this.gallery_path = gallery.GalleryPath;
//Console.WriteLine("Finished!!!");
} catch {}
try {
Dialog.Destroy ();
Gnome.Vfs.Result result = Gnome.Vfs.Result.Ok;
System.Console.WriteLine ("trying {0}", gallery_path);
Gnome.Vfs.Uri source = new Gnome.Vfs.Uri (gallery_path);
Gnome.Vfs.Uri target = dest.Clone();
target = target.AppendFileName(source.ExtractShortName ());
Console.WriteLine(target);
Gnome.Vfs.XferProgressCallback cb = new Gnome.Vfs.XferProgressCallback (Progress);
System.Console.WriteLine ("Xfering {0} to {1}", source.ToString (), target.ToString ());
result = Gnome.Vfs.Xfer.XferUri (source, target,
Gnome.Vfs.XferOptions.Default,
Gnome.Vfs.XferErrorMode.Abort,
Gnome.Vfs.XferOverwriteMode.Replace,
cb);
if (result == Gnome.Vfs.Result.Ok) {
progress_dialog.Message = Mono.Posix.Catalog.GetString ("Done Sending Photos");
progress_dialog.Fraction = 1.0;
progress_dialog.ProgressText = Mono.Posix.Catalog.GetString ("Transfer Complete");
progress_dialog.ButtonLabel = Gtk.Stock.Ok;
} else {
progress_dialog.ProgressText = result.ToString ();
progress_dialog.Message = Mono.Posix.Catalog.GetString ("Error While Transferring");
}
if (open && photo_index > 0)
Gnome.Url.Show (dest.ToString ());
} catch (System.Exception e) {
progress_dialog.Message = e.ToString ();
progress_dialog.ProgressText = Mono.Posix.Catalog.GetString ("Error Transferring");
}
}
private int Progress (Gnome.Vfs.XferProgressInfo info)
{
progress_dialog.ProgressText = info.Phase.ToString ();
if (info.BytesTotal > 0) {
progress_dialog.Fraction = info.BytesCopied / (double)info.BytesTotal;
}
switch (info.Status) {
case Gnome.Vfs.XferProgressStatus.Vfserror:
progress_dialog.Message = Mono.Posix.Catalog.GetString ("Error: Error while transferring, Aborting");
return (int)Gnome.Vfs.XferErrorAction.Abort;
case Gnome.Vfs.XferProgressStatus.Overwrite:
progress_dialog.ProgressText = Mono.Posix.Catalog.GetString ("Error: File Already Exists, Aborting");
return (int)Gnome.Vfs.XferOverwriteAction.Abort;
default:
return 1;
}
}
private void HandleMsg (Gnome.Vfs.ModuleCallback cb)
{
Gnome.Vfs.ModuleCallbackStatusMessage msg = cb as Gnome.Vfs.ModuleCallbackStatusMessage;
System.Console.WriteLine ("{0}", msg.Message);
}
private void HandleAuth (Gnome.Vfs.ModuleCallback cb)
{
Gnome.Vfs.ModuleCallbackFullAuthentication fcb = cb as Gnome.Vfs.ModuleCallbackFullAuthentication;
System.Console.Write ("Enter your username ({0}): ", fcb.Username);
string username = System.Console.ReadLine ();
System.Console.Write ("Enter your password : ");
string passwd = System.Console.ReadLine ();
if (username.Length > 0)
fcb.Username = username;
fcb.Password = passwd;
}
private void HandleResponse (object sender, Gtk.ResponseArgs args)
{
if (args.ResponseId != Gtk.ResponseType.Ok) {
Dialog.Destroy ();
return;
}
dest = new Gnome.Vfs.Uri (uri_entry.Text);
open = open_check.Active;
command_thread = new System.Threading.Thread (new System.Threading.ThreadStart (Upload));
command_thread.Name = Mono.Posix.Catalog.GetString ("Transfering Pictures");
//FIXME: get the files/dirs count in a cleaner way than (* 5 + 2(zip) + 9)
// selection * 5 (original, mq, lq, thumbs, comments)
// 2: zipfiles
// 9: directories + info.txt + .htaccess
// this should actually be 1 anyway, because we transfer just one dir
progress_dialog = new FSpot.ThreadProgressDialog (command_thread,
1);
progress_dialog.Start ();
}
}
// This class will create a local gallery in a temporary location (e.g. /tmp)
class OriginalGallery
{
private IPhotoCollection selection;
private string gallery_name = "web-gallery";
private string gallery_path;
private string tmpdir = "temp";
private bool setmtime = false;
private int photo_index = 1; //used to name files
FSpot.ThreadProgressDialog progress_dialog;
System.Threading.Thread command_thread;
public OriginalGallery (IPhotoCollection selection)
{
this.selection = selection;
}
public void StartProcessing()
{
MakeDirs();
CreateHtaccess();
CreateInfo();
StartAll ();
}
private void StartAll()
{
//FIXME: when used in a try statement, a System.NullReferenceException
// is thrown after completion.
try {
foreach (Photo photo in selection.Photos) {
CreateImages(photo.Path);
CreateComments(photo.Path);
//Set the directory's mtime sa the oldest photo's one.
if (!setmtime)
{
try {
Directory.SetLastWriteTimeUtc(gallery_path, photo.Time);
setmtime = true;
} catch { setmtime = false; }
}
photo_index++;
}
CreateZipFile("mq");
CreateZipFile("hq");
} catch (System.Exception e) {
System.Console.WriteLine (e.ToString ());
}
}
private void MakeDirs()
{
gallery_path = Global.HomeDirectory + Path.DirectorySeparatorChar
+ tmpdir + Path.DirectorySeparatorChar + gallery_name;
//FIXME: Create this with 0700 mode in the case it is placed in /tmp
try {
Directory.CreateDirectory(gallery_path);
Directory.CreateDirectory(gallery_path + Path.DirectorySeparatorChar + "thumbs");
Directory.CreateDirectory(gallery_path + Path.DirectorySeparatorChar + "lq");
Directory.CreateDirectory(gallery_path + Path.DirectorySeparatorChar + "mq");
Directory.CreateDirectory(gallery_path + Path.DirectorySeparatorChar + "hq");
Directory.CreateDirectory(gallery_path + Path.DirectorySeparatorChar + "comments");
Directory.CreateDirectory(gallery_path + Path.DirectorySeparatorChar + "zip");
} catch {
Console.WriteLine("Error in creating directory" + gallery_path);
}
}
private void CreateImages (string photo_path)
{
Gdk.Pixbuf source_image = PixbufUtils.LoadAtMaxSize (photo_path, 800, 600);
string img_name = "img" + photo_index + ".jpg";
string [] keys = {"quality"};
string [] values = {"75"};
// scale the images to different sizes
// High quality is the orignal image
File.Copy(photo_path, SubdirPath ("hq", img_name), true);
// Medium Quality
string path = SubdirPath ("mq", img_name);
source_image.Savev(path, "jpeg", keys, values);
//low quality
Gdk.Pixbuf scaled = PixbufUtils.ScaleToMaxSize (source_image, 640, 480);
path = SubdirPath ("lq", img_name);
scaled.Savev(path, "jpeg", keys, values);
source_image.Dispose ();
source_image = scaled;
// Thumbnail
scaled = PixbufUtils.ScaleToMaxSize (source_image, 120, 90);
path = SubdirPath ("thumbs", img_name);
scaled.Savev(path, "jpeg", keys, values);
source_image.Dispose ();
scaled.Dispose ();
}
private string SubdirPath (string subdir, string file)
{
string path = Path.Combine (gallery_path, subdir);
if (file != null)
path = Path.Combine (path, file);
return path;
}
private void CreateComments(string photo_path)
{
StreamWriter comment = File.CreateText(SubdirPath ("comments", "img-" + photo_index + "txt"));
comment.WriteLine("<span>image " + photo_index + "</span>\n");
comment.Close();
}
private void CreateZipFile(string img_quality)
{
string[] filenames = Directory.GetFiles(Path.Combine (gallery_path, img_quality));
Crc32 crc = new Crc32();
ZipOutputStream s = new ZipOutputStream(File.Create(gallery_path
+ Path.DirectorySeparatorChar + "zip" + Path.DirectorySeparatorChar
+ img_quality + ".zip"));
s.SetLevel(0);
foreach (string file in filenames) {
FileStream fs = File.OpenRead(file);
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
ZipEntry entry = new ZipEntry(Path.GetFileName(file));
entry.DateTime = DateTime.Now;
// set Size and the crc, because the information
// about the size and crc should be stored in the header
// if it is not set it is automatically written in the footer.
// (in this case size == crc == -1 in the header)
// Some ZIP programs have problems with zip files that don't store
// the size and crc in the header.
entry.Size = fs.Length;
fs.Close();
crc.Reset();
crc.Update(buffer);
entry.Crc = crc.Value;
s.PutNextEntry(entry);
s.Write(buffer, 0, buffer.Length);
}
s.Finish();
s.Close();
}
private void CreateHtaccess()
{
StreamWriter htaccess = File.CreateText(gallery_path + Path.DirectorySeparatorChar + ".htaccess");
htaccess.Write("<Files info.txt>\n\tdeny from all\n</Files>\n");
htaccess.Close();
}
private void CreateInfo()
{
//Console.WriteLine(selection.Photos[0].Time.Date.ToString ("yyyy-MM-dd"));
StreamWriter info = File.CreateText(gallery_path + Path.DirectorySeparatorChar + "info.txt");
info.WriteLine("date|" + selection.Photos[0].Time.Date.ToString ("yyyy-MM-dd"));
info.Close();
}
// This is provided in order to pass the name as an argument through the
// dialog window.
public string GalleryPath {
get {
return gallery_path;
}
}
public string TmpPath {
get {
return tmpdir;
} set {
tmpdir = value;
}
}
}
}
cvs -z3
update -dP
diff -upN
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]