private static void UploadTaskCallback(UploadTask task) { try { if (task.Stream != null) { task.Stream.Close(); } OnUploadTaskDone(task); // Invoke 'OnUploadedVersion' on the viewmodel // This should maybe be done nicer, interface? Session.ScheduleTask(task.SessionId, (Session session, String sessionId) => { if (sessionId == task.SessionId) { if (session.Data is WarehouseMainPage) { if (((WarehouseMainPage)session.Data).Partial is ApplicationPage) { ApplicationPage page = ((WarehouseMainPage)session.Data).Partial as ApplicationPage; page.OnUploadedVersion(task.UploadFileName, task.Version); session.CalculatePatchAndPushOnWebSocket(); } else if (((WarehouseMainPage)session.Data).Partial is UploadVersionsPage) { UploadVersionsPage page = ((WarehouseMainPage)session.Data).Partial as UploadVersionsPage; page.OnUploadedVersion(task.UploadFileName, task.Version); session.CalculatePatchAndPushOnWebSocket(); } } } }); } catch (Exception e) { string message = e.Message; try { if (File.Exists(task.TempFilename)) { File.Delete(task.TempFilename); } } catch (Exception) { message += ". Failed to cleanup temp file"; } // Invoke 'OnInvalidUploadVersion' on the viewmodel // This should maybe be done nicer, interface? Session.ScheduleTask(task.SessionId, (Session session, String sessionId) => { if (sessionId == task.SessionId) { if (session.Data is WarehouseMainPage) { if (((WarehouseMainPage)session.Data).Partial is ApplicationPage) { ApplicationPage page = ((WarehouseMainPage)session.Data).Partial as ApplicationPage; page.OnInvalidUploadVersion(task.UploadFileName, message); session.CalculatePatchAndPushOnWebSocket(); } else if (((WarehouseMainPage)session.Data).Partial is UploadVersionsPage) { UploadVersionsPage page = ((WarehouseMainPage)session.Data).Partial as UploadVersionsPage; page.OnInvalidUploadVersion(task.UploadFileName, message); session.CalculatePatchAndPushOnWebSocket(); } } } }); } }
/// <summary> /// /// </summary> /// <param name="task"></param> private static void OnUploadTaskDone(UploadTask task) { string file = null; PackageManager.VerifyPacket(task.TempFilename); PackageConfigFile config; PackageManager.ReadConfiguration(task.TempFilename, out config); // Get Resource object IObjectView obj = DbHelper.FromID(DbHelper.Base64DecodeObjectID(task.ResourceId)); Organization organization = null; Software software = null; if (obj is App) { software = (Software)obj; organization = software.Organization; if (!string.Equals(config.Namespace, software.Namespace, StringComparison.InvariantCultureIgnoreCase)) { throw new InvalidOperationException(string.Format("Uploaded version namespace ({0}) does not match application namespace ({1}).", config.Namespace, software.Namespace)); } } else if (obj is Organization) { organization = obj as Organization; } if (organization == null) { throw new InvalidOperationException("Upload on a non organization resource"); } try { // Move and name the temp file to it's correct place file = MoveUploadedFile(task.TempFilename, organization, config.Namespace, config.Channel, config.Version); Db.Transact(() => { // Find software software = Db.SQL<Software>("SELECT o FROM Warehouse.Software o WHERE o.Organization=? AND o.Namespace=?", organization, config.Namespace).First; if (software == null) { // Auto-create application software = CreateApplication(config, organization, task.SessionId); } else { // Check if Version already exists. Version duplicatedVersion = Db.SQL<Version>("SELECT o FROM Warehouse.Version o WHERE o.Software=? AND o.Name=? AND o.Channel=?", software, config.Version, config.Channel).First; if (duplicatedVersion != null) { throw new InvalidOperationException("Version already exist"); } } Settings settings = Settings.GetSettings(); if (settings == null) { throw new InvalidOperationException("Warehouse has not be configured, Visit the settings page."); } string folder = Path.Combine(settings.PublicFolder, "warehouse"); folder = Path.Combine(folder, "images"); UnpackAppStoreMetadata(software, file, config, folder); // Create version database instance Version version = new Version(); version.ID = string.Format("{0:X8}", (software.ID + config.Channel + config.VersionDate).GetHashCode()); version.Name = config.Version; version.Software = software; version.BinaryFile = file; version.VersionDate = config.VersionDate; version.Channel = config.Channel; // Add AppVersion Dependencies if (config.Dependencies != null) { foreach (Dependency dependency in config.Dependencies) { if (String.Equals("Starcounter", dependency.Name, StringComparison.InvariantCultureIgnoreCase)) { version.Compatiblility = dependency.Value; break; } // dependency.Name; // "Starcounter" // dependency.Value; // "~2.1.284" } } task.Version = version; // Update task }); // Push changed to viewmodel Session.ScheduleTask(task.SessionId, (Session session, String sessionId) => { if (session != null && session.IsAlive()) { session.CalculatePatchAndPushOnWebSocket(); } }); } catch (Exception) { if (file != null) { if (File.Exists(file)) { File.Delete(file); } DirectoryInfo di = Directory.GetParent(file); if (Utils.IsDirectoryEmpty(di.FullName)) { Directory.Delete(di.FullName); } } throw; } }
/// <summary> /// Create upload task /// </summary> /// <param name="sessionId"></param> /// <param name="fileName"></param> /// <param name="fileSize"></param> /// <param name="resourceId">Object id where the upload should be related to</param> /// <returns></returns> private static UploadTask CreateUploadTask(string sessionId, string fileName, int fileSize, string resourceId) { string tempFileName = GenerateUploadTempFileName(); var fs = new FileStream(tempFileName, FileMode.Append); UploadTask ut = new UploadTask() { SessionId = sessionId, Stream = fs, FileSize = fileSize, UploadFileName = fileName, ResourceId = resourceId }; ut.DoneCallback = UploadTaskCallback; return ut; }