This is a migrated thread and some comments may be shown as answers.

API to upload and extract ZIP

7 Answers 155 Views
Upload
This is a migrated thread and some comments may be shown as answers.
Andrew
Top achievements
Rank 1
Andrew asked on 13 Oct 2009, 08:10 AM
Hi

I would like to develop a module allowing admins to upload a zip file and extract the contents, in a similar way to the Sitefinity image/document library upload functionality. Is this zip & extract functionality available via an API, and are there any examples or documentation?

A zip file will contain a Silverlight app and various media/resources referenced by that app (a zip may be 50Mb+ and contain hundreds of files and folders). Am I right in saying it wouldn't be practical to extract the zip to a Sitefinity library because the Silverlight app couldn't easily reference the files, also performance issues due to size and numbers? Would a better approach be to extract to the file system, and is this possible through the Sitefinity zip/extract API?

Thanks in advance
Andy

7 Answers, 1 is accepted

Sort by
0
Ivan Dimitrov
Telerik team
answered on 13 Oct 2009, 10:39 AM
Hello Andrew,

You could upload Silverlight files to images and documents library of custom type where you do not have restriction about the extension of a file, but most probably the application will not work. The best way at this stage is uploading the application somewhere in your project - say in a root folder called SilverlightApplications.

Is this zip & extract functionality available via an API, and are there any examples or documentation?

Below is a sample code that illustrates using of ZipManager class.

private void UploadFiles(ILibrary library)
 {
      
         foreach (UploadedFile file in RadUploadControl.UploadedFiles)
         {
 
             ZipManager zipManager = new ZipManager();
             IZipArchive zipArchive = zipManager.GetZipArchive(file.InputStream);
             IAbstractFile[] archive = zipArchive.GetFiles(true);
 
             long filesSize = 0;
             if (library.MaxSize > 0)
             {
                 foreach (IAbstractFile item in archive)
                 {
                     filesSize += item.Size;
                     if (filesSize > library.MaxSize)
                     {
                         HttpContext.Current.Response.Write("FILE SIZE PROBLEM");
                         return;
                     }
                 }
             }
 
             int i = -1;
             foreach (IAbstractFile item in archive)
             {
                 i++;
                 double percentIncrement = 100 / (double)archive.Length;
                 progress["PrimaryTotal"] = archive.Length.ToString();
                 if (i != 0)
                     progress["PrimaryPercent"] = ((int)(i * percentIncrement)).ToString();
                 progress["PrimaryValue"] = (i + 1).ToString();
 
                 string extension = String.Empty;
                 string name;
                 string itemName = item.FullName.Substring(item.RootFolder.FullName.Length - 1);
                 if (item.Name.LastIndexOf(".") != -1)
                 {
                     extension = item.Name.Substring(item.Name.LastIndexOf('.'));
                     name = item.Name.Remove(item.Name.LastIndexOf("."));
                 }
                 else
                     name = item.Name;
 
                 Stream str = item.OpenRead();
                 byte[] buffer = new byte[item.Size];
 
                 long position = 0;
                 int currentByte = str.ReadByte();
                 while (currentByte != -1)
                 {
                     buffer[position++] = (byte)currentByte;
                     currentByte = str.ReadByte();
                 }
                 try
                 {
                     this.manager = new LibraryManager();
                     // JUST FOR THE SAMPLE
                     //ILibrary lib = manager.GetLibrary("silverlight");
                     //or set it from the parameter.
                     itemId = manager.UploadFile(buffer,
                                                 name,
                                                 extension,
                                                 MimeMapper.GetMimeMapping(item.Name),
                                                 item.Size,
                                                 library).ID;
                     uploadedFileIDs.Add(itemId.ToString());
                 }
                 catch (ArgumentException)
                 {
                     FilesToUpload.Add(itemName, "NOT VALID");
                     continue;
                 }
                 catch (Exception)
                 {
                     FilesToUpload.Add(itemName, "UNKNOWN");
                     continue;
                 }
 
                 if (itemId != Guid.Empty)
                     FilesToUpload.Add(itemId.ToString(), "SUCCESSFULL");
                 else
                     FilesToUpload.Add(itemName, "UNKNOWN");
             }
         }
         foreach (UploadedFile file in RadUploadControl.InvalidFiles)
         {
             if (!file.GetExtension().Equals(".zip", StringComparison.OrdinalIgnoreCase))
             {
                 HttpContext.Current.Response.Write("NOT VALID EXTENSION");
                 return;
             }
         }
      
 }
 
 private LibraryManager manager;
 private List<string> uploadedFileIDs = new List<string>();
 private Guid itemId;
 // just for the the sample
 private RadUpload RadUploadControl;



All the best,
Ivan Dimitrov
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Andrew
Top achievements
Rank 1
answered on 13 Oct 2009, 01:48 PM
Hi

Thanks for the response. With your help I've created a user control that allows a user to upload a zip then unzip it to a folder. The user control contains a RadProgressArea, RadUpload and a button to start the upload/unzip operation. Just a couple of minor issues now, if you could assist please:-

1) The RadProgressArea control is used to display progress during the file upload, and then during the unzip process (custom progress similar to your above code sample). Before the unzipping begins I want to change the progress area's Uploaded label to something more appropriate, e.g. "Unzipped:", so in my button click event I'm doing this:

