コード例 #1
0
 protected void DownloadOnClick(Object source, CommandEventArgs args)
 {
     if (fileStore != null)
     {
         ListItem item = list.SelectedItem;
         if (item != null)
         {
             ICentralizedFile file = fileStore.GetFile("", item.Value);
             if (file != null)
             {
                 HttpResponse response = HttpContext.Current.Response;
                 response.ClearContent();
                 response.AddHeader("Content-Disposition", "attachment; filename=" + file.FileName);
                 response.AddHeader("Content-Length", file.ContentLength.ToString());
                 response.ContentType = "text/plain";
                 using (Stream readStream = file.OpenReadStream())
                 {
                     byte[] buffer = new byte[4096];
                     int    bytesRead;
                     while ((bytesRead = readStream.Read(buffer, 0, buffer.Length)) > 0)
                     {
                         response.BinaryWrite(buffer);
                     }
                 }
                 HttpContext.Current.ApplicationInstance.CompleteRequest();
             }
         }
     }
 }
コード例 #2
0
        private void UploadToApplication(HttpContextBase context, HttpPostedFileBase uploadedFile, string jsonId, int defaultHeight, int defaultWidth, StringBuilder returnString)
        {
            string contextId = context.Request.QueryString["uploaderId"] ?? string.Empty;

            if (string.IsNullOrEmpty(contextId))
            {
                throw new Exception("No file was received.");
            }

            string fname = Path.GetFileName(uploadedFile.FileName);

            ICentralizedFile uploadedCfsFile = null;

            var fm = new Telligent.Evolution.Components.MultipleUploadFileManager();

            fm.AddFile(fname, uploadedFile.InputStream, contextId);

            uploadedCfsFile = fm.GetCfsFile(fname, contextId);

            if (uploadedCfsFile != null)
            {
                string resizedHtml = PublicApi.UI.GetResizedImageHtml(CentralizedFileStorage.GetGenericDownloadUrl(uploadedCfsFile), defaultWidth, defaultHeight, new UiGetResizedImageHtmlOptions());

                returnString.Append(string.Concat("{\"" + jsonId + "\":\"", PublicApi.Javascript.Encode(uploadedCfsFile.GetDownloadUrl()), "\",\"resizedMarkup\":\"", PublicApi.Javascript.Encode(resizedHtml), "\",\"filename\":\"" + fname + "\"}"));
            }
        }
コード例 #3
0
ファイル: AppDataService.cs プロジェクト: Vivalldi/Mobile-SDK
        public AppData Get(ICentralizedFile sourceFile)
        {
            if (sourceFile == null)
            {
                return(null);
            }

            string  cacheKey = GetCacheKey(sourceFile);
            AppData appData  = (AppData)Telligent.Evolution.Extensibility.Caching.Version1.CacheService.Get(cacheKey, Extensibility.Caching.Version1.CacheScope.Context | Extensibility.Caching.Version1.CacheScope.Process);

            if (appData == null)
            {
                var targetFileStore = CentralizedFileStorage.GetFileStore(CentralizedFileStorage.HasAccessValidator(sourceFile.FileStoreKey) ? AppConstants.SecureAppDataFileStoreKey : AppConstants.AppDataFileStoreKey);
                if (targetFileStore == null)
                {
                    return(null);
                }

                string appPath = CentralizedFileStorage.MakePath(sourceFile.FileStoreKey, sourceFile.Path, sourceFile.FileName.Replace(CentralizedFileStorage.DirectorySeparator.ToString(), ""));

                appData = GetOrExtractAppData(sourceFile, targetFileStore, appPath);

                Telligent.Evolution.Extensibility.Caching.Version1.CacheService.Put(cacheKey, appData, Extensibility.Caching.Version1.CacheScope.Context | Extensibility.Caching.Version1.CacheScope.Process, new string[] { GetTag() });
            }

            return(appData);
        }
