Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

[MOD] Host photos on the Internet
marty1101
#1 Posted : Wednesday, 25 February 2009 5:29:26 PM(UTC)
Rank: Advanced Member

Joined: 4/01/2009(UTC)
Posts: 37
Location: Taipei, Taiwan

Goal: Put all photos on Flickr and display in GSP

Assumption: Ease of obtaining the image url of large and thumbnail photos on Flickr (via Friendly.Flickr)

After experiments:

Flickr photos:
1. Large: 1024px
2. Midium: 500px
3. Small: 240px
4. Thumbnail: 100px
5. Square Thumbnail: 75px

GSP Issues:
1. No slide show
Solve: Look for the codes.
2. No thumbnails. Thumbnails are retrieved from disk.
Solve: Create a talbe to store the thumbnail url. Change the code to display external thumbnails if it's external images type.
3. Cannot transfer the object to another album ("move object")
Error - One or both arguments contain an empty string. dirPath = "D:\Sites\20085\gsp_mediaobjects\babies"; fileName = ""
Because there is no filename.
"Move" involves moving the actual file to the destination. (copy and delete)

OK. No Show/Hide the original high-res image
OK. No Download this media object
OK. Can not rotate the image
OK. No info about this image
OK. Cannot delete high-res images
OK. Cannot sync
OK. Can assign a thumbnail for the album.
OK. Can copy the object to another album ("copy object")
It only adds another row in gs_MediaObject table

For external images:
. No rows in gs_MediaObjectMetadata
. In gs_MediaObject, differences from non-external objects
HashKey=''(No use)
ThumbnailFilename = _zThumb_external(?).jpeg
OptimizedFilename=''(No use)
OptimizedWidth=-2147483648(why? No use)
OptimizedHeight=-2147483648(why? No use)
OptimizedSizeKB=-2147483648(why? No use)
OriginalFilename=''(No use)
OriginalWidth=640 (incorrect)(No use)
OriginalHeight=480 (incorrect)(No use)
OriginalSizeKB=0(No use)(No use)
. If mannually inserting a row in gs_MediaObject, one needs to restart the app to see the new photo thumbnail (cache?)

It looks like there're not many fixes need to be done before looking into the source code.
Is there anything I shall pay attention to? I'm not sure if any of these will be changed in future editions of GSP. I'll do the best to keep the changes apart from the source code so modifications to the future source code would be kept to the minimum.
Roger Martin
#2 Posted : Thursday, 26 February 2009 12:37:56 AM(UTC)
Roger Martin

Rank: Administration

Joined: 3/08/2007(UTC)
Posts: 3,300
Location: Fort Atkinson, WI

It sounds like you have a good handle on the situation. Before you dive in, consider another approach: using the RSS feed from Flickr (Flickr does offer an RSS feed, right?). This is one of the features I want to add, but it is probably a year or so away before I can get to it.

I imagine configuring an album in GSP where you set an RSS feed as the album source. GSP would be pre-programmed to understand the syntax of the Flickr feed and is able to present thumbnails, optimized, and full-size photos as needed.

The beauty of this approach is that GSP immediately reflects your Flickr album without any additional work on your part.

I don't yet have a plan for exactly how this feature would be implemented but I am happy to work with you to make it robust and eventually integrate it into the core GSP product.

Getting back to your original post, a few comments:

* The issue "Cannot transfer the object to another album" is a known bug where external media objects cannot be moved. It has been fixed and will be included in the next release.

* The OriginalWidth and OriginalHeight fields are set according to the media type you choose in the dropdown on the add external media object page. For a video, they are set to the default width and height for videos as assigned in Site admin - Video/Audio/Other page. For an external image or other, it is set to the generic width and height setting. But the actual width and height is determined by the HTML snippet you enter, so I can see why you consider the behavior incorrect. But the values *are* used to help format other objects on the page, like the width of the table containing the next/previous buttons above the media object.

* The number -2147483648 is sometimes used to indicate that I am intentionally not assigning a value to a field. The number is the smallest number that can be stored a 32-bit integer, and is conveniently referenced in code as int.MinValue.
Roger Martin
Creator and Lead Developer of Gallery Server Pro
marty1101
#3 Posted : Sunday, 1 March 2009 4:28:23 PM(UTC)
Rank: Advanced Member

Joined: 4/01/2009(UTC)
Posts: 37
Location: Taipei, Taiwan

