0

I have a Composite C1 4.04 site.

The user needs a blog - and they can upload images.

However, the images go into some weird virtual 'media' folder that apparently doesn't exist - and they aren't stored like normal images.

I would like them instead to just go into a regular folder - as I need to manipulate them later - to re-compress them (for example).

How can I do this?

thx

niico
  • 11,206
  • 23
  • 78
  • 161

1 Answers1

1

The media files are plugable in Composite C1, in the default implementation media files are represented as

  1. A record in a database, that contains file's meta data (mime type, etc)
  2. A physical file with the content, located under "\App_Data\Media" f.e. \App_Data\Media\0b11c288-5432-4482-a776-3eb0ac9ad437

This has certain advantages - having a database record allows to keep additional meta data relevant to serving http requests (such as MimeType), apply security to those files, etc. ; also file names don't follow file system restrictions (such as path length and certain reserved names/forbidden characters) - so when you upload a file, you don't have to care if website folder path + media folder path + file name would exceed 255 characters.

There are also other media archive plug-ings, when f.e. files are kept in a SQL data base or files are fetched from a Facebook album.

If you want to compress the image files, you can iterate over files in \App_Data\Media\ folder. You can get the list of media files by calling Get() on a DataConnection instance.

If you want to export media to a different solution, you can use the following code that copies a Composite C1 media folder to a physical folder:

private int MediaToFiles(string mediaFolder, string physicalFolder)
{
    if (!mediaFolder.StartsWith("/"))
    {
        mediaFolder = "/" + mediaFolder;
    }

    string mediaFolderPrefix = mediaFolder == "/" ? "/" : mediaFolder + "/";
    using (var conn = new DataConnection())
    {
        var mediaFiles = conn.Get<IMediaFile>().Where(f => string.Equals(f.FolderPath, mediaFolder, StringComparison.OrdinalIgnoreCase)
                                                           || f.FolderPath.StartsWith(mediaFolderPrefix, StringComparison.OrdinalIgnoreCase))
                                               .ToList();
        if(mediaFiles.Count == 0) return 0;

        Directory.CreateDirectory(physicalFolder);

        int newFiles = 0;

        foreach (var file in mediaFiles)
        {
            string targetFolder = file.FolderPath.Length <= mediaFolderPrefix.Length ?
                        physicalFolder : Path.Combine(physicalFolder, file.FolderPath.Substring(mediaFolderPrefix.Length));
            Directory.CreateDirectory(targetFolder);

            string targetFilePath = Path.Combine(targetFolder, file.FileName);

            if(File.Exists(targetFilePath) && File.GetLastWriteTime(targetFilePath) == file.LastWriteTime) continue;

            using (var stream = file.GetReadStream())
            {
                using (var outputStream = File.Create(targetFilePath, 8192))
                {
                    stream.CopyTo(outputStream);

                    outputStream.Close();
                }
            }

            File.SetLastWriteTime(targetFilePath, file.LastWriteTime.Value);

            newFiles++;
        }

        return newFiles;
    }
}



// Example of usage:
int newFiles = MediaToFiles("/", @"c:\Temp\C1media"); // Copying all the media files
OutPut("New files: " + newFiles);


int newFiles2 = MediaToFiles("/Office", @"c:\Temp\C1media\Office pictures"); // Copying only "Office" media folder
OutPut("New files: " + newFiles2);
Dmitry Dzygin
  • 1,258
  • 13
  • 26
  • Thanks very helpful. How could I abandon the media folder totally and just have users upload images to a physical folder (maybe with a guid added to filenames)? Having MIME types stored in a database just isn't worth the hassle for me. – niico Aug 28 '14 at 04:46
  • You would have to implement your own data provider, which could be a lot of work. See class Composite.Plugins.Data.DataProviders.MediaFileProvider.MediaFileProvider – Dmitry Dzygin Sep 12 '14 at 12:27
  • Thanks. I need to re-compress the images, perhaps there is a better image compression plug-in I could use instead. That would negate my need for this. – niico Sep 13 '14 at 14:05