UploadedFile f = RadUploadContext.Current.UploadedFiles[0];  
 
RadProgressArea1.Localization.Uploaded = "Unzipped: ";  
 
UnzipFiles(f);  
                                 

However the label never changes. Am I missing something? Is it something to do with AJAX/partial postbacks not updating the UI?

2) On the RadProgressArea I have DisplayCancelButton=true. Do I need to handle any kind of cancel event or will the Cancel button stop any current operation itself (either a file upload or unzipping)? (It's just that I've noticed after clicking Cancel that the w3wp memory usage stays high, so I don't know if it is carrying on with the unzipping, or it's just the GC kicking in).

Thanks again
Andy
0
Ivan Dimitrov
Telerik team
answered on 13 Oct 2009, 02:25 PM
Hi Andrew,

Below is a sample implementation of the desired functionality

protected void Page_Load(object sender, EventArgs e)
  {

      if (!IsPostBack)
      {
          RadProgressArea1.Localization.UploadedFiles = "Unzipped: ";
      }
      Button1.Click += new EventHandler(Button1_Click);
  }
 
  void Button1_Click(object sender, EventArgs e)
  {
      Telerik.Web.UI.RadProgressContext ProgressContex = Telerik.Web.UI.RadProgressContext.Current;
      ProgressContex.SecondaryTotal = "100";
      for (int i = 1; i < 100; i++)
      {
          ProgressContex.CurrentOperationText = "Uploading zip file percentage " + i.ToString();
              // FORCE STOP UPLOADING
          if (!Response.IsClientConnected)
          {
              break;
          }
          // SIMULATE TIME UPLOADING
          System.Threading.Thread.Sleep(100);
      }
  }
 
<telerik:RadUpload id="RadUpload1" runat="server" OverwriteExistingFiles ="true"TargetFolder="~/Files" />
<telerik:RadProgressManager ID="RadProgressManager1" runat="server" />
<telerik:RadProgressArea
 ID="RadProgressArea1"
 runat="server"
 DisplayCancelButton="True"
 ProgressIndicators="FilesCountBar,
 FilesCount,
 FilesCountPercent,
 SelectedFilesCount,
 CurrentFileName,
 TimeElapsed,
 TimeEstimated">
</telerik:RadProgressArea>
<asp:Button ID="Button1" runat="server" Text="Unzip selected file" />


You can modify the code and integrate it with the previous solution I sent.

Sincerely yours,
Ivan Dimitrov
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Andrew
Top achievements
Rank 1
answered on 13 Oct 2009, 02:38 PM
Hi

Thanks again for the quick reply.

I can also set the Localization properties in Page Load, but I need to do this in the button click event. I would like the text to be different during the file upload and during the unzipping, hence needing to do this in the button click event as per my earlier sample.

It's not a big deal if this isn't possible, as I'll just use more generic text such as "Processed:".

Thanks
Andy
0
Ivan Dimitrov
Telerik team
answered on 13 Oct 2009, 02:54 PM
Hi Andrew,

You can modify the button click event as below.

void Button1_Click(object sender, EventArgs e)
 {
     Telerik.Web.UI.RadProgressContext ProgressContex = Telerik.Web.UI.RadProgressContext.Current;
     ProgressContex.SecondaryTotal = "100";
     for (int i = 1; i < 100; i++)
     {
         foreach(UploadedFile file in RadUpload1.UploadedFiles)
         {
             string ext = file.GetExtension();
               if(ext == ".zip")
               {
                 RadProgressArea1.Localization.UploadedFiles = "Unzipping: ";
               }
               else
               {
                   RadProgressArea1.Localization.UploadedFiles = "Uploading: ";
               }
         ProgressContex.CurrentOperationText = "Uploading zip file percentage " + i.ToString();
         // FORCE STOP UPLOADING
         if (!Response.IsClientConnected)
         {
             break;
         }
         // SIMULATE TIME UPLOADING
         System.Threading.Thread.Sleep(100);
         }
     }
 }

you can use switch loop. Note that the page should be refreshed because on each upload the control generates RadUrid = "some guid here"

Regards,
Ivan Dimitrov
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Yusuf
Top achievements
Rank 1
answered on 21 Nov 2011, 10:07 AM
Hello Ivan

I need to do the same operation using Silverlight RADUpload control and RADUploadHandler. I need to first Extract Zip files and show within the RADUpload Listbox and only upload the extracted files rather than the zip file to the Server location. I am able to extract the files using the code given in this link but cannot add it to the RADUpload listboxitem control.
http://www.sharpgis.net/post/2009/04/22/REALLY-small-unzip-utility-for-Silverlight.aspx

Any help on this regards would be much appreciated.

Thanks & Regards
Yusuf Shabbir
0
Tina Stancheva
Telerik team
answered on 24 Nov 2011, 02:21 PM
Hello Yusuf,

Please have a look at this CodeLibrary solution and let us know if this is what you had in mind.

Regards,
Tina Stancheva
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

Tags
Upload
Asked by
Andrew
Top achievements
Rank 1
Answers by
Ivan Dimitrov
Telerik team
Andrew
Top achievements
Rank 1
Yusuf
Top achievements
Rank 1
Tina Stancheva
Telerik team
Share this question
or