using System; using System.Collections.Generic; using System.Configuration; using System.IO; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.ServiceModel.Web; using System.Text; using Tango.Core.Helpers; using Tango.BL.Entities; using Tango.Logging; using Tango.MachineStudio.Common.Update; using Tango.BL; using Tango.BL.Enumerations; namespace Tango.MachineStudio.UpdateService { public class MachineStudioUpdateService : IMachineStudioUpdateService { private LogManager LogManager = LogManager.Default; private class PendingUpload { public String Token { get; set; } public String Version { get; set; } public String UserGuid { get; set; } public String Comments { get; set; } public bool ForcedUpdate { get; set; } public String FilePath { get; set; } public bool IsStable { get; set; } } private static List _pendingUploads; static MachineStudioUpdateService() { _pendingUploads = new List(); } public CheckForUpdatesResponse CheckForUpdates(CheckForUpdatesRequest request) { LogManager.Log("Request received..."); try { CheckForUpdatesResponse response = new CheckForUpdatesResponse(); using (ObservablesContext db = ObservablesContext.CreateDefault(GetServerAddress())) { db.Configuration.LazyLoadingEnabled = false; //Load relation first... db.Roles.ToList(); db.Permissions.ToList(); db.UsersRoles.ToList(); db.RolesPermissions.ToList(); var user = db.Users.SingleOrDefault(x => x.Email.ToLower() == request.Email.ToLower() && x.Password == request.Password); if (user != null && user.HasPermission(Permissions.RunMachineStudio) || (request.Email == "ForceUpdate")) { var versions = db.MachineStudioVersions.ToList(); var latestVersion = versions.OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); Version currentVersion = Version.Parse(request.Version); bool isForcedUpdate = versions.Exists(x => x.ForceUpdate && Version.Parse(x.Version) > currentVersion); bool stable_condition = true; if (!request.AcceptBetaRelease && !latestVersion.Stable) { stable_condition = false; } String comments = String.Join(Environment.NewLine, versions.OrderBy(x => Version.Parse(x.Version)).Where(x => Version.Parse(x.Version) > currentVersion).Select(x => x.Comments)); if (latestVersion != null && Version.Parse(latestVersion.Version) > currentVersion) { if (stable_condition) { response.IsUpdateAvailable = true; response.FtpHost = ConfigurationManager.AppSettings["FtpHost"].ToString(); response.UserName = ConfigurationManager.AppSettings["UserName"].ToString(); response.Password = ConfigurationManager.AppSettings["Password"].ToString(); response.FilePath = latestVersion.FtpFilePath; response.Version = latestVersion.Version; response.Comments = latestVersion.Comments; response.ForcedUpdate = isForcedUpdate; response.IsStable = latestVersion.Stable; } } } else { throw new FaultException("Invalid user credentials."); } } return response; } catch (Exception ex) { LogManager.Log(ex); throw new FaultException(ex.ToString()); } } public UploadVersionResponse UploadVersion(UploadVersionRequest request) { try { UploadVersionResponse response = new UploadVersionResponse(); using (ObservablesContext db = ObservablesContext.CreateDefault(GetServerAddress())) { db.Configuration.LazyLoadingEnabled = false; //Load relation first... db.Roles.ToList(); db.Permissions.ToList(); db.UsersRoles.ToList(); db.RolesPermissions.ToList(); var user = db.Users.SingleOrDefault(x => x.Email.ToLower() == request.Email.ToLower() && x.Password == request.Password); if (user != null && user.HasPermission(Permissions.PublishMachineStudioVersion)) { var latestVersion = db.MachineStudioVersions.ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); Version currentVersion = Version.Parse(request.Version); String newVersionFileName = Path.GetRandomFileName() + ".zip"; String newVersionFilePath = "/machine studio versions/" + newVersionFileName; if (currentVersion > Version.Parse(latestVersion.Version)) { response.FtpHost = ConfigurationManager.AppSettings["FtpHost"].ToString(); response.UserName = ConfigurationManager.AppSettings["UserName"].ToString(); response.Password = ConfigurationManager.AppSettings["Password"].ToString(); response.FilePath = newVersionFilePath; response.FileName = newVersionFileName; response.Token = Guid.NewGuid().ToString(); _pendingUploads.Add(new PendingUpload() { UserGuid = user.Guid, Comments = request.Comments, ForcedUpdate = request.ForcedUpdate, Token = response.Token, Version = request.Version, FilePath = response.FilePath, IsStable = request.IsStable, }); } else { throw new FaultException("New version must be greater than latest version."); } } else { throw new FaultException("Invalid user credentials."); } } return response; } catch (Exception ex) { LogManager.Log(ex); throw new FaultException(ex.ToString()); } } public void NotifyUploadCompleted(UploadCompletedRequest request) { try { PendingUpload upload = _pendingUploads.FirstOrDefault(x => x.Token == request.Token); if (upload != null) { _pendingUploads.RemoveAll(x => x.Token == upload.Token); using (ObservablesContext db = ObservablesContext.CreateDefault(GetServerAddress())) { db.Configuration.LazyLoadingEnabled = false; db.MachineStudioVersions.Add(new MachineStudioVersion() { Comments = upload.Comments, FtpFilePath = upload.FilePath, UserGuid = upload.UserGuid, Version = upload.Version, ForceUpdate = upload.ForcedUpdate, Stable = upload.IsStable, }); db.SaveChanges(); } } else { throw new FaultException("Invalid Token."); } } catch (Exception ex) { LogManager.Log(ex); throw new FaultException(ex.ToString()); } } public string GetLatestVersion() { try { using (ObservablesContext db = ObservablesContext.CreateDefault(GetServerAddress())) { return db.MachineStudioVersions.ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault().Version; } } catch (Exception ex) { throw new FaultException(ex.ToString()); } } private String GetServerAddress() { return ConfigurationManager.AppSettings["ServerAddress"].ToString(); } } }