コード例 #4
0
   public ICentralizedFile AddUpdateFile(string path, string fileName, Stream contentStream)
   {
       if (!CentralizedFileStorage.IsValid(this.FileStoreKey, path, fileName))
           throw this.CreateFilePathInvalidException(path, fileName);
       bool processEvents = EventExecutor != null && fileName != FileSystemFileStorageProvider.PLACE_HOLDER_FILENAME;
       ICentralizedFile originalFile = (ICentralizedFile)null;
       if (processEvents)
       {
           originalFile = GetFile(path, fileName);
           if (originalFile != null)
               EventExecutor.OnBeforeUpdate(originalFile);
           else
               EventExecutor.OnBeforeCreate(FileStoreKey, path, fileName);
       }
       this.GetConnection().Put(this._bucketName, this.MakeKey(path, fileName), new SortedList<string, string>(), contentStream, new SortedList<string, string>()
 {
   {
     "Content-Type",
     MimeTypeConfiguration.GetMimeType(fileName)
   }
 });
       this.RemoveAmazonS3PathQueryResultsAndAmazonS3FileStorageFileFromCache(path, fileName);
       var file = GetFile(path, fileName);
       if (processEvents)
       {
           if (originalFile != null)
               EventExecutor.OnAfterUpdate(file);
           else
               EventExecutor.OnAfterCreate(file);
       }
       return file;
   }
        private string GetFilestoreCssPath()
        {
            ICentralizedFile file = InlineContentStore.GetFile("css", "inlinecontent.css");

            if (file == null)
            {
                using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(Css)))
                {
                    file = InlineContentStore.AddUpdateFile("css", "inlinecontent.css", stream);
                }
            }

            return(file.GetDownloadUrl());
        }
コード例 #6
0
        public string GetFilestoreCssPath()
        {
            ICentralizedFile file = EmoticonStore.GetFile("css", "emoticons.css");

            if (file == null)
            {
                using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(_cssToRender)))
                {
                    file = EmoticonStore.AddUpdateFile("css", "emoticons.css", stream);
                }
            }

            return(file.GetDownloadUrl());
        }
コード例 #7
0
        protected void Delete(Object source, CommandEventArgs args)
        {
            ListItem item = list.SelectedItem;

            if (item != null)
            {
                String           fname = item.Value;
                ICentralizedFile file  = fileStore.GetFile("", fname);
                if (file != null)
                {
                    fileStore.Delete("", fname);
                    ListDataBind();
                }
            }
        }
コード例 #8
0
        public ICentralizedFile AddUpdateFile(string path, string fileName, System.IO.Stream contentStream)
        {
            if (!CentralizedFileStorage.IsValid(this.FileStoreKey, path, fileName))
            {
                throw new ApplicationException("The provided path and/or file name is invalid");
            }

            bool             processEvents = EventExecutor != null && fileName != FileSystemFileStorageProvider.PLACE_HOLDER_FILENAME;
            ICentralizedFile originalFile  = null;

            if (processEvents)
            {
                originalFile = GetFile(path, fileName);
                if (originalFile != null)
                {
                    EventExecutor.OnBeforeUpdate(originalFile);
                }
                else
                {
                    EventExecutor.OnBeforeCreate(FileStoreKey, path, fileName);
                }
            }

            SortedList headers = new SortedList();

            headers.Add("Content-Type", Telligent.Evolution.Configuration.MimeTypeConfiguration.GetMimeType(fileName));

            GetConnection().Put(this._bucketName, MakeKey(path, fileName), new SortedList(), contentStream, headers);

            this.RemoveAmazonS3PathQueryResultsAndAmazonS3FileStorageFileFromCache(path, fileName);

            var file = GetFile(path, fileName);

            if (processEvents)
            {
                if (originalFile != null)
                {
                    EventExecutor.OnAfterUpdate(file);
                }
                else
                {
                    EventExecutor.OnAfterCreate(file);
                }
            }

            return(file);
        }
        public string UpdateInlineContentFiles(string sourceContent)
        {
            var fs = CentralizedFileStorage.GetFileStore(InlineContentLogic.FILESTORE_KEY);

            return(_ftController.SaveFilesInHtml(sourceContent, file =>
            {
                using (Stream contentStream = file.OpenReadStream())
                {
                    ICentralizedFile centralizedFile = fs.AddFile(file.Path, file.FileName, contentStream, true);
                    if (centralizedFile != null)
                    {
                        return centralizedFile;
                    }

                    _ftController.InvalidFile(file, string.Empty);
                }
                return (ICentralizedFile)null;
            }));
        }
