wiki:ProcessingEmbeddedMedia

How Image/Media/Attachment? Files are Embedded in eXe

NB This draft was built from a discussion held on IRC on 2007-08-23 and represents how images, media, mathematics images, and attachments are processed by eXe 1.00.

Here's the nutshell on how images, media, the LaTeX-based math images, and even other file resources that are embedded or attached with the text link button really get embedded:

  1. they all follow the same paradigm of first copying the desired file into a previews directory,
  2. and then, when processing the edits, actually creating a resource of the file.

A more step-by-step is as such:

  1. The magical file browser callback for each of these TinyMCE buttons is tied to our Javascript code, exe/webui/scripts/common.js:chooseImage_viaTinyMCE() except for the custom exemath plugin, which instead uses: exe/webui/scripts/common.js:makeMathImage_viaTinyMCE() (between which you will find definite similarities)
  2. This next part is really the key to how we easily get the file into the server's file space without using something more AJAXy, since we KNOW that our client-server architecture happens to be sitting on the same machine. As such, we break a rule in the following bit, and actually copy the file across that known boundary. That is done in:
    1. the Javascript makes a server call via twisted/nevow using window.parent.nevow_clientToServerEvent('previewTinyMCEimage',...)
    2. the server handles this event previewTinyMCEimage in exe/xului/mainpage.py:goingLive()
    3. which actually calls the specific event handler in exe/xului/mainpage.py:handleTinyMCEimageChoice() and that's where the file is copied from its original local source into the temporary spot in the server's previews directory.
    4. once the server handling returns to common.js's Javascript, chooseImage_viaTinyMCE() finally ends with writing the appropriate previews-path to the file into the calling TinyMCE dialog's URL field.
  3. So that's the first real section of stuff that goes on, all behind the scenes of the TinyMCE dialog's file browser button.

At this point, the file is sitting in previews, and all paths reference previews. It's all in a temporary holding spot, awaiting to become a "real" resource. Now, why not go ahead and do all of that right now at this point? Perhaps because..... the whole communication pipeline initiated by TinyMCE is actually a bit particular, and in trying to do too much more, it falls apart :-( For example, what I would have REALLY wanted to do was to create the real eXe resource right there, except that its name could have been changed at that point due to resource unique-ification (think about adding a few different file1.jpgs - internally, we will store them as file1.jpg, file1.1.jpg, file1.2.jpg, etc.) (And THAT'S something that we are also interested in changing down the road, how we handle resources.... we have been living with early design decisions to flatten the entire resource tree into a single directory, which is why they needed to be unique names. But we're not fond of that, and might improve that as we get into other areas. But for now, that's how it behaves.)

So, looking at the JS still....