The Flickr RSS idea is great. I googled it for a while, but didn't find a site that's similar to an album site. Doubts in mind:
1. Can I totally rely on Flickr?
2. Does Flickr opens everything to me via API?
3. To what extent can I control the layout of the feed?
4. What are the limits?
5. How do I query the photos I want? (I saw someone mentioned that Flickr Sets doesn't provide RSS feeds. and query using Chinese words may cause other problems.)

Well, these may be answered after learning all about Flickr, but that'll take a while.

What I originally thought was:
1. I can put photos on external sites and get the jpg url => save space and bandwidth
2. If one site suddenly closes, or changes the url, I can quickly recover these url by altering the url in my database.
3. I can even put one photo on different external sites and have several urls for this photo stored in my database. My script can just use the one that works.

I found Website\CodeFiles\GalleryPage.cs:
Code:

        public string GetThumbnailUrl(IGalleryObject galleryObject)
        {
/* Original codes
if (galleryObject is Album)
return GetAlbumThumbnailUrl(galleryObject);
else
return GetMediaObjectUrl(galleryObject, DisplayObjectType.Thumbnail);
*/

#region marty1101
if (galleryObject is Album)
return GetAlbumThumbnailUrl(galleryObject);
else if (galleryObject.Original.DisplayType == DisplayObjectType.External)
{
galleryObject.Thumbnail.Height = 100;
galleryObject.Thumbnail.Width = 100;

return GetExternalThumbnailUrl(galleryObject.Original.MediaObjectId); // this function needs to be implemented later.
// return "http://farm4.static.flickr.com/3548/3311132776_162659eb19_t.jpg";
}
else
return GetMediaObjectUrl(galleryObject, DisplayObjectType.Thumbnail);
#endregion marty1101
}

Ah ya! I need the thumbnail width and height of the external photo! so, the thumbnails would display nicely. Do I
1. Use Friendly.Flickr to download the thumbnails and use AcdSee to get the width&height => con: too time consuming, pro: solve right away
2. In the "add external photo" page, download the thumbnails and get width&height => con: it takes time when adding photos and bandwidth, pro: universal for all external storages
3. Get width&height numbers from some Flickr API

(1) Friendly.Flickr doesn't give such information
(2) This might be the best solution for now. Downloading it to the local disc and getting the properties shouldn't be difficult.
(3) Friendly.Flickr doesn't give the Flickr photo id

This method may require lots of work upon adding information into my database. If the external links break, the entire process would need to be gone through again. The "Feed" concept seems to be quite popular now. The "Yahoo Pipe"? Looks like a new world to me.

marty1101
#4 Posted : Tuesday, 3 March 2009 6:55:54 PM(UTC)
Rank: Advanced Member

Joined: 4/01/2009(UTC)
Posts: 37
Location: Taipei, Taiwan

I got the thumbnails displayed for external images today. One more to go:

Issue: Slide show doesn't work for external images.

In galleryserverpro.config.readme
Quote:

enableSlideShow (defaultValue = "true")
Specifies whether slide show functionality is enabled. When true, a start/pause slideshow button is displayed in the
toolbar that appears above a media object. The length of time each image is shown before automatically moving
to the next one is controlled by the SlideshowInterval setting. Note that only images are shown during a slide
show; other objects such as videos, audio files, and documents are skipped.


I think it uses Ajax callback. and it has something to do with mediaobjectview.js
Strangely, I thought VS2008 can trace step-by-step in javascript, but it's not happening today.
After clicking the play button, it goes back to the album's thumbnail view (There are 3 external images in the album). It seems not have gone through the html generating codes (GetMediaObjectHtml). Where did it jump the ship?

A little dizzy now after a day's digging. Where shall I look for the source code for this sentence?
"Note that only images are shown during a slide show; other objects such as videos, audio files, and documents are skipped." I appreciate for a little hints in your spare time.

and there're some talks about other slideshow viewers in the forum. Well, ya, full screen slideshow using Silverlight is coming. Will external images slidshow be included in the next version?
Roger Martin
#5 Posted : Wednesday, 4 March 2009 12:15:50 AM(UTC)
Roger Martin

Rank: Administration

Joined: 3/08/2007(UTC)
Posts: 3,300
Location: Fort Atkinson, WI

The most reliable way I have found to debug javascript is to uncheck the Disable script debugging option in IE (Tools - Internet Options - Advanced), then add the statement "debugger" somewhere in your javascript, and finally use IE to load the page. A popup should appear that asks if you want to open the page in the debugger. Choose the Visual Studio option and it will fire up in VS.

There are other ways but they aren't as reliable.

Slide show items are determined by the function GetNextMediaObjectIdForSlideshow in the GalleryPage class:

Code:
private static int GetNextMediaObjectIdForSlideshow(int mediaObjectIndex, IGalleryObjectCollection siblings)
{
int nextMediaObjectId = 0;
while (mediaObjectIndex < (siblings.Count - 1))
{
IGalleryObject nextMediaObject = siblings[mediaObjectIndex + 1];
if (nextMediaObject is GalleryServerPro.Business.Image)
{
nextMediaObjectId = nextMediaObject.Id;
break;
}

mediaObjectIndex += 1;
}

return nextMediaObjectId;
}


To include external media objects, modify it like this:

Code:
private static int GetNextMediaObjectIdForSlideshow(int mediaObjectIndex, IGalleryObjectCollection siblings)
{
int nextMediaObjectId = 0;
while (mediaObjectIndex < (siblings.Count - 1))
{
IGalleryObject nextMediaObject = siblings[mediaObjectIndex + 1];
if ((nextMediaObject is GalleryServerPro.Business.Image) || (nextMediaObject is GalleryServerPro.Business.ExternalMediaObject))
{
nextMediaObjectId = nextMediaObject.Id;
break;
}

mediaObjectIndex += 1;
}

return nextMediaObjectId;
}


Note that GSP doesn't know whether an external media object is a photo, video, or something else, so if you've added, say, YouTube videos, they will briefly appear as a slide show item and then move to the next item before you've had a chance to view it.

External images slideshow or external RSS functionality is not in scope for 2.3.
Roger Martin
Creator and Lead Developer of Gallery Server Pro
marty1101
#6 Posted : Wednesday, 4 March 2009 1:42:19 PM(UTC)
Rank: Advanced Member

Joined: 4/01/2009(UTC)
Posts: 37
Location: Taipei, Taiwan

Thank you so much! The javascript debugging way really helps.

About the changes in GetNextMediaObjectIdForSlideshow():

1. My assumption is that all media files are images on my site. No problem for now. I was thinking if it's other types like video, audio, documents ..., can't they be displayed as slideshow? This might get into the initial design structure. If it's an video, can the player tell the script to go to the next media object when it's done playing?

2. I ran into another problem: the slideshow goes to the next image before this image is fully loaded. Although I can change the slideshowInterval, I found it convenient to change it while watching the slideshow (many photo viewers such as Flickr's have this function.)

I've got relieved now going through these with your help. More testing and coding to import info of external images is on the way. I'll summarize after all is done.
Roger Martin
#7 Posted : Wednesday, 4 March 2009 1:54:12 PM(UTC)
Roger Martin

Rank: Administration

Joined: 3/08/2007(UTC)
Posts: 3,300
Location: Fort Atkinson, WI

In order for javascript to know that a video has stopped it has to have intimate knowledge about the plug-in playing the video. This is practically impossible to do for all the possible plug-ins. The best you can do is pick one or two and code specifically for them.

I'll consider your interval issue as a feature suggestion: Allow changing the interval during a slideshow.
Roger Martin
Creator and Lead Developer of Gallery Server Pro
marty1101
#8 Posted : Sunday, 8 March 2009 9:32:35 PM(UTC)
Rank: Advanced Member

Joined: 4/01/2009(UTC)
Posts: 37
Location: Taipei, Taiwan

When I thought every issue is the last issue, a new issue came up. :(

I might have solved it, but wish to get your approval.

1. I managed to put the actual ThumbnailWidth and ThumbnailHeight in gs_MediaObject of external images.
2. Synchronizing all albums (there are also other images on disk) updates these values (and maybe OriginalWidth and OriginalHeight. I forgot to check these values during testing.) and incorrectly display the external image thumbnails.

Solve: By commenting out these, I seem to avoid updating these values

\TIS.GSP.Business\SynchronizationManager.cs
Code:

        private void SynchronizeExternalMediaObjects(IAlbum album)
        {
//foreach (IGalleryObject mediaObject in album.GetChildGalleryObjects(GalleryObjectType.External))
//{
// // Check for existence of thumbnail.
// if (this.OverwriteThumbnail || !File.Exists(mediaObject.Thumbnail.FileNamePhysicalPath))
// {
// mediaObject.RegenerateThumbnailOnSave = true;
// HelperFunctions.UpdateAuditFields(mediaObject, this._userName);
// mediaObject.Save();
// mediaObject.IsSynchronized = true;
// }
//}
        }


Aside from not being able to display a thumbnail set by default, everything seems working.

Will there be other side effects?
Roger Martin
#9 Posted : Monday, 9 March 2009 12:42:42 AM(UTC)
Roger Martin

Rank: Administration

Joined: 3/08/2007(UTC)
Posts: 3,300
Location: Fort Atkinson, WI

That should be fine.
Roger Martin
Creator and Lead Developer of Gallery Server Pro
marty1101
#10 Posted : Tuesday, 10 March 2009 2:55:19 PM(UTC)
Rank: Advanced Member

Joined: 4/01/2009(UTC)
Posts: 37
Location: Taipei, Taiwan

Goal: To host thumbnails and images on the internet

Benefits:
1. Reduce the storage on the server where space is limited
2. Put the images geographically close your target audience - shorter image load time
3. Give the user freedom of choice and flexibility as where to host images

Assumptions:
1. All external objects on the site are images (external or on-server)
2. User can easily obtain the thumbnail and image urls
3. These urls never expire

Story:
I host my site for $30 a year including 500MB storage and 5GB bandwidth. The 500MB storage
really can't host many photos. A Flickr Pro account gives you unlimited storage and bandwidth
for $25 a year. I thought: why don't I put my photos on Flickr and display on my web site?
The design of this fix is not limited to Flickr but to any http urls where you can put your
photos. I just use Flickr for now.

Brief of the uploading SOP [Flickr], for example:
1. Upload photos to your Flickr account with specified tags or other methods that let you search for them later.
2. Get the title, thumbnail urls and the image urls from any software (I use Friendly.Flickr)
3. Put thse three set of info as three columns in excel
4. Create an album in GSP
5. Pick the album you created and copy&past the three columns (title, thumbnail url, image url) onto the page. Be careful with the format. The script doesn't do very well to detect errors in your data. Please see the example excell file.
6. The script obtain the widths and heights of these thumbnails and images and put all information in the database
7. The page turns to the newly created album page

Requirements:
1. Use Gallery Server Pro v2.2.3286 source version to build new dlls
2. Create a new table and link to GSP's gs_MediaObject table

Modifications to Gallery Server Pro v2.2.3286:

A. \Website\CodeFiles\GalleryPage.cs [GalleryServerPro.Web.dll]
1. Include marty1101 namespace
using marty1101;

2. Display thumbnails for external images
Code:

        public string GetThumbnailUrl(IGalleryObject galleryObject)
        {
/* Original codes
if (galleryObject is Album)
return GetAlbumThumbnailUrl(galleryObject);
else
return GetMediaObjectUrl(galleryObject, DisplayObjectType.Thumbnail);
*/

#region marty1101
marty1101_GSP m = new marty1101_GSP();
if (galleryObject is Album)
{
if (galleryObject.Thumbnail.MediaObjectId > 0)
{
IGalleryObject ThumbnailGalleryObject = Factory.LoadMediaObjectInstance(galleryObject.Thumbnail.MediaObjectId);
if (ThumbnailGalleryObject.Original.DisplayType == DisplayObjectType.External)
{
// Get thumbnail images hosted on Flickr. HostUid=1
return m.GetExternalThumbnailUrl(ThumbnailGalleryObject.Original.MediaObjectId, 1);
}
else
{ return GetAlbumThumbnailUrl(galleryObject); }
}
else
{ return GetAlbumThumbnailUrl(galleryObject); }
}
else if (galleryObject.Original.DisplayType == DisplayObjectType.External)
{
// Get thumbnail images hosted on Flickr. HostUid=1
return m.GetExternalThumbnailUrl(galleryObject.Original.MediaObjectId, 1);
}
else
{
return GetMediaObjectUrl(galleryObject, DisplayObjectType.Thumbnail);
}
#endregion marty1101
        }
    


3.Include external object in slideshow
Code:

        private static int GetNextMediaObjectIdForSlideshow(int mediaObjectIndex, IGalleryObjectCollection siblings)
        {
            int nextMediaObjectId = 0;
            while (mediaObjectIndex < (siblings.Count - 1))
            {
                IGalleryObject nextMediaObject = siblings[mediaObjectIndex + 1];

/* Origional Code
* if (nextMediaObject is GalleryServerPro.Business.Image)
*/
#region marty1101
if (nextMediaObject is GalleryServerPro.Business.Image || nextMediaObject is GalleryServerPro.Business.ExternalMediaObject)
#endregion marty1101

{
                    nextMediaObjectId = nextMediaObject.Id;
                    break;
                }

                mediaObjectIndex += 1;
            }

            return nextMediaObjectId;
        }
    


B. \TIS.GSP.Business\SynchronizationManager.cs [GalleryServerPro.Business.dll]
1. To avoid "Synchronization" updating gs_MediaObject.ThumbnailWidth and gs_MediaObject.ThumbnailHeight to generic values
Code:

        private void SynchronizeExternalMediaObjects(IAlbum album)
        {
/* Original Codes
foreach (IGalleryObject mediaObject in album.GetChildGalleryObjects(GalleryObjectType.External))
{
// Check for existence of thumbnail.
if (this.OverwriteThumbnail || !File.Exists(mediaObject.Thumbnail.FileNamePhysicalPath))
{
mediaObject.RegenerateThumbnailOnSave = true;
HelperFunctions.UpdateAuditFields(mediaObject, this._userName);
mediaObject.Save();
mediaObject.IsSynchronized = true;
}
}
*/
#region marty1101
// Do nothing here. The above codes generate the default thumbnail for external objects when there is no default thumbnail existed.
// Since the thumbnail for an external object is assigned in gs_ExternalThumbnail table, there is no need for the default thumbnail.
#endregion
}
    


C. \Website\CodeFiles\Util.cs [GalleryServerPro.Web.dll]
1. Solve the conflicts between the global.asax files of CommunityServer and GSP. Make GSP not relying on global.asax
Code:

        public static void InitializeApplication()
        {
            try
            {
// Set application key so ComponentArt knows it is properly licensed.

#region marty1101
                HttpContext.Current.Application["ComponentArtWebUI_AppKey"] = "This edition of ComponentArt Web.UI is licensed for Gallery Server Pro application only.";
#endregion marty1101

// Add a dummy value to session so that the session ID remains constant. (This is required by Util.GetRolesForUser().)
                HttpContext.Current.Session.Add("1", "1");

                // Set web-related variables in the business layer and initialize the data store.
                InitializeBusinessLayer();

                // Delete anonymous profiles, if they exist, to minimize the database clutter.
                DeleteAnonymousProfiles();

                // Validate users, roles and profiles.
                ValidateMembership();
            }
            catch (System.Threading.ThreadAbortException) { }
            catch (Exception ex)
            {
                // Let the error handler deal with it. It will decide whether to transfer the user to a friendly error page.
                // If the function returns, that means it didn't redirect, so we should re-throw the exception.
                HandleGalleryException(ex);
                throw;
            }
        }
    


D. Issues:
1. "Rearrange" function updates gs_MediaObject.ThumbnailWidth and gs_MediaObject.ThumbnailHeight, gs_MediaObject.OriginalWidth and gs_MediaObject.OriginalHeight to generic values.
2. "Rearrange" function generate generic image files on disk

\TIS.GSP.Business\MediaObjectSaveBehavior.cs [GalleryServerPro.Business.dll]
Code:

        public void Save()
        {
            // If the user requested a rotation, then rotate and save the original. If no rotation is requested,
            // the following line does nothing.
/* Original Code
            this._galleryObject.Original.GenerateAndSaveFile();
*/
#region marty1101
if (!(this._galleryObject.Original.DisplayType == DisplayObjectType.External && this._galleryObject.Original.ExternalType == MimeTypeCategory.Image))
{ this._galleryObject.Original.GenerateAndSaveFile(); }
#endregion

            // Generate the thumbnail and optimized versions. These must run after the previous statement because when
            // the image is rotated, these methods assume the original has already been rotated.
            try
            {
/* Original Code
                this._galleryObject.Thumbnail.GenerateAndSaveFile();
*/
#region marty1101
if ( !(this._galleryObject.Original.DisplayType == DisplayObjectType.External && this._galleryObject.Original.ExternalType == MimeTypeCategory.Image) )
{ this._galleryObject.Thumbnail.GenerateAndSaveFile(); }
#endregion

this._galleryObject.Optimized.GenerateAndSaveFile();
}
            catch (UnsupportedImageTypeException)
            {
                // We'll get here when there is a corrupt image or the server's memory is not sufficient to process the image.
                // When this happens, replace the thumbnail creator object with a GenericThumbnailCreator. That one uses a
                // hard-coded thumbnail image rather than trying to generate a thumbnail from the original image.
                // Also, null out the Optimized object and don't bother to try to create an optimized image.
                this._galleryObject.Thumbnail.DisplayObjectCreator = new GenericThumbnailCreator(this._galleryObject);
                this._galleryObject.Thumbnail.GenerateAndSaveFile();

                this._galleryObject.Optimized = new NullObjects.NullDisplayObject();
            }


            // Update the metadata if required.
            if (this._galleryObject is Image)
            {
                UpdateMetadata();
            }

            // Save the data to the data store
            Factory.GetDataProvider().MediaObject_Save(this._galleryObject);
        }


\TIS.GSP.Business\GalleryObject.cs [GalleryServerPro.Business.dll]
Code:

        private void ValidateSave()
        {
            if ((!this.IsNew) && (!this.IsInflated))
            {
                throw new System.InvalidOperationException(Resources.GalleryObject_ValidateSave_Ex_Msg);
            }

            ValidateSequence();

            // Set RegenerateThumbnailOnSave to true if thumbnail image doesn't exist.
/* Original Code
CheckForThumbnailImage();
*/
#region marty1101
if ( !(this.Original.DisplayType == DisplayObjectType.External && this.Original.ExternalType == MimeTypeCategory.Image) )
{ CheckForThumbnailImage(); }
else
{ RegenerateThumbnailOnSave = false; }
#endregion

// Set RegenerateOptimizedOnSave to true if optimized image doesn't exist. This is an empty virtual method
            // that is overridden in the Image class. That is, this method does nothing for non-images.
            CheckForOptimizedImage();

            // Make sure the audit fields have been set.
            ValidateAuditFields();
        }


\TIS.GSP.Business\ExternalMediaObject.cs [GalleryServerPro.Business.dll]
Code:

        internal ExternalMediaObject(int id, int parentId, IAlbum parentAlbum, string title, string hashKey, string thumbnailFilename,
         int thumbnailWidth, int thumbnailHeight, int thumbnailSizeKb, string originalFilename,
         int originalWidth, int originalHeight, int originalSizeKb, string externalHtmlSource, MimeTypeCategory mimeType, int sequence,
         string createdByUsername, DateTime dateAdded, string lastModifiedByUsername, DateTime dateLastModified,
         bool isPrivate, bool isInflated)
        {
...................
...................
            switch (mimeType)
            {
                case MimeTypeCategory.Audio:
                    this.Original.Width = GalleryServerPro.Configuration.ConfigManager.GetGalleryServerProConfigSection().Core.DefaultAudioPlayerWidth;
                    this.Original.Height = GalleryServerPro.Configuration.ConfigManager.GetGalleryServerProConfigSection().Core.DefaultAudioPlayerHeight;
                    break;
                case MimeTypeCategory.Video:
                    this.Original.Width = GalleryServerPro.Configuration.ConfigManager.GetGalleryServerProConfigSection().Core.DefaultVideoPlayerWidth;
                    this.Original.Height = GalleryServerPro.Configuration.ConfigManager.GetGalleryServerProConfigSection().Core.DefaultVideoPlayerHeight;
                    break;
                case MimeTypeCategory.Image:
#region marty1101
this.Original.Width = originalWidth;
this.Original.Height = originalHeight;
this.Original.FileName = originalFilename;
this.Original.FileSizeKB = originalSizeKb;
break;
#endregion
                case MimeTypeCategory.Other:
                    this.Original.Width = GalleryServerPro.Configuration.ConfigManager.GetGalleryServerProConfigSection().Core.DefaultGenericObjectWidth;
                    this.Original.Height = GalleryServerPro.Configuration.ConfigManager.GetGalleryServerProConfigSection().Core.DefaultGenericObjectHeight;
                    break;
            }
...................
...................
        }


Added codes:

A. Create a new project in the source solution: marty1101 and add related references; and include these files:
marty1101_Image.cs
marty1101_GSP.cs

B. The page that let you add photos to GSP: (you can put wherever in your site)
add_external_image.aspx
add_external_image.aspx.cs

These files are in the attached zip

Steps of modifications:

1. Create a new table in the database called gs_ExternalThumbnail. The SQL command:
Create_gs_ExternalThumbnail.sql
The SQL command also creates a constraint to link gs_ExternalThumbnail.MediaObjectId to gs_MediaObject.MediaObjectId, so that when a media object was deleted in gs_MediaObject, the related rows in gs_ExternalThumbnail would be deleted.

2. Once all the above are in place, compile the solution and get these new dlls:
GalleryServerPro.Web.dll
GalleryServerPro.Business.dll
GalleryServerPro.Web.dll
marty1101.dll

3. Put these in your web \bin and replace the old ones

4. browse to add_external_image.aspx and you're ready to go!

These codes were written to make it work asap. I've tried the best to make it easy to do for future versions of GSP. There're still more can be done and you're welcome to modify. Please comment.

If there were mistakes in this document, please let me know.
File Attachment(s):
[MOD] Host photos on the Internet.zip (17kb) downloaded 9 time(s).
Roger Martin
#11 Posted : Wednesday, 11 March 2009 12:15:23 AM(UTC)
Roger Martin

Rank: Administration

Joined: 3/08/2007(UTC)
Posts: 3,300
Location: Fort Atkinson, WI

Thanks for the submission and thorough documentation. I hope it helps someone.
Roger Martin
Creator and Lead Developer of Gallery Server Pro
marty1101
#12 Posted : Wednesday, 11 March 2009 6:04:23 PM(UTC)
Rank: Advanced Member

Joined: 4/01/2009(UTC)
Posts: 37
Location: Taipei, Taiwan

Another problem was found yesterday and fixed it today.

With external images, the "Rearrange" function causes:
1. "Rearrange" function updates gs_MediaObject.ThumbnailWidth and gs_MediaObject.ThumbnailHeight, gs_MediaObject.OriginalWidth and gs_MediaObject.OriginalHeight to generic values.
2. "Rearrange" function generate generic image files on disk

I traced and modified three files:
\TIS.GSP.Business\MediaObjectSaveBehavior.cs
\TIS.GSP.Business\GalleryObject.cs
\TIS.GSP.Business\ExternalMediaObject.cs

and also fixed a bug in add_external_image.aspx.cs
The sequence of photos should start from 0 instead of 1.

A question raised during tracing:
In \TIS.GSP.Business\ExternalMediaObject.cs,
Code:

            switch (mimeType)
            {
                case MimeTypeCategory.Audio:
                    this.Original.Width = GalleryServerPro.Configuration.ConfigManager.GetGalleryServerProConfigSection().Core.DefaultAudioPlayerWidth;
                    this.Original.Height = GalleryServerPro.Configuration.ConfigManager.GetGalleryServerProConfigSection().Core.DefaultAudioPlayerHeight;
                    break;
                case MimeTypeCategory.Video:
                    this.Original.Width = GalleryServerPro.Configuration.ConfigManager.GetGalleryServerProConfigSection().Core.DefaultVideoPlayerWidth;
                    this.Original.Height = GalleryServerPro.Configuration.ConfigManager.GetGalleryServerProConfigSection().Core.DefaultVideoPlayerHeight;
                    break;
                case MimeTypeCategory.Image:
                case MimeTypeCategory.Other:
                    this.Original.Width = GalleryServerPro.Configuration.ConfigManager.GetGalleryServerProConfigSection().Core.DefaultGenericObjectWidth;
                    this.Original.Height = GalleryServerPro.Configuration.ConfigManager.GetGalleryServerProConfigSection().Core.DefaultGenericObjectHeight;
                    break;


I found when creating an ExternalMediaObject object, several columns in the database wasn't retrieved. When it's a "external image', the trace go through "MimeTypeCategory.Other". There should be at least a "break;" after "case MimeTypeCategory.Image:". and I added some codes here. FYI.
Code:

            switch (mimeType)
            {
                case MimeTypeCategory.Audio:
                    this.Original.Width = GalleryServerPro.Configuration.ConfigManager.GetGalleryServerProConfigSection().Core.DefaultAudioPlayerWidth;
                    this.Original.Height = GalleryServerPro.Configuration.ConfigManager.GetGalleryServerProConfigSection().Core.DefaultAudioPlayerHeight;
                    break;
                case MimeTypeCategory.Video:
                    this.Original.Width = GalleryServerPro.Configuration.ConfigManager.GetGalleryServerProConfigSection().Core.DefaultVideoPlayerWidth;
                    this.Original.Height = GalleryServerPro.Configuration.ConfigManager.GetGalleryServerProConfigSection().Core.DefaultVideoPlayerHeight;
                    break;
                case MimeTypeCategory.Image:
#region marty1101
this.Original.Width = originalWidth;
this.Original.Height = originalHeight;
this.Original.FileName = originalFilename;
this.Original.FileSizeKB = originalSizeKb;
break;
#endregion
                case MimeTypeCategory.Other:
                    this.Original.Width = GalleryServerPro.Configuration.ConfigManager.GetGalleryServerProConfigSection().Core.DefaultGenericObjectWidth;
                    this.Original.Height = GalleryServerPro.Configuration.ConfigManager.GetGalleryServerProConfigSection().Core.DefaultGenericObjectHeight;
                    break;


I'll update the previous post to include the new changes.
Roger Martin
#13 Posted : Thursday, 12 March 2009 6:40:11 AM(UTC)
Roger Martin

Rank: Administration

Joined: 3/08/2007(UTC)
Posts: 3,300
Location: Fort Atkinson, WI

The original code is correct. By not having a break I am letting the MimeTypeCategory.Image fall through to the MimeTypeCategory.Other, which is what I want.

External objects are a little tricky to understand (and deal with) in code. Remember that external objects are nothing more than snippets of HTML that is rendered by GSP. You specify what that HTML is, either through the add external objects page or through code (like I think you are doing). That HTML is often an iframe or some other block level HTML element that has a width and height defined within the HTML.

GSP doesn't attempt to figure out what the real width or height of the HTML snippet is. In fact, the width and height fields in the database are ignored and not used by the app, and so it doesn't matter what we set them to. I am talking about these fields: OptimizedWidth, OptimizedHeight, OriginalWidth, & OriginalHeight.

That is not quite true. There is one place we need the width.

The next and previous buttons are displayed in a table with a width calculated based on the widest media object in an album. Since GSP doesn't know how wide an HTML fragment is, it uses the OriginalWidth or OptimizedWidth to figure it out. That is the only reason why the code you cited is assigning values to the width and height. Actually, I don't think the height field is ever used by GSP for an external media object.

I'm not sure how this affects your customization, but hopefully this explanation makes sense and helps you move forward.
Roger Martin
Creator and Lead Developer of Gallery Server Pro
marty1101
#14 Posted : Thursday, 12 March 2009 3:47:32 PM(UTC)
Rank: Advanced Member

Joined: 4/01/2009(UTC)
Posts: 37
Location: Taipei, Taiwan

Thanks for the explanation. Since what I'm trying to do is different from the design logic, conflicts may occur in other places where I haven't bump into yet.

If these fields: OptimizedWidth, OptimizedHeight, OriginalWidth, & OriginalHeight were inserted with the generic values at the first place, it would be the same values when retrieving them. If I put other values at the first place, wouldn't it be nice to get the actual values from the database?

Well, I found out this by comparing all values before and after rearranging an album. I thought these values may be useful in future uses, such as having a flash slideshow viewer who may want to know the size ... etc. Also, my script retrieves the images and get the size numbers at the time of adding the external images. It takes about 1.5 sec for an images. That's quite some time and resources. Since I've got the information in the database, I can use it when needed instead of retrieving again at run time. and, I found ThumbnailWidth & ThumbnailHeight are the actual values instead of the generic values. This looks odd to me. I was scratching my head while discovering this difference.

The logic of having the HTML snippet input by the user can't quite be understood.
1. I don't want the user to break the layout.
2. The user may not know how to do html.

Well, it seems more like a control-freedom trade-off.

Today, another issue came up.

Syncronizing the current album(/wedding/shannon) makes the image(Seq=0) the album thumbnail. However, syncronizing the upper-level album (/wedding) makes the first image(before rearranging) the album thumbnail. A different behavior of Syncornize here.

Syncornizing all albums seems to be a usual need by me at this stage. What I would like to do is rearranging the album thumbnail image to be the first image(seq=0) and having it to be the album thumbnail after sync all albums. I only tested external images, but logically I think it's the same behavior for images on disk.

and another issue that I haven't double-confirmed yet:
sync and rearrange start Seq from 0. but, adding images on disk start Seq from 1.
Roger Martin
#15 Posted : Friday, 13 March 2009 12:48:34 AM(UTC)
Roger Martin

Rank: Administration

Joined: 3/08/2007(UTC)
Posts: 3,300
Location: Fort Atkinson, WI

I didn't understand everything you wrote but I'll mention a couple things.

1. The embed code provided by YouTube and other media sites is in HTML format, so that's why the external objects accept HTML.

2. You are right that there is an inconsistency in sequence numbers, but it's a little different than you describe. In my test, I saw synch and add objects start at 1, and rearrange start at 0. This is an easy fix, but in the interest of "if it ain't broke, don't fix it" I may leave it alone, since I'm not aware of any negative side effects to the current behavior.
Roger Martin
Creator and Lead Developer of Gallery Server Pro
Rss Feed  Atom Feed
Users browsing this topic
Guest
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.