コード例 #10
0
        private MetaData GetCurrentMetaData(ContentDetails details)
        {
            string cacheKey = GetCacheKey(details.FileName);

            MetaData result = CacheService.Get(cacheKey, CacheScope.All) as MetaData;

            if (result == null && MetaDataStore != null)
            {
                ICentralizedFile file = MetaDataStore.GetFile("", details.FileName + ".xml");

                if (file != null)
                {
                    using (Stream stream = file.OpenReadStream())
                    {
                        result = ((MetaData)_metaDataSerializer.Deserialize(stream));

                        //FIlter out any tags that have oreviously been configured but then removed
                        var lookup = _metaConfig.ExtendedEntries.ToLookup(f => f);

                        foreach (var tag in result.ExtendedMetaTags.Keys)
                        {
                            if (!lookup.Contains(tag))
                            {
                                result.ExtendedMetaTags.Remove(tag);
                            }
                        }
                    }
                }

                if (result == null)
                {
                    result = new MetaData()
                    {
                        InheritData = true, ContainerId = details.ContainerId.GetValueOrDefault(Guid.Empty), ContainerTypeId = details.ContainerTypeId.GetValueOrDefault(Guid.Empty)
                    };
                }

                CacheService.Put(cacheKey, result, CacheScope.All);
            }

            return(result);
        }
コード例 #11
0
        public BundleCfsFile(string type, string uri, ContentFragmentPageControl contentFragmentPage, string additionalId)
        {
            try
            {
                ICentralizedFile file = CentralizedFileStorage.GetCentralizedFileByUrl(uri.Replace("cfs-filesystemfile.ashx", "cfs-file.ashx"));

                if (file != null)
                {
                    LocalPath   = EnsureLocalCopyExists(file, string.Format("{0}-{1}-{2}-{3}", contentFragmentPage.ThemeName, contentFragmentPage.ThemeContextId, additionalId, file.FileName));
                    Type        = type;
                    OrignalUri  = uri;
                    RelativeUri = ResolveVirtual(LocalPath);
                    IsValid     = true;
                }
            }
            catch (Exception ex)
            {
                new CSException(CSExceptionType.UnknownError, "Failed to build remote file lookup", ex).Log();
            }
        }
コード例 #12
0
        protected string EnsureLocalCopyExists(ICentralizedFile file, string replacementFileName)
        {
            string localFsPath = LocalPerformanceCachePath();

            string localFileName = Path.Combine(localFsPath, replacementFileName);

            using (FileStream localFile = File.Open(localFileName, FileMode.Create, FileAccess.Write))
            {
                using (Stream readStream = file.OpenReadStream())
                {
                    Byte[] buffer = new Byte[readStream.Length];

                    readStream.Read(buffer, 0, (int)readStream.Length);

                    localFile.Write(buffer, 0, buffer.Length);
                }
            }

            return localFileName;
        }
コード例 #13
0
        protected string EnsureLocalCopyExists(ICentralizedFile file, string replacementFileName)
        {
            string localFsPath = LocalPerformanceCachePath();

            string localFileName = Path.Combine(localFsPath, replacementFileName);

            using (FileStream localFile = File.Open(localFileName, FileMode.Create, FileAccess.Write))
            {
                using (Stream readStream = file.OpenReadStream())
                {
                    Byte[] buffer = new Byte[readStream.Length];

                    readStream.Read(buffer, 0, (int)readStream.Length);

                    localFile.Write(buffer, 0, buffer.Length);
                }
            }

            return(localFileName);
        }
        public InlineContentData GetInlineContent(string contentName)
        {
            contentName = MakeSafeFileName(contentName);

            string            cacheKey = GetCacheKey(contentName);
            InlineContentData result   = CacheService.Get(cacheKey, CacheScope.All) as InlineContentData;

            if (result == null && InlineContentStore != null)
            {
                ICentralizedFile file = InlineContentStore.GetFile("", contentName + ".xml");

                if (file != null)
                {
                    using (Stream stream = file.OpenReadStream())
                    {
                        result = ((InlineContentData)_inlineContentSerializer.Deserialize(stream));

                        CacheService.Put(cacheKey, result, CacheScope.All);
                    }
                }
            }
            return(result);
        }