07:28:48  <r3m0_h0me> So, looking at the JS still....
07:29:09  <r3m0_h0me> IF I wanted to have the server generate a real resource at that point,
07:29:23  <r3m0_h0me> then the server handler would need to return the file name which was created.
07:29:55  <r3m0_h0me> And the whole darned twisted/nevow asynchronous architecture doesn't really do "return values", per se,
07:30:32  <r3m0_h0me> but will instead require a callback function which CAN be fine in some cases (see how we do Printing, if you would like to see a multi-layered callback chain),
07:30:53  <r3m0_h0me> but NOT whilst in the TinyMCE callback chain already.... at least, not from what I could do.
07:31:44  <r3m0_h0me> It might be possible, indeed.  I just found that I couldn't get back to the TinyMCE dialog window after multiple client JS -> server Python -> client JS callbacks :-(
07:32:08  <r3m0_h0me> So.... (sorry if this is too much info!)
07:32:29  <r3m0_h0me> back at the JS ranch,
07:32:32  <eburnett> Not at all ;) I'm drinking every word up..
07:32:38  <r3m0_h0me> cool :-)
07:33:02  <r3m0_h0me> the common.js:chooseImage_viaTinyMCE() routine
07:33:54  <r3m0_h0me> can do a temporary unique-ification of its own (essentially just flattening the entire pathname), just in case multiple "file1.jpgs"s end up being added at the same time, and
07:35:02  <r3m0_h0me> can make some very simple, well, simplifications, in this process, just to get a filename into TinyMCE's URL field that matches the filename that the server's mainpage.py copied into place.    without anymore callbacks :-)
07:35:05  <r3m0_h0me> okay, enough of that part.
07:35:14  <r3m0_h0me> (or is it - any questions there?)
07:36:07  <eburnett> Haha it's overwhelming, but it's a start.. no questions for now, please continue..
07:36:11  <eburnett> ;)
07:36:49  <r3m0_h0me> one thing you'll also see in the xul/mainpage.py is that it pairs up an info file (maybe *.exe_info ?) with the previews file, so that when it later makes a full resource out of it, it can get it as close as possible to the original filename, regardless of any simplications that the common.js JS did.  but on to the rest of it.....
07:37:13  <r3m0_h0me> Okay, so as a user you might add a few different images, media, text links, whatever into your active authoring session in TinyMCE.
07:37:34  <r3m0_h0me> the next chunk o' magic happens when you hit the green checkmark.
07:38:48  <r3m0_h0me> every iDevice field (and quite literally, the field class) that can embed any TinyMCE resource, or is even TinyMCE rich-text-editable at all, will extend from exe/engine/field:FieldWithResources
07:39:28  <r3m0_h0me> there are only a few of them, primarily TextArea, and maybe FeedbackField and ClozeField or something (?)
07:39:47  <r3m0_h0me> they are all defined in exe/engine/field.py  (oops, I had left that .py off above)
07:40:08  <eburnett> yeah I've looked through field.py actually
07:40:16  <r3m0_h0me> cool.
07:40:41  <r3m0_h0me> well then you might already have a good idea that whenever you hit that green checkmark, it calls process() on each field that has been authored.
07:41:10  <r3m0_h0me> ooooh, wait, I might be getting slightly ahead....
07:41:49  <r3m0_h0me> I'd better pull the code up, for I believe that it is in its corresponding element.py class that the process() will be called.
07:41:59  <eburnett> k
07:42:12  <r3m0_h0me> eXe's fields and elements go hand-in-hand,
07:42:44  <r3m0_h0me> with fields essentially being the actually data structure to maintain the iDevice's data, and as an interface into its persistence,
07:43:04  <r3m0_h0me> and the elements being related to the viewing, the rendering, of the fields.
07:43:36  <r3m0_h0me> exe/webui/element.py
07:43:43  <r3m0_h0me> has all of the basic elements defined
07:44:06  <r3m0_h0me> You'll also see in that webui directory many "blocks",
07:44:34  <r3m0_h0me> and each block is to an iDevice as an element is to a field.  the iDevice is essentially a container of fields,
07:45:08  <r3m0_h0me> and its corresponding block is really responsible for ensuring that each of the corresponding elements exist for each field.
07:45:28  <eburnett> It's so good you're writing all this out.. when I first started looking through exe's source I kindof figured out the block/iDevice relationship after alot of trial & error
07:45:38  <r3m0_h0me> but that's a higher-level bit of info that you don't really need for the rest of our discussion.
07:45:40  <r3m0_h0me> cool!
07:46:02  <r3m0_h0me> yeah, the more of this that you do understand, the more it can all fit in to a more coherent whole
07:46:17  <r3m0_h0me> whether that's good or bad, it's a whole :-)
07:46:23  <eburnett> and the more I can actually potentially contribute back to you guys ;)
07:46:32  <eburnett> At least with more detailed bug reports - haha.
07:46:34  <r3m0_h0me> oh, man, how we would LOVE that!
07:46:52  <r3m0_h0me> in ANY element!  we really are down to just 2 coders now, and it's rough.
07:46:58  <eburnett> Wow..
07:47:14  <r3m0_h0me> yeah, not as a complaint, but just a fact of eXe life.
07:47:28  <r3m0_h0me> and we have taking the philosophy that....
07:47:49  <r3m0_h0me> now that eXe v1.0 is out there, and more and more requests and bug tickets (hopefully not :-) ) will be coming in,
07:48:12  <r3m0_h0me> we might have to direct more and more of the potential developers out there (you!!!! excellent!!!) on how to do some of these,
07:48:29  <r3m0_h0me> especially if we want to begin making any bigger changes to some of the architectural issues such as:
07:49:50  <r3m0_h0me> the resource structure (as mentioned) and the entire file storage mechanism (getting away from the mystical and all too crazy .elps into something a bit more readable predicatable, and manageable, such as an XML-based file format which can be itself perhaps IMS or SCORM compliant or... ?????  anyway, I digress ;-) )
07:50:29  <r3m0_h0me> so, where were we?  oh yeah, element...
07:50:51  <r3m0_h0me> open up element.py and field.py "side by side"
07:51:07  <r3m0_h0me> and you'll see that each class has a partner class.
07:51:17  <r3m0_h0me> FieldWithResources has ElementWithResources
07:51:35  <r3m0_h0me> TextAreaField has TextAreaElement
07:51:38  <r3m0_h0me> and so on.
07:52:27  <r3m0_h0me> A quick note about the render methods (on TextAreaElement, for example),
07:52:47  <r3m0_h0me> [back in a moment...]
07:53:16  <eburnett> k
07:59:35  <r3m0_h0me> [trying to warm up my cold bones with a cup of tea, almost back]
08:00:41  <eburnett> haha no worries
08:03:35  <r3m0_h0me> some days it seems like Spring is on its way, but it still takes me half the day to thaw out ;-)
08:04:12  <r3m0_h0me> my Arizona blood is quite glad I didn't move down to the South Island! :-)
08:04:39  <r3m0_h0me> okay, render methods -
08:05:40  <r3m0_h0me> each element should have 3 of them: renderEdit() for eXe's authoring mode, using TinyMCE if applicable; renderPreview() for eXe's preview mode; and renderView() for exports, prints, and so on.
08:06:00  <r3m0_h0me> each element should also have a process() method,
08:07:11  <eburnett> Gotcha (figured that one out on my own as well, the 3 methods)
08:07:12  <r3m0_h0me> and looking at TextAreaElement's process() method,
08:07:17  <r3m0_h0me> (cool!)
08:07:48  <r3m0_h0me> you should be able to see it calling right back to its field's ProcessPreviewed() method.
08:07:57  <r3m0_h0me> its field, of course being the TextAreaField.
08:08:14  <r3m0_h0me> (or, more accurately, an instance of TextAreaField)
08:08:22  <eburnett> yeah
08:08:50  <r3m0_h0me> on some of the more simple elements, such as TextElement, right above TextAreaElement,
08:09:04  <r3m0_h0me> you can see that it's process merely sets its field.content directly.
08:09:31  <r3m0_h0me> not so in the case of any field which can embed (any number of) resources - that's where the ProcessPreviewed() comes in.
08:10:05  <r3m0_h0me> but before we get to ProcessPreviewed() itself, there's one more important point I wanna show right here in TextAreaElement's process()...
08:10:43  <r3m0_h0me> good, bad, or ugly, the TextAreaField (and any FieldWithResources subclass) has 3 versions of "content":
08:10:54  <r3m0_h0me> content, content_w_resourcePaths, and content_wo_resourcePaths
08:12:05  <r3m0_h0me> we are now at least only persisting content_w_resourcePaths, and re-creating the other 2 from it during FieldWithResource's TwistedRePersist() method call when loading the data from the .elp.
08:14:10  <r3m0_h0me> we don't need to get into too much of that except to know that all 3 of the content versions are unfortunately currently necessary:  content_w_resourcePaths for preview mode (with its eXe resourceDir in the path), content_wo_resourcePaths for export mode (once the resources are further flattened into the same directory as, say, the web page directory), and content itself, which is really just a shortcut to whichever of the other two is currently active.
08:14:13  <r3m0_h0me> strange, but true.
08:14:29  <r3m0_h0me> and there might be better approaches for that, but, just know that they are there.
08:16:24  <r3m0_h0me> Okay, eburnett, so back to TextAreaElement's process(),
08:16:35  <eburnett> Amazing, I'm still with you..
08:17:17  <r3m0_h0me> you'll notice that it first does the ProcessPreviewed(), and then essentially pulls out all of the "resource/" resourceDir path references with a quick followup to MassageContentForRenderView().
08:17:49  <r3m0_h0me> nice!  tell me to stop whenever needed - ask any questions as we're going along.  But, believe it or not, we're coming to the end of this long crazy ride :-)
08:19:57  <r3m0_h0me> So, where in the big step 2 here - the user has hit the green checkbox, the active iDevice's block is going through each of its elements and calling their process() with their newly authored information, and the TextAreaElement (for example) now calls its TextAreaField's ProcessPreviewed().
08:20:12  <r3m0_h0me> let's go into exe/engine/field.py:FieldWithResources
08:21:39  <r3m0_h0me> it's got a whole bunch of other helper routines, such as the TwistedRePersist, and some ListActiveImageResources,
08:22:11  <r3m0_h0me> and RemoveZombieResources, but the bit one really is ProcessPreviewed() and its specific versions,
08:23:46  <r3m0_h0me> (oh yeah, but first quick tangent on the use of the word Image in routines such as ListActiveImageResources, and even back in common.js's chooseImage_viaTinyMCE() - in some cases it has grown to include ALL of the resources, and isn't specific to images anymore, as you may have already guessed.
08:24:23  <r3m0_h0me> in the case we're about to get to, within ProcessPreviewedXXXXX(), though, it really is specific to that type:)
08:24:45  <r3m0_h0me> ProcessPreviewedImages(), ProcessPreviewedMedia(), and now the new(!!) ProcessPreviewedLinkResources()
08:24:57  <r3m0_h0me> all pretty much do the same thing, with the same overall processing loop,
08:25:32  <r3m0_h0me> and could have been consolidated into a much better processing/parsing paradigm.  They weren't though ;-)  not yet at least :-)
08:26:41  <r3m0_h0me> I do imagine that we would have one big processing loop that could be called with a few variations for the specific kind of file resources that are being embedded, but for now, just know that only a few parts are different, and they'll be easy enough to follow along.
08:27:47  <r3m0_h0me> So far everything has been the same whether adding an image or a media object or a text link "attachment", and I was planning on going into ProcessPreviewedImages() just because it was the first one of these created, but....
08:28:05  <r3m0_h0me> eburnett: would  you rather go through ProcessPreviewedMedia() specifically?  either way, the concepts are the same.
08:28:38  <eburnett> Let's do PreviewedMedia, if that's ok?
08:29:20  <r3m0_h0me> sure thing!  you'll find it very much like the others, and might indeed wonder why they're not already using the same structure ;-) but here we go....
08:30:37  <r3m0_h0me> ideally, these would all be using a real XHTML tag tree to process,
08:31:01  <r3m0_h0me> but instead, it's doing a very primitive string parsing to search for its strings of interest.
08:31:17  <r3m0_h0me> ProcessPreviewedMedia() begins by looking for:
08:31:24  <r3m0_h0me> search_str = "<param name=\"src\" value=\"/previews/"
08:32:36  <r3m0_h0me> so far, all of the media we have embedded follows the following object form (looking for an example):
08:33:15  <r3m0_h0me> well, shoot, let's look at this together in an active eXe session, shall we?  wanna follow along embedding some media?
08:33:39  <eburnett> Absolutely, show me the way ;)
08:34:11  <eburnett> (there will always be a slight delay as I truck around through various directories peeking at files in use, etc)
08:34:24  <r3m0_h0me> okay, I'm just starting up eXe right now - let's start with a very simple iDevice, maybe Activity, and start authoring it.
08:34:29  <r3m0_h0me> good, good!
08:34:41  <eburnett> hey could we just use Free Text (
08:34:52  <eburnett> only because everything our authors are doing is based on Free Text)
08:35:05  <r3m0_h0me> yup!
08:35:37  <r3m0_h0me> I was also just thinking that if we needed to get onto a phone call, Skype, or whatever for some of this, we could certainly do so.  But I'm enjoying this approach at the moment :-)
08:36:05  <r3m0_h0me> So, FreeText it is.  once you've got one open, go ahead and click on TinyMCE's media button.
08:36:13  <eburnett> k
08:36:34  <r3m0_h0me> and from its media window, go ahead and choose a file, selecting it such that it is in the URL field.
08:36:51  <r3m0_h0me> you're probably going to select a WMP file, aren't you? ;-)
08:37:08  <r3m0_h0me> they have one extra bit of information in their <object> tag, a "data=", from what I recall.
08:37:24  <eburnett> haha I'm going to do Flash actually
08:37:51  <r3m0_h0me> okay, Flash it is - I'll do the same.  Just know that WMPs have that 1 more attribute, but everything else is pretty much the same.
08:38:00  <eburnett> k
08:38:27  <r3m0_h0me> before even hitting INSERT on that Media dialog,
08:38:37  <r3m0_h0me> (but no worries if you did)
08:38:56  <r3m0_h0me> we can check the temporary previews directory to see that it was copied over.
08:39:01  <r3m0_h0me> In my case, the URL field now shows:
08:39:20  <r3m0_h0me> "/previews/_Users_r3m0_Movies_conctheatrericous.swf"
08:39:45  <eburnett> me too
08:39:58  <r3m0_h0me> which is really just the JS-uniqueified representation of my source file /Users/r3m0/Movies/conctheatreicous.swf.  cool.
08:40:13  <r3m0_h0me> okay, you're on Windows right now?
08:41:28  <r3m0_h0me> I'm on a Mac, so I can't confirm this at the moment, but offhand, I believe that Windows temporary directories are located in
08:41:46  <r3m0_h0me> your Documents and Settings \ yourname \ Local Settings \ Temp
08:41:54  <r3m0_h0me> or something like that.  Lemme know when you've found that.
08:42:04  <eburnett> k one sec
08:43:49  <eburnett> Yeah I can't actually find the temp directory, I am running Vista though
08:44:19  <r3m0_h0me> oh, shoot, I won't be able to help much there, but.... make sure that you are showing hidden and system files within your windows explorer.
08:44:30  <eburnett> of course
08:44:34  <r3m0_h0me> :-)
08:45:30  <r3m0_h0me> okay, here's a clue, then, if you can do an entire disk search for the "previews" directory, you should be able to find it.
08:45:48  <r3m0_h0me> and if not, we can certainly get by without looking at the actual disk - it's just nice to see what's happening on the file side of things as well.
08:46:28  <eburnett> I agree.. let me try the search
08:46:40  <r3m0_h0me> okay, I'll be back in a few minutes, then.
08:48:11  <eburnett> k
08:54:06  <r3m0_h0me> while you're searching for it, I could let you know that eXe has two primary temporary directories active:
08:54:35  <eburnett> yeah there is no /previews dir on my HD according to Vista.. built-in searching in Windows has always been brutal
08:55:09  <r3m0_h0me> did you have the / in there, as "/previews"?  perhaps without it, as "previews" might find it?
08:55:35  <eburnett> no it was just previews
08:55:39  <r3m0_h0me> shoot :-(
08:56:03  <r3m0_h0me> and you, of course, selected to search all hidden and system folders as well, eh? ;-)
08:56:13  <eburnett> actually I did that about 10 seconds before you typed it ;)
08:56:15  <eburnett> searching now..
08:56:22  <r3m0_h0me> cool :-)
08:56:23  <eburnett> Vista is still very new to me, everything's in a different place
08:56:26  <eburnett> buggy as hell actually..
08:56:45  <r3m0_h0me> I haven't yet had the (mis?)fortune :-)
08:56:56  <eburnett> ;
08:56:57  <eburnett> 0
08:57:03  <r3m0_h0me> are they releasing bug fixes for it pretty regularly?
08:57:12  <r3m0_h0me> SPs?
08:57:39  <eburnett> It's hard to tell here, something about the Windows Update services is causing us issues with our firewall.. or, I guess it's the other way around.
08:58:42  <eburnett> Yeah it wasn't able to find it either.
08:58:48  <eburnett> I could try this on XP once I get home..
08:59:20  <r3m0_h0me> yeah, okay.  maybe one more thing to try and look for (but doubtful it will find it either) is the name of the file that is in the previews directory.
08:59:57  <eburnett> in my case the swf.. good ida.
09:00:02  <eburnett> Good Ida!
09:00:12  <r3m0_h0me> (copy it straight out of the media dialog's URL field, after "/previews/")
09:00:38  <r3m0_h0me> ha ha, Good Ida! :-)
09:03:33  <r3m0_h0me> oh yeah, so, eXe has two primary temporary directories active:
09:04:01  <r3m0_h0me> one is this one, that has the previews directory in it, kind of a temporary holding space until things become real eXe resources,
09:04:11  <r3m0_h0me> and the other is... you guessed it, where the real eXe resources are kept!
09:04:29  <r3m0_h0me> So, if we can find these directories and watch the files during the progress,
09:04:33  <r3m0_h0me> what we'll see is
09:04:45  <r3m0_h0me> that the file first goes into the previews directory, until you hit the green checkbox,
09:05:02  <r3m0_h0me> at which point it will go into the resources directory, where all of the other resources are held,
09:05:26  <r3m0_h0me> and then the previews directory will be cleared out in case any zombie files remained, etc.
09:05:45  <r3m0_h0me> in fact, the files will NOT be deleted from the previews directory right when their corresponding resource is made,
09:05:51  <eburnett> gotcha (was unable to find the previews directory sadly)
09:06:08  <r3m0_h0me> because the same file could be added multiple times within an iDevice, whether in the same field or multiple fields, etc.
09:06:24  <r3m0_h0me> okay, bummer on that.  hopefully this information will get you going to look at it on you XP later.
09:06:37  <r3m0_h0me> and if you get a good idea of where that is, perhaps you can find it on Vista and let us know :-)
09:06:39  <eburnett> I think so.
09:06:52  <r3m0_h0me> as a tip... what I like to do in general,
09:07:03  <eburnett> Yeah I searched for C__Users_eburnett.APPLEBY_Desktop_fontname.swf, with the hidden files/folders option enabled and no luck..
09:07:28  <r3m0_h0me> is just look in the overall temporary directory, and keep the subdirectories sorted by last modification date/time;
09:07:40  <eburnett> Sure..
09:07:46  <r3m0_h0me> you'll typically find these two eXe temp directories to be the most recent, of course.  and the one with the previews
09:08:01  <r3m0_h0me> is one that ends in a .eXe, such as: tmp6Y6x3V.eXe
09:08:07  <r3m0_h0me> yup, easy enough.
09:08:50  <r3m0_h0me> okay, so, where were we? looking at the code, the field is about to ProcessPreviewed(), but not yet,
09:09:07  <r3m0_h0me> because we are still looking in eXe itself, and we can at least get a good understanding with the HTML source.
09:09:19  <r3m0_h0me> So, with our SWF that is in the media dialog, go ahead and hit INSERT.
09:09:47  <eburnett> k
09:10:08  <r3m0_h0me> Once you've done so, and are back in the TinyMCE editor for eXe's authoring mode, click on TinyMCE's HTML source editor and look at the page's source as it stands now:
09:10:13  <r3m0_h0me> (mine shows as...)
09:10:14  <r3m0_h0me> <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" width="100" height="100">
09:10:15  <r3m0_h0me>   <param name="play" value="false" />
09:10:15  <r3m0_h0me>   <param name="scale" value="exactfit" />
09:10:15  <r3m0_h0me>   <param name="src" value="/previews/_Users_r3m0_Movies_conctheatrericous.swf" />
09:10:15  <r3m0_h0me>   <param name="width" value="100" />
09:10:16  <r3m0_h0me>   <param name="height" value="100" />
09:10:18  <r3m0_h0me>   <embed type="application/x-shockwave-flash" play="false" scale="exactfit" src="/previews/_Users_r3m0_Movies_conctheatrericous.swf" width="100" height="100"></embed>
09:10:21  <r3m0_h0me> </object>
09:10:39  <eburnett> mine too.
09:10:57  <r3m0_h0me> again, WMP will have one more data="/previews/.." in its top <object> tag, but for this, we've got 2 occurrences of that path,
09:11:06  <r3m0_h0me> one in a <param name="src"....">
09:11:13  <r3m0_h0me> and another in the <embed src="...">
09:11:36  <r3m0_h0me> THIS is what FieldWithResources:ProcessPreviewedMedia() will be searching for.
09:12:10  <r3m0_h0me> hmmmmmm, how much of ProcessPreviewedMedia() do we wanna step through at this point,
09:12:31  <r3m0_h0me> or is some of that left as "an excercise for the reader", to just say that it DOES parse that information,
09:12:33  <r3m0_h0me> and....
09:12:44  <r3m0_h0me> lemme take a look and point you to the important part there.
09:12:51  <eburnett> Ok sounds good..
09:13:32  <eburnett> I'm going to save this entire conversation.. but this may be a step in the right direction to create a "primer" for new developers, to get their head around how the app works if they're completely unfamiliar with how the app is structured.
09:14:17  <r3m0_h0me> I think that's a great idea.  I haven't had to step through this with anybody yet, and it's probably the first opportunity I have really had to explain it in this much detail, too.
09:15:21  <eburnett> Well to be honest I probably neat to eat soon.. this is all golden information though. Would you be interested in all in writing it out into a document that I could look through?
09:18:24  <eburnett> r3m0 has filled my brain up to the brim ;)
09:21:07  <r3m0_h0me> okay, rest assured, eburnett, that there isn't much more either:  I think that there is only a tiny bit more that I will wrap up with the ProcessPreviewed*() stuff, specifically where the resources are then made.  And then a whole 'nuther discussion would be the TinyMCE media plugin itself, and how to add new media types into that.  But I'll probably save that for later as well.
09:21:19  <eburnett> ok ;)
09:21:30  <eburnett> I'm with you..
09:22:47  <eburnett> You're doing a great thing though, talking through it.. heck, you guys should make an .elp with video screen captures of you talking while browsing throug the code ;)
09:23:16  <r3m0_h0me> okay, thanks for all of your interest in this, eburnett!
09:23:43  <eburnett> I have a feeling at one point down the road I will be able to help, if that makes typing all this out any easier ;)
09:23:56  <r3m0_h0me> this is amazing to us, too, to have the opportunity to see some development begin outside of the team!
09:24:04  <r3m0_h0me> you betcha!
09:24:26  <eburnett> Talk soon guys!
09:25:22  <eburnett> k ttys!
09:25:27  <r3m0_h0me> cya!
09:26:36  <r3m0_h0me> Okay, so a quick wrap-up of this part of the media embedding process really ends with....
09:27:17  <r3m0_h0me> ProcessPreviewedMedia() looking for the relevant src tags, still pointing to a file in the "previews" directory,
09:27:29  <r3m0_h0me> and then creating a real eXe resource out of it, using
09:28:06  <r3m0_h0me> the GalleryImage as a wrapping class for the resource.
09:28:53  <r3m0_h0me> See field.py line#571 for the instantiation of the GalleryImage.
09:30:04  <r3m0_h0me> GalleryImage was initially specific to GalleryIDevice, but since it was one of the only (or THE only?) iDevice to be able to hold onto multiple resources, using a GalleryImages list, it was reused as the basis for all multi-resources.
09:31:24  <r3m0_h0me> When the file is passed to GalleryImage, that creates a real resource, unique-ifying the filename where necessary, and tying it to not only this field's list of resources (GalleryImages) but also this active package's list of resources (as per the lower-level resource behaviour).
09:31:59  <r3m0_h0me> And note that the filename passed to GalleryImage is not actually the name as it appeared in the "previews" directory,
09:32:41  <r3m0_h0me> but can be the original base name, if an .exe_info file exists and stores that original basename.
09:33:42  <r3m0_h0me> Finally, all relevant occurrences of the previous "previews" filename are changed in the HTML to reference the new storage name, as occurs in the eXe resourceDir (as referenced by "resources/..."), and
09:33:48  <r3m0_h0me> the parsed content is returned,
09:34:06  <r3m0_h0me> to be massaged into a content_wo_resourcePaths,
09:34:09  <r3m0_h0me> and that's about it!
09:34:12  <r3m0_h0me> "easy as" :-)
09:35:15  <r3m0_h0me> I'm sure I left a few other things out of there in the last couple minutes, but that's the general idea, and I think that as long as the main flow of data and objects from TinyMCE is understood, then the rest is just bits and pieces, details.
09:35:40  <r3m0_h0me> And again, a whole 'nuther' discussion is how to add stuff into the media plugin itself.