コード例 #15
0
        private void UpsertSourceMap(string fileName, string fileStoreKey, string path)
        {
            const string propertyName = Constants.ThemeStylesheetFiles;

            // Test if modified file is a stylesheet
            if (fileName.EndsWith(".css") && fileStoreKey == Constants.ThemeFiles && path.EndsWith(propertyName))
            {
                ICentralizedFileStorageProvider fileStore = CentralizedFileStorage.GetFileStore(fileStoreKey);
                string mapName = string.Concat(fileName, ".map");

                if (fileStore != null)
                {
                    ICentralizedFile mapFile = fileStore.GetFile(path, mapName);

                    // Check if source map exists
                    if (mapFile != null)
                    {
                        string writePath = GetSanitisedPath(_siteThemeTypeId, _themeContextId, _siteThemeName,
                                                            propertyName, new Uri(Globals.FullPath("~/")));

                        if (CentralizedFileStorage.GetFileStore(Constants.ThemeFiles).GetFile(writePath, mapName) == null)
                        {
                            lock (_lock)
                            {
                                if (CentralizedFileStorage.GetFileStore(Constants.ThemeFiles).GetFile(writePath, mapName) ==
                                    null)
                                {
                                    using (DistributedMonitor distributedMonitor = new DistributedMonitor())
                                    {
                                        const int limit = 5;

                                        for (int i = 0; i < limit; i++)
                                        {
                                            using (
                                                DistributedLock distributedLock =
                                                    distributedMonitor.Enter(Constants.DistributedMonitorKey))
                                            {
                                                if (distributedLock.IsOwner)
                                                {
                                                    if (
                                                        CentralizedFileStorage.GetFileStore(Constants.ThemeFiles)
                                                        .GetFile(writePath, mapName) ==
                                                        null)
                                                    {
                                                        byte[] array;

                                                        using (Stream stream = mapFile.OpenReadStream())
                                                        {
                                                            array = new byte[stream.Length];
                                                            stream.Read(array, 0, array.Length);
                                                            stream.Close();
                                                        }

                                                        string text = Encoding.UTF8.GetString(array);

                                                        // Modify paths
                                                        text = text.Replace("../",
                                                                            string.Format("{0}/cfs-file/__key/themefiles/s-fd-{1}-",
                                                                                          CSContext.Current.ApplicationPath, _siteThemeName));
                                                        array = Encoding.UTF8.GetBytes(text);
                                                        CentralizedFileStorage.GetFileStore(Constants.ThemeFiles)
                                                        .AddUpdateFile(writePath, mapName, new MemoryStream(array));
                                                    }
                                                    break;
                                                }
                                                distributedMonitor.Wait(distributedLock, 5);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
コード例 #16
0
ファイル: AppDataService.cs プロジェクト: Vivalldi/Mobile-SDK
        private AppData GetOrExtractAppData(ICentralizedFile sourceFile, ICentralizedFileStorageProvider targetFileStore, string targetPath)
        {
            var appDataFile = targetFileStore.GetFile(targetPath, "appdata");

            if (appDataFile != null)
            {
                using (Stream appDataStream = appDataFile.OpenReadStream())
                {
                    byte[] data = new byte[appDataStream.Length];
                    appDataStream.Read(data, 0, data.Length);
                    var qs = System.Web.HttpUtility.ParseQueryString(Encoding.UTF8.GetString(data));

                    return(new AppData {
                        Name = qs["name"] ?? sourceFile.FileName,
                        ApplicationId = qs["appid"] ?? string.Empty,
                        Image = string.IsNullOrEmpty(qs["image"]) ? null : targetFileStore.GetFile(targetPath, qs["image"]),
                        IsDirectlyInstallable = string.IsNullOrEmpty(qs["installable"]) || qs["installable"] == "true",
                        AppType = (AppType)Enum.Parse(typeof(AppType), qs["apptype"] ?? "Unknown", true),
                        File = sourceFile
                    });
                }
            }

            AppData appData = new AppData();

            appData.File    = sourceFile;
            appData.AppType = AppType.Unknown;
            appData.IsDirectlyInstallable = false;

            using (var inStream = sourceFile.OpenReadStream())
            {
                using (var archive = new ZipArchive(inStream, ZipArchiveMode.Read, false))
                {
                    var imageEntry = GetImageEntry(archive, ImageSearchPaths);
                    if (imageEntry != null)
                    {
                        using (var imageStream = imageEntry.Open())
                        {
                            byte[] data = new byte[imageEntry.Length];
                            imageStream.Read(data, 0, data.Length);
                            using (var tempStream = new MemoryStream(data))
                            {
                                tempStream.Seek(0, SeekOrigin.Begin);
                                appData.Image = targetFileStore.AddUpdateFile(targetPath, "icon.png", tempStream);
                            }
                        }
                    }

                    if (string.Compare(Path.GetExtension(sourceFile.FileName), ".apk", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        appData.AppType = AppType.Android;
                        appData.IsDirectlyInstallable = true;
                    }
                    else if (string.Compare(Path.GetExtension(sourceFile.FileName), ".ipa", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        appData.AppType = AppType.iOS;
                        appData.IsDirectlyInstallable = false;

                        var iTunesEntry = archive.GetEntry(@"iTunesMetadata.plist");
                        if (iTunesEntry != null)
                        {
                            using (var iTunesStream = iTunesEntry.Open())
                            {
                                byte[] data = new byte[iTunesEntry.Length];
                                iTunesStream.Read(data, 0, data.Length);
                                using (var tempStream = new MemoryStream(data))
                                {
                                    tempStream.Seek(0, SeekOrigin.Begin);

                                    var    iTunesData = (Dictionary <string, object>)PlistCS.Plist.readPlist(tempStream, PlistCS.plistType.Auto);
                                    object d;
                                    if (iTunesData.TryGetValue("softwareVersionBundleId", out d))
                                    {
                                        appData.ApplicationId = d.ToString();
                                    }

                                    if (iTunesData.TryGetValue("playlistName", out d))
                                    {
                                        appData.Name = d.ToString();
                                    }
                                }
                            }
                        }
                        else
                        {
                            // this is not packaged for iTunes, check the Payload for developer/enterprise-deployment details
                            foreach (var entry in archive.Entries.Where(x => x.FullName.StartsWith(@"Payload/", StringComparison.OrdinalIgnoreCase) && x.FullName.EndsWith(@"/Info.plist", StringComparison.OrdinalIgnoreCase)))
                            {
                                var appFolder = entry.FullName.Substring(8, entry.FullName.Length - 19);
                                if (!appFolder.Contains(@"/"))
                                {
                                    using (var plistStream = entry.Open())
                                    {
                                        byte[] data = new byte[entry.Length];
                                        plistStream.Read(data, 0, data.Length);
                                        using (var tempStream = new MemoryStream(data))
                                        {
                                            tempStream.Seek(0, SeekOrigin.Begin);

                                            var    plistData = (Dictionary <string, object>)PlistCS.Plist.readPlist(tempStream, PlistCS.plistType.Auto);
                                            object d;
                                            if (plistData.TryGetValue("CFBundleIdentifier", out d))
                                            {
                                                appData.ApplicationId = d.ToString();
                                            }

                                            if (plistData.TryGetValue("CFBundleName", out d))
                                            {
                                                appData.Name = d.ToString();
                                            }
                                        }
                                    }

                                    imageEntry = GetImageEntry(archive, new string[] {
                                        string.Concat(@"Payload/", appFolder, @"/icon-320.png"),
                                        string.Concat(@"Payload/", appFolder, @"/[email protected]"),
                                        string.Concat(@"Payload/", appFolder, @"/[email protected]"),
                                        string.Concat(@"Payload/", appFolder, @"/[email protected]"),
                                        string.Concat(@"Payload/", appFolder, @"/[email protected]"),
                                        string.Concat(@"Payload/", appFolder, @"/icon.png")
                                    });

                                    if (imageEntry != null)
                                    {
                                        using (var imageStream = imageEntry.Open())
                                        {
                                            byte[] data = new byte[imageEntry.Length];
                                            imageStream.Read(data, 0, data.Length);
                                            using (var tempStream = new MemoryStream(data))
                                            {
                                                tempStream.Seek(0, SeekOrigin.Begin);
                                                using (var uncrushedStream = new MemoryStream())
                                                {
                                                    PNGDecrush.PNGDecrusher.Decrush(tempStream, uncrushedStream);
                                                    uncrushedStream.Seek(0, SeekOrigin.Begin);
                                                    appData.Image = targetFileStore.AddUpdateFile(targetPath, "icon.png", uncrushedStream);
                                                }
                                            }
                                        }
                                    }

                                    var provisionEntry = archive.GetEntry(string.Concat(@"Payload/", appFolder, @"/embedded.mobileprovision"));
                                    if (provisionEntry != null)
                                    {
                                        appData.IsDirectlyInstallable = true;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (string.IsNullOrEmpty(appData.Name))
            {
                appData.Name = sourceFile.FileName.Substring(0, sourceFile.FileName.LastIndexOf('.'));
            }

            if (appData.ApplicationId == null)
            {
                appData.ApplicationId = "";
            }

            StringBuilder qstr = new StringBuilder();

            qstr.Append("name=");
            qstr.Append(Uri.EscapeDataString(appData.Name));
            qstr.Append("&appid=");
            qstr.Append(Uri.EscapeDataString(appData.ApplicationId));
            qstr.Append("&image=");
            qstr.Append(appData.Image == null ? "" : Uri.EscapeDataString(appData.Image.FileName));
            qstr.Append("&installable=");
            qstr.Append(appData.IsDirectlyInstallable ? "true" : "false");
            qstr.Append("&apptype=");
            qstr.Append(Uri.EscapeDataString(appData.AppType.ToString()));

            using (var appDataStream = new MemoryStream(Encoding.UTF8.GetBytes(qstr.ToString())))
            {
                appDataStream.Seek(0, SeekOrigin.Begin);
                targetFileStore.AddUpdateFile(targetPath, "appdata", appDataStream);
            }

            return(appData);
        }
コード例 #17
0
ファイル: AppDataService.cs プロジェクト: Vivalldi/Mobile-SDK
 private string GetCacheKey(ICentralizedFile sourceFile)
 {
     return(string.Concat("AppData_PK:", sourceFile.FileStoreKey, ":", sourceFile.Path, ":", sourceFile.FileName));
 }
 public FileViewerMediaType GetMediaType(ICentralizedFile file, IFileViewerOptions options)
 {
     throw new FileViewerNotSupportedException();
 }
 public FileViewerMediaType GetMediaType(ICentralizedFile file, IFileViewerOptions options)
 {
     return FileViewerMediaType.Empty;
 }
 public string Render(ICentralizedFile file, IFileViewerOptions options)
 {
     return string.Empty;
 }
コード例 #21
0
 public FileViewerMediaType GetMediaType(ICentralizedFile file, IFileViewerOptions options)
 {
     return(FileViewerMediaType.Empty);
 }
コード例 #22
0
 public string Render(ICentralizedFile file, IFileViewerOptions options)
 {
     return(string.Empty);
 }
 public string Render(ICentralizedFile file, IFileViewerOptions options)
 {
     throw new FileViewerNotSupportedException();
 }
コード例 #24
0
        public string Render(ICentralizedFile file, IFileViewerOptions options)
        {
            var appData = Telligent.Evolution.Mobile.ServiceLocator.Get <Telligent.Evolution.Mobile.App.Services.IAppDataService>().Get(file);

            if (appData == null || appData.Image == null)
            {
                throw new FileViewerNotSupportedException();
            }

            if (options.ViewType == FileViewerViewType.Preview)
            {
                return(Telligent.Evolution.Extensibility.Api.Version1.PublicApi.UI.GetResizedImageHtml(CentralizedFileStorage.GetGenericDownloadUrl(appData.Image), options.Width.HasValue ? options.Width.Value : 0, options.Height.HasValue ? options.Height.Value : 0, new UiGetResizedImageHtmlOptions {
                    ResizeMethod = "ZoomAndCrop", OutputIsPersisted = options.OutputIsPersisted
                }));
            }
            else
            {
                StringBuilder html       = new StringBuilder();
                string        installUrl = null;

                var installer = PluginManager.Get <AppInstaller>().FirstOrDefault();
                if (installer != null)
                {
                    installUrl = installer.FormatInstallationUrl(appData);
                }

                if (!string.IsNullOrEmpty(installUrl))
                {
                    html.Append("<a href=\"");
                    html.Append(PublicApi.Html.Encode(installUrl));
                    html.Append("\" style=\"display:inline-block; background-color: #f3f3f3; color: #555; text-align: center; text-decoration: none; padding: 2px; border-radius: 10px;\" class=\"app-viewer with-install\">");
                }
                else
                {
                    html.Append("<span class=\"app-view without-install\">");
                }

                html.Append(Telligent.Evolution.Extensibility.Api.Version1.PublicApi.UI.GetResizedImageHtml(CentralizedFileStorage.GetGenericDownloadUrl(appData.Image), options.Width.HasValue ? options.Width.Value : 0, options.Height.HasValue ? options.Height.Value : 0, new UiGetResizedImageHtmlOptions
                {
                    ResizeMethod      = "ScaleDown",
                    OutputIsPersisted = options.OutputIsPersisted,
                    HtmlAttributes    = new Dictionary <string, string>
                    {
                        { "style", "border-radius: 10px; display: inline-block;" }
                    }
                }));

                if (!string.IsNullOrEmpty(installUrl))
                {
                    html.Append("<div style=\"padding: 8px;\">");

                    if (appData.IsDirectlyInstallable)
                    {
                        html.Append(_translation.GetLanguageResourceValue("ota_install"));
                    }
                    else
                    {
                        html.Append(_translation.GetLanguageResourceValue("itunes_install"));
                    }

                    html.Append("</div></a>");
                }
                else
                {
                    html.Append("</span>");
                }

                return(html.ToString());
            }
        }