From 2e35a3c27a8078ca222eafb5eb2c646f27122ed5 Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Sat, 26 Jan 2013 00:19:33 -0500 Subject: [PATCH 1/9] Added tag build-2.1.0.30 for changeset 389e019d489f From 815519b6500fac343824a6ac6648743089bc9a34 Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Sat, 26 Jan 2013 01:27:33 -0500 Subject: [PATCH 2/9] Added tag build-2.1.0.31 for changeset 086cab9e0045 From a2c0a6b6eb6e10d8b131dd7fb72fa8b4f8e257cf Mon Sep 17 00:00:00 2001 From: Christopher York Date: Tue, 29 Jan 2013 12:02:08 -0600 Subject: [PATCH 3/9] Fixed: Using incorrect table name format for addons Changed: Addons no longer store the Enterprise Server credentials Fixed: Error codes not resolving to the correct response text --- .../includes/hooks/websitepanel_addons.php | 12 +++--- .../includes/hooks/websitepanel_sync.php | 6 ++- .../websitepanel_addons.php | 42 +++++++++++++------ .../websitepanel_sync/websitepanel_sync.php | 24 +++++++++-- .../websitepanel/websitepanel.functions.php | 28 ++++++++++++- 5 files changed, 89 insertions(+), 23 deletions(-) diff --git a/WebsitePanel.WHMCSModule/includes/hooks/websitepanel_addons.php b/WebsitePanel.WHMCSModule/includes/hooks/websitepanel_addons.php index 5d628e81..52ddeef0 100644 --- a/WebsitePanel.WHMCSModule/includes/hooks/websitepanel_addons.php +++ b/WebsitePanel.WHMCSModule/includes/hooks/websitepanel_addons.php @@ -46,15 +46,17 @@ function websitepanel_addons_AddonActivation($params) { // Sanity check to make sure the associated service is WebsitePanel based product // And that the addon purchased has an associated WebsitePanel addon - $results = full_query("SELECT h.id AS `id` FROM `tblhosting` AS h, `tblwspaddons` AS w, `tblservers` AS s WHERE h.id = {$params['serviceid']} AND h.server = s.id AND s.type = 'websitepanel' AND w.whmcs_id = {$params['addonid']}"); + $results = full_query("SELECT h.id AS `id` FROM `tblhosting` AS h, `mod_wspaddons` AS w, `tblservers` AS s WHERE h.id = {$params['serviceid']} AND h.server = s.id AND s.type = 'websitepanel' AND w.whmcs_id = {$params['addonid']}"); if (mysql_num_rows($results) > 0) { // Include the WebsitePanel ES Class require_once(ROOTDIR . '/modules/servers/websitepanel/websitepanel.class.php'); + require_once(ROOTDIR . '/modules/servers/websitepanel/websitepanel.functions.php'); // Retrieve the WebsitePanel Addons module settings $modSettings = websitepanel_addons_GetSettings(); - if (empty($modSettings['username']) || empty($modSettings['password']) || empty($modSettings['serverhost']) || empty($modSettings['serverport'])) + $srvSettings = websitepanel_GetServerSettings(); + if (empty($modSettings['serverhost']) || empty($modSettings['serverport']) || empty($srvSettings['username']) || empty($srvSettings['password'])) { // The module is disabled or has not yet been configured - stop return; @@ -71,7 +73,7 @@ function websitepanel_addons_AddonActivation($params) } // Create the WebsitePanel object instance - $wsp = new WebsitePanel($modSettings['username'], $modSettings['password'], $modSettings['serverhost'], $modSettings['serverport'], (($modSettings['serversecured']) == 'on' ? TRUE : FALSE)); + $wsp = new WebsitePanel($srvSettings['username'], $srvSettings['password'], $modSettings['serverhost'], $modSettings['serverport'], (($modSettings['serversecured']) == 'on' ? TRUE : FALSE)); // Grab the user's details from WebsitePanel in order to get the user's id $user = $wsp->get_user_by_username($username); @@ -89,7 +91,7 @@ function websitepanel_addons_AddonActivation($params) } // Get the associated WebsitePanel addon id - $results = select_query('tblwspaddons', 'wsp_id,is_ipaddress', array('whmcs_id' => $params['addonid'])); + $results = select_query('mod_wspaddons', 'wsp_id,is_ipaddress', array('whmcs_id' => $params['addonid'])); $addon = mysql_fetch_array($results); $addonPlanId = $addon['wsp_id']; $addonIsIpAddress = $addon['is_ipaddress']; @@ -129,7 +131,7 @@ function websitepanel_addons_GetSettings() $results = select_query('tbladdonmodules', 'setting,value', array('module' => 'websitepanel_addons')); while (($row = mysql_fetch_array($results)) != false) { - $settings[$row['setting']] = $row['value']; + $settings[$row[0]] = $row[1]; } return $settings; } \ No newline at end of file diff --git a/WebsitePanel.WHMCSModule/includes/hooks/websitepanel_sync.php b/WebsitePanel.WHMCSModule/includes/hooks/websitepanel_sync.php index 46a7a10e..0de3f28d 100644 --- a/WebsitePanel.WHMCSModule/includes/hooks/websitepanel_sync.php +++ b/WebsitePanel.WHMCSModule/includes/hooks/websitepanel_sync.php @@ -50,17 +50,19 @@ function websitepanel_sync_ClientEdit($params) { // Include the WebsitePanel ES Class require_once(ROOTDIR . '/modules/servers/websitepanel/websitepanel.class.php'); + require_once(ROOTDIR . '/modules/servers/websitepanel/websitepanel.functions.php'); // Retrieve the WebsitePanel Addons module settings $modSettings = websitepanel_sync_GetSettings(); - if (empty($modSettings['username']) || empty($modSettings['password']) || empty($modSettings['serverhost']) || empty($modSettings['serverport'])) + $srvSettings = websitepanel_GetServerSettings(); + if (empty($modSettings['serverhost']) || empty($modSettings['serverport']) || empty($srvSettings['username']) || empty($srvSettings['password'])) { // The module is disabled or has not yet been configured - stop return; } // Create the WebsitePanel object instance - $wsp = new WebsitePanel($modSettings['username'], $modSettings['password'], $modSettings['serverhost'], $modSettings['serverport'], (($modSettings['serversecured']) == 'on' ? TRUE : FALSE)); + $wsp = new WebsitePanel($srvSettings['username'], $srvSettings['password'], $modSettings['serverhost'], $modSettings['serverport'], (($modSettings['serversecured']) == 'on' ? TRUE : FALSE)); // Get all WSP users with the old email $items = (array)$wsp->get_users_paged_recursive(1, 'Email', $params['olddata']['email'], 0, 0, ''); diff --git a/WebsitePanel.WHMCSModule/modules/addons/websitepanel_addons/websitepanel_addons.php b/WebsitePanel.WHMCSModule/modules/addons/websitepanel_addons/websitepanel_addons.php index 6bee05b3..13ce02bb 100644 --- a/WebsitePanel.WHMCSModule/modules/addons/websitepanel_addons/websitepanel_addons.php +++ b/WebsitePanel.WHMCSModule/modules/addons/websitepanel_addons/websitepanel_addons.php @@ -46,13 +46,11 @@ function websitepanel_addons_config() { $configarray = array('name' => 'WebsitePanel Addons Automation', 'description' => 'Automates WHMCS product addons with WebsitePanel', - 'version' => '1.0', + 'version' => '1.2', 'author' => 'Christopher York', 'fields' => array('serverhost' => array('FriendlyName', 'Enterprise Server Host', 'Type' => 'text', 'Size' => 25, 'Description' => 'Enterprise Server hostname / IP address', 'Default' => '127.0.0.1'), 'serverport' => array('FriendlyName', 'Enterprise Server Port', 'Type' => 'text', 'Size' => 4, 'Description' => 'Enterprise Server port', 'Default' => 9002), 'serversecured' => array('FriendlyName', 'Use Secured Connection', 'Type' => 'yesno', 'Description' => 'Tick to use SSL secured connection'), - 'username' => array('FriendlyName', 'Username', 'Type' => 'text', 'Size' => 25, 'Description' => 'Enterprise Server username', 'Default' => 'serveradmin'), - 'password' => array('FriendlyName', 'Password', 'Type' => 'password', 'Size' => 25, 'Description' => 'Enterprise Server password') ) ); return $configarray; @@ -67,7 +65,7 @@ function websitepanel_addons_config() function websitepanel_addons_activate() { // Create the WebsitePanel Addons table - $query = "CREATE TABLE `tblwspaddons` ( + $query = "CREATE TABLE `mod_wspaddons` ( `whmcs_id` int(11) NOT NULL, `wsp_id` int(11) NOT NULL, `is_ipaddress` bit(1) NOT NULL DEFAULT b'0', @@ -94,9 +92,8 @@ function websitepanel_addons_activate() */ function websitepanel_addons_deactivate() { - // Create the WebsitePanel Addons table - $query = 'DROP TABLE `tblwspaddons`'; - $result = full_query($query); + // Drop the WebsitePanel Addons table + $result = full_query('DROP TABLE `mod_wspaddons`'); // Check the results to verify that the table has been created properly if (!$result) @@ -109,6 +106,27 @@ function websitepanel_addons_deactivate() } } +/** + * websitepanel_addons_upgrade + * + * @param $vars array + * @access public + * @return array + */ +function websitepanel_addons_upgrade($vars) +{ + + $version = $vars['version']; + + // Adjust the table name and remove the WebsitePanel credentials + if ($version < 1.2) + { + full_query('RENAME TABLE `tblwspaddons` TO `mod_wspaddons`'); + full_query("DELETE FROM `tbladdonmodules` WHERE `module` = 'websitepanel_addons' AND `setting` = 'username'"); + full_query("DELETE FROM `tbladdonmodules` WHERE `module` = 'websitepanel_addons' AND `setting` = 'password'"); + } +} + /** * websitepanel_addons_output * @@ -120,24 +138,24 @@ function websitepanel_addons_output($params) // Delete the requested WebsitePanel addon if (isset($_GET['action']) && $_GET['action'] == 'delete') { - delete_query('tblwspaddons', array('whmcs_id' => $_GET['id'])); + delete_query('mod_wspaddons', array('whmcs_id' => $_GET['id'])); } // Add the requested WebsitePanel addon if ($_POST && isset($_POST['action']) && $_POST['action'] == 'add') { // Sanity check to make sure the WHMCS addon ID exists - $results = select_query('tbladdons', 'id', array('id' => $_POST['whmcs_id'])); + $results = select_query('mod_wspaddons', 'id', array('id' => $_POST['whmcs_id'])); if (mysql_num_rows($results) > 0) { - $results = select_query('tblwspaddons', 'whmcs_id', array('whmcs_id' => $_POST['whmcs_id'])); + $results = select_query('mod_wspaddons', 'whmcs_id', array('whmcs_id' => $_POST['whmcs_id'])); if (mysql_num_rows($results) > 0) { echo '

Duplicate WHMCS Addon ID. The WHMCS Addon ID Is Assigned To Another WebsitePanel Addon.

'; } else { - insert_query('tblwspaddons', array('whmcs_id' => $_POST['whmcs_id'], 'wsp_id' => $_POST['wsp_id'], 'is_ipaddress' => $_POST['is_ipaddress'])); + insert_query('mod_wspaddons', array('whmcs_id' => $_POST['whmcs_id'], 'wsp_id' => $_POST['wsp_id'], 'is_ipaddress' => $_POST['is_ipaddress'])); } } else @@ -147,7 +165,7 @@ function websitepanel_addons_output($params) } // Get all the assigned addons and display them to the user - $results = full_query('SELECT a.name AS `name`, a.id AS `whmcs_id`, w.wsp_id AS `wsp_id` FROM `tbladdons` AS a, `tblwspaddons` AS w WHERE w.whmcs_id = a.id'); + $results = full_query('SELECT a.name AS `name`, a.id AS `whmcs_id`, w.wsp_id AS `wsp_id` FROM `tbladdons` AS a, `mod_wspaddons` AS w WHERE w.whmcs_id = a.id'); // Build the table / data grid echo '
'; diff --git a/WebsitePanel.WHMCSModule/modules/addons/websitepanel_sync/websitepanel_sync.php b/WebsitePanel.WHMCSModule/modules/addons/websitepanel_sync/websitepanel_sync.php index 8822fa44..1db0d327 100644 --- a/WebsitePanel.WHMCSModule/modules/addons/websitepanel_sync/websitepanel_sync.php +++ b/WebsitePanel.WHMCSModule/modules/addons/websitepanel_sync/websitepanel_sync.php @@ -46,14 +46,32 @@ function websitepanel_sync_config() { $configarray = array('name' => 'WebsitePanel Sync Automation', 'description' => 'Syncs WHMCS client details / contact changes with WebsitePanel', - 'version' => '1.0', + 'version' => '1.2', 'author' => 'Christopher York', 'fields' => array('serverhost' => array('FriendlyName', 'Enterprise Server Host', 'Type' => 'text', 'Size' => 25, 'Description' => 'Enterprise Server hostname / IP address', 'Default' => '127.0.0.1'), 'serverport' => array('FriendlyName', 'Enterprise Server Port', 'Type' => 'text', 'Size' => 4, 'Description' => 'Enterprise Server port', 'Default' => 9002), 'serversecured' => array('FriendlyName', 'Use Secured Connection', 'Type' => 'yesno', 'Description' => 'Tick to use SSL secured connection'), - 'username' => array('FriendlyName', 'Username', 'Type' => 'text', 'Size' => 25, 'Description' => 'Enterprise Server username', 'Default' => 'serveradmin'), - 'password' => array('FriendlyName', 'Password', 'Type' => 'password', 'Size' => 25, 'Description' => 'Enterprise Server password') ) ); return $configarray; +} + +/** + * websitepanel_addons_upgrade + * + * @param $vars array + * @access public + * @return array + */ +function websitepanel_sync_upgrade($vars) +{ + + $version = $vars['version']; + + // Remove the WebsitePanel credentials + if ($version < 1.2) + { + full_query("DELETE FROM `tbladdonmodules` WHERE `module` = 'websitepanel_sync' AND `setting` = 'username'"); + full_query("DELETE FROM `tbladdonmodules` WHERE `module` = 'websitepanel_sync' AND `setting` = 'password'"); + } } \ No newline at end of file diff --git a/WebsitePanel.WHMCSModule/modules/servers/websitepanel/websitepanel.functions.php b/WebsitePanel.WHMCSModule/modules/servers/websitepanel/websitepanel.functions.php index 6305669a..2c73b195 100644 --- a/WebsitePanel.WHMCSModule/modules/servers/websitepanel/websitepanel.functions.php +++ b/WebsitePanel.WHMCSModule/modules/servers/websitepanel/websitepanel.functions.php @@ -45,8 +45,13 @@ */ function websitepanel_GetErrorMessage($code) { - global $esErrorCodes; + // Error codes + $esErrorCodes = array(); + // Include the common / known error codes + require_once(ROOTDIR . '/modules/servers/websitepanel/websitepanel.errorcodes.php'); + + // Check if the error code exists, if not return the code if (array_key_exists($code, $esErrorCodes)) { return $esErrorCodes[$code]; @@ -167,4 +172,25 @@ function websitepanel_CalculateUsage($result, $usageType) } } return $total; +} + +/** + * websitepanel_GetServerSettings + * + * @access public + * @return array + */ +function websitepanel_GetServerSettings() +{ + $settings = array('username' => '', 'password' => ''); + + // Retrieve the settings from the modules configuration table + $results = select_query('tblservers', 'username,password', array('type' => 'websitepanel')); + if (mysql_num_rows($results) != 0) + { + $row = mysql_fetch_array($results, MYSQL_ASSOC); + $settings['username'] = $row['username']; + $settings['password'] = decrypt($row['password']); + } + return $settings; } \ No newline at end of file From 880e35c6348dafe8a4178db0cb37b2406530a600 Mon Sep 17 00:00:00 2001 From: Christopher York Date: Tue, 29 Jan 2013 12:32:54 -0600 Subject: [PATCH 4/9] Fixed: WebsitePanel error codes not being converted properly --- .../websitepanel/websitepanel.errorcodes.php | 29 ++++++++++++------- .../websitepanel/websitepanel.functions.php | 1 + 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/WebsitePanel.WHMCSModule/modules/servers/websitepanel/websitepanel.errorcodes.php b/WebsitePanel.WHMCSModule/modules/servers/websitepanel/websitepanel.errorcodes.php index 8ce934d1..5bde4a57 100644 --- a/WebsitePanel.WHMCSModule/modules/servers/websitepanel/websitepanel.errorcodes.php +++ b/WebsitePanel.WHMCSModule/modules/servers/websitepanel/websitepanel.errorcodes.php @@ -39,15 +39,22 @@ /** * Common error codes encountered while using the WebsitePanel Server Module * These are not all the Enterprise Server error codes, only the ones I have encountered using the API + * + * @access public + * @return array */ -$esErrorCodes = array(-100 => 'User already exists', - -101 => 'User not found', - -102 => 'User has child user accounts', - -300 => 'Hosting package could not be found', - -301 => 'Hosting package has child hosting spaces', - -501 => 'The sub-domain belongs to an existing hosting space that does not allow sub-domains to be created', - -502 => 'The domain or sub-domain exists within another hosting space', - -511 => 'Instant alias is enabled, but not configured', - -601 => 'The website already exists on the target hosting space', - -700 => 'The email domain already exists on the target hosting space', - -1100 => 'User already exists'); \ No newline at end of file +function websitepanel_GetEnterpriseServerErrors() +{ + $esErrorCodes = array(-100 => 'User already exists', + -101 => 'User not found', + -102 => 'User has child user accounts', + -300 => 'Hosting package could not be found', + -301 => 'Hosting package has child hosting spaces', + -501 => 'The sub-domain belongs to an existing hosting space that does not allow sub-domains to be created', + -502 => 'The domain or sub-domain exists within another hosting space', + -511 => 'Instant alias is enabled, but not configured', + -601 => 'The website already exists on the target hosting space', + -700 => 'The email domain already exists on the target hosting space', + -1100 => 'User already exists'); + return $esErrorCodes; +} \ No newline at end of file diff --git a/WebsitePanel.WHMCSModule/modules/servers/websitepanel/websitepanel.functions.php b/WebsitePanel.WHMCSModule/modules/servers/websitepanel/websitepanel.functions.php index 2c73b195..b41b2ddc 100644 --- a/WebsitePanel.WHMCSModule/modules/servers/websitepanel/websitepanel.functions.php +++ b/WebsitePanel.WHMCSModule/modules/servers/websitepanel/websitepanel.functions.php @@ -50,6 +50,7 @@ function websitepanel_GetErrorMessage($code) // Include the common / known error codes require_once(ROOTDIR . '/modules/servers/websitepanel/websitepanel.errorcodes.php'); + $esErrorCodes = websitepanel_GetEnterpriseServerErrors(); // Check if the error code exists, if not return the code if (array_key_exists($code, $esErrorCodes)) From 6f54db6d2d1ab41b7b487114cc5905baaf58d68f Mon Sep 17 00:00:00 2001 From: Christopher York Date: Tue, 29 Jan 2013 12:33:51 -0600 Subject: [PATCH 5/9] Updated: Readme updated Added: Changelog file --- WebsitePanel.WHMCSModule/changelog.log | 3 +++ WebsitePanel.WHMCSModule/readme.txt | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 WebsitePanel.WHMCSModule/changelog.log diff --git a/WebsitePanel.WHMCSModule/changelog.log b/WebsitePanel.WHMCSModule/changelog.log new file mode 100644 index 00000000..02488cf6 --- /dev/null +++ b/WebsitePanel.WHMCSModule/changelog.log @@ -0,0 +1,3 @@ +01/29/2013 (1.2) +* WebsitePanel addons no longer require the storage of the Enterprise Server credentials +* Error codes are not properly resolved to their text responses \ No newline at end of file diff --git a/WebsitePanel.WHMCSModule/readme.txt b/WebsitePanel.WHMCSModule/readme.txt index dade497c..f45ca9c4 100644 --- a/WebsitePanel.WHMCSModule/readme.txt +++ b/WebsitePanel.WHMCSModule/readme.txt @@ -13,7 +13,7 @@ To enable addon automation... What does not work? - Quantities, only a single addon => addon can be allocated - Terminating / Suspending Addons, I've ran out of time on what I can do currently -- When an IP address is allocated WebsitePanel does not return back what IP was allocated, so WHMCS is not updated which what IP has been allocated to his / her package at this time. +- When an IP address is allocated, WebsitePanel does not return back what IP was allocated, so WHMCS is not updated with which IP was assigned to the users hosting space - A single user => single package is the only way the WebsitePanel server module works. I have no plans on making this work any other way. DO NOT CONTACT WHMCS FOR SUPPORT WITH THIS MODULE - THIS IS NOT DEVELOPED BY WHMCS AND HAS NO AFFILIATION WITH WHMCS OR WHMCS.COM. \ No newline at end of file From 54c8438ecef0569585e49b770ab75563d141b8aa Mon Sep 17 00:00:00 2001 From: ruslanht Date: Wed, 30 Jan 2013 17:33:37 +0200 Subject: [PATCH 6/9] Ability to change main WPI (Microsoft) feed url in System Settings. --- .../Common/WebPlatformInstaller.cs | 13 + .../System/SystemSettings.cs | 4 + .../WebsitePanel.EnterpriseServer.Base.csproj | 1 + .../WebAppGallery/WebAppGalleryController.cs | 32 +- .../esServers.asmx.cs | 30 +- .../WebsitePanel.Providers.Web.IIs60/IIs60.cs | 4 +- .../WebApplicationGallery.cs | 943 ------------------ .../WebsitePanel.Providers.Web.IIs60.csproj | 1 - .../WebsitePanel.Server/Code/WPIHelper.cs | 20 +- .../WebsitePanel.Server/WindowsServer.asmx.cs | 20 +- .../SystemSettings.ascx.resx | 6 + .../WebsitePanel/SystemSettings.ascx | 30 +- .../WebsitePanel/SystemSettings.ascx.cs | 37 +- .../SystemSettings.ascx.designer.cs | 22 +- 14 files changed, 122 insertions(+), 1041 deletions(-) create mode 100644 WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Common/WebPlatformInstaller.cs delete mode 100644 WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/WebApplicationGallery.cs diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Common/WebPlatformInstaller.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Common/WebPlatformInstaller.cs new file mode 100644 index 00000000..d7e28612 --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Common/WebPlatformInstaller.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace WebsitePanel.EnterpriseServer.Base.Common +{ + public class WebPlatformInstaller + { + public const string MAIN_FEED_URL = "https://www.microsoft.com/web/webpi/4.2/webproductlist.xml"; + public const string ZOO_FEED = "http://www.helicontech.com/zoo/feed/wsp4"; + } +} diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/System/SystemSettings.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/System/SystemSettings.cs index 904dec23..76778a16 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/System/SystemSettings.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/System/SystemSettings.cs @@ -42,6 +42,10 @@ namespace WebsitePanel.EnterpriseServer public const string BACKUP_SETTINGS = "BackupSettings"; public const string SETUP_SETTINGS = "SetupSettings"; public const string WPI_SETTINGS = "WpiSettings"; + + // key to access to wpi main & custom feed in wpi settings + public const string WPI_MAIN_FEED_KEY = "WpiMainFeedUrl"; + public const string FEED_ULS_KEY = "FeedUrls"; public static readonly SystemSettings Empty = new SystemSettings { SettingsArray = new string[][] {} }; diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/WebsitePanel.EnterpriseServer.Base.csproj b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/WebsitePanel.EnterpriseServer.Base.csproj index 9350215a..2168e6e3 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/WebsitePanel.EnterpriseServer.Base.csproj +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/WebsitePanel.EnterpriseServer.Base.csproj @@ -74,6 +74,7 @@ Code + diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/Code/WebAppGallery/WebAppGalleryController.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/Code/WebAppGallery/WebAppGalleryController.cs index ff0f06d2..e4fb539b 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/Code/WebAppGallery/WebAppGalleryController.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/Code/WebAppGallery/WebAppGalleryController.cs @@ -29,15 +29,14 @@ using System; using System.Collections.Generic; using System.Threading; -using WebsitePanel.Providers.Web; +using WebsitePanel.EnterpriseServer.Base.Common; +using WebsitePanel.Providers.Web; using WebsitePanel.Providers.ResultObjects; using WebsitePanel.Providers.Database; using WebsitePanel.Providers.WebAppGallery; using System.Collections.Specialized; -using System.Reflection; using WebsitePanel.Providers.Common; using System.Diagnostics; -using System.IO; namespace WebsitePanel.EnterpriseServer { @@ -72,28 +71,33 @@ namespace WebsitePanel.EnterpriseServer private static string[] getFeedsFromSettingsByServiceId(int serviceId) { - StringDictionary serviceSettings = ServerController.GetServiceSettings(serviceId); + var wpiSettings = SystemController.GetSystemSettings(SystemSettings.WPI_SETTINGS); - List arFeeds = new List(); + List feeds = new List(); - if (Utils.ParseBool(serviceSettings["FeedEnableMicrosoft"], true)) + // Microsoft feed + string mainFeedUrl = wpiSettings[SystemSettings.WPI_MAIN_FEED_KEY]; + if (string.IsNullOrEmpty(mainFeedUrl)) { - arFeeds.Add(esServers.MAIN_WPI_FEED); + mainFeedUrl = WebPlatformInstaller.MAIN_FEED_URL; } + feeds.Add(mainFeedUrl); - if (Utils.ParseBool(serviceSettings["FeedEnableHelicon"], true)) - { - arFeeds.Add(esServers.HELICON_WPI_FEED); - } + // Zoo Feed + feeds.Add(WebPlatformInstaller.ZOO_FEED); - string additionalFeeds = serviceSettings["FeedUrls"]; + + // additional feeds + string additionalFeeds = wpiSettings[SystemSettings.FEED_ULS_KEY]; if (!string.IsNullOrEmpty(additionalFeeds)) { - arFeeds.AddRange(additionalFeeds.Split(';')); + feeds.AddRange(additionalFeeds.Split(';')); } - return arFeeds.ToArray(); + return feeds.ToArray(); } + + public static void InitFeedsByServiceId(int UserId, int serviceId) { string[] feeds = getFeedsFromSettingsByServiceId(serviceId); diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esServers.asmx.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esServers.asmx.cs index c9f4a3b2..982c6f11 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esServers.asmx.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esServers.asmx.cs @@ -35,6 +35,7 @@ using System.Collections.Generic; using System.Web.Services; using System.Web.Services.Protocols; using System.ComponentModel; +using WebsitePanel.EnterpriseServer.Base.Common; using WebsitePanel.Providers.Common; using Microsoft.Web.Services3; @@ -54,8 +55,10 @@ namespace WebsitePanel.EnterpriseServer [ToolboxItem(false)] public class esServers : System.Web.Services.WebService { - public const string MAIN_WPI_FEED = "https://www.microsoft.com/web/webpi/4.0/WebProductList.xml"; + /* + public const string MAIN_WPI_FEED = "https://www.microsoft.com/web/webpi/4.2/WebProductList.xml"; public const string HELICON_WPI_FEED = "http://www.helicontech.com/zoo/feed/wsp4"; + */ #region Servers [WebMethod] @@ -696,25 +699,28 @@ namespace WebsitePanel.EnterpriseServer var wpiSettings = SystemController.GetSystemSettings(SystemSettings.WPI_SETTINGS); - List arFeeds = new List(); + List feeds = new List(); - if (Utils.ParseBool(wpiSettings["FeedEnableMicrosoft"] ,true)) + // Microsoft feed + string mainFeedUrl = wpiSettings[SystemSettings.WPI_MAIN_FEED_KEY]; + if (string.IsNullOrEmpty(mainFeedUrl)) { - arFeeds.Add( MAIN_WPI_FEED ); + mainFeedUrl = WebPlatformInstaller.MAIN_FEED_URL; } + feeds.Add(mainFeedUrl); - if (Utils.ParseBool(wpiSettings["FeedEnableHelicon"] ,true)) - { - arFeeds.Add( HELICON_WPI_FEED ); - } - - string additionalFeeds = wpiSettings["FeedUrls"]; + // Zoo Feed + feeds.Add(WebPlatformInstaller.ZOO_FEED); + + + // additional feeds + string additionalFeeds = wpiSettings[SystemSettings.FEED_ULS_KEY]; if (!string.IsNullOrEmpty(additionalFeeds)) { - arFeeds.AddRange(additionalFeeds.Split(';')); + feeds.AddRange(additionalFeeds.Split(';')); } - OperatingSystemController.InitWPIFeeds(serverId, string.Join(";", arFeeds)); + OperatingSystemController.InitWPIFeeds(serverId, string.Join(";", feeds)); } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/IIs60.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/IIs60.cs index 4aa4e55b..5319504f 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/IIs60.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/IIs60.cs @@ -279,7 +279,8 @@ namespace WebsitePanel.Providers.Web get { return FileUtils.EvaluateSystemVariables(ProviderSettings["ProtectedFoldersFile"]); } } - protected string GalleryXmlFeedUrl + /* + protected string GalleryXmlFeedUrl { get { @@ -289,6 +290,7 @@ namespace WebsitePanel.Providers.Web return ret; } } + */ #endregion private WmiHelper wmi = null; diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/WebApplicationGallery.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/WebApplicationGallery.cs deleted file mode 100644 index 913e9a2a..00000000 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/WebApplicationGallery.cs +++ /dev/null @@ -1,943 +0,0 @@ -// Copyright (c) 2012, Outercurve Foundation. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// - Neither the name of the Outercurve Foundation nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -using System; -using System.Collections.Generic; -using System.Text; - -using System.Xml; -using System.Xml.Serialization; - -using Microsoft.Practices.EnterpriseLibrary.Caching; -using System.Net; -using System.IO; -using WebsitePanel.Server.Utils; -using WebsitePanel.Providers.WebAppGallery; -using System.Text.RegularExpressions; -using System.Web; -using System.Reflection; -using Microsoft.Web.Deployment; -using System.Diagnostics; -using System.Threading; -using System.Security.Cryptography; -using System.Collections; -using Microsoft.Win32; -using System.Linq; - -namespace WebsitePanel.Providers.Web -{ - [Obsolete] - public sealed class WebApplicationGallery - { - // MS Deploy library - private const string MS_DEPLOY_ASSEMBLY_NAME = "Microsoft.Web.Deployment"; - - private CacheManager cache; - private static DeploymentSkipDirective SkipMsSQL = new DeploymentSkipDirective("skipSqlDirective", "objectName=dbFullSql"); - private static DeploymentSkipDirective SkipMySQL = new DeploymentSkipDirective("skipSqlDirective", "objectName=dbMySql"); - - public const string AtomFeedNamespace = "http://www.w3.org/2005/Atom"; - - public static string WEB_PI_USER_AGENT_HEADER = "Platform-Installer/{0}({1})"; - public const string WEB_PI_APP_PACK_ROOT_INSTALLER_ITEM_MISSING = "Root installer item for the {0} application could not be found. Please contact your Web Application Gallery feed provider to resolve the error."; - public const string WEB_PI_APP_PACK_DISPLAY_URL_MISSING = "Web application '{0}' could not be downloaded as installer displayURL is empty or missing."; - - // web application gallery - public const string WAG_XML_FEED_CACHE_KEY = "WAG_XML_FEED_CACHE_KEY"; - public const int WEB_APPLICATIONS_CACHE_STORE_MINUTES = 60; - public const int XML_FEED_RECOVERY_ATTEMPTS = 10; - // public const string WAG_DEFAULT_FEED_URL = "https://www.microsoft.com/web/webpi/3.0/WebApplicationList.xml"; - public const string WAG_DEFAULT_FEED_URL = "https://www.microsoft.com/web/webpi/4.0/webapplicationlist.xml"; - - // well-known parameters matching - public readonly Dictionary wellKnownParameters - = new Dictionary(StringComparer.InvariantCultureIgnoreCase) - { - {"Database Server", DeploymentParameterWellKnownTag.DBServer}, - {"Database Administrator", DeploymentParameterWellKnownTag.DBAdminUserName}, - {"Database Administrator Password", DeploymentParameterWellKnownTag.DBAdminPassword}, - {"Database Name", DeploymentParameterWellKnownTag.DBName}, - {"Database User Name", DeploymentParameterWellKnownTag.DBUserName}, - {"Database Password", DeploymentParameterWellKnownTag.DBUserPassword} - }; - - // well-known dependencies matching - public readonly Dictionary wellKnownDependencies - = new Dictionary(StringComparer.InvariantCultureIgnoreCase) - { - {"ASPNETApp", GalleryApplicationWellKnownDependency.AspNet20}, - {"ASPNET35App", GalleryApplicationWellKnownDependency.AspNet20}, - {"MVCApp", GalleryApplicationWellKnownDependency.AspNet20}, - {"ASPNET4App", GalleryApplicationWellKnownDependency.AspNet40}, - {"PHPApp", GalleryApplicationWellKnownDependency.PHP}, - {"SQLApp", GalleryApplicationWellKnownDependency.SQL}, - {"SQLDriverPHPApp", GalleryApplicationWellKnownDependency.SQL}, - {"MySQLApp", GalleryApplicationWellKnownDependency.MySQL} - }; - - private string feedXmlURI; - - static WebApplicationGallery() - { - AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_MSDeploy_AssemblyResolve); - } - - static Assembly CurrentDomain_MSDeploy_AssemblyResolve(object sender, ResolveEventArgs args) - { - // Ensure we resolve MSDeploy assembly - if (args.Name.StartsWith(MS_DEPLOY_ASSEMBLY_NAME) == false) - return null; - // - var regkey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\IIS Extensions\MSDeploy"); - // - if (regkey == null) - return null; - // Always start with the most recent version of MSDeploy - var versionKeys = regkey.GetSubKeyNames().OrderByDescending(x => x).ToArray(); - // Log all version keys found - Array.ForEach(versionKeys, (x) => { Log.WriteInfo("MSDeploy version key found: {0}", x); }); - // Determine appropriate key name to query for - var installPathKey = (IntPtr.Size == 8) ? "InstallPath" : "InstallPath_x86"; - - // Check if running in 32bit mode under 64bit Windows (WOW64) - works with .NET 2.0+ - if (Environment.GetEnvironmentVariable("PROCESSOR_ARCHITEW6432") == "AMD64") - { - installPathKey = "InstallPath_x64"; - } - - var fileVersion = String.Empty; - // - var libPath = String.Empty; - // - for (int i = 0; i < versionKeys.Length; i++) - { - var versionKey = regkey.OpenSubKey(versionKeys[i]); - // - libPath = Path.Combine(versionKey.GetValue(installPathKey).ToString(), String.Concat(MS_DEPLOY_ASSEMBLY_NAME, ".dll")); - // - Log.WriteInfo("MSDeploy v{0}; Lib Path: {1}", versionKeys[i], libPath); - // - if (File.Exists(libPath) == true) - { - Log.WriteInfo("MSDeploy Lib Path: {0};", libPath); - var fileVerInfo = FileVersionInfo.GetVersionInfo(libPath); - // - WEB_PI_USER_AGENT_HEADER = String.Format(WEB_PI_USER_AGENT_HEADER, fileVerInfo.FileVersion, Environment.OSVersion.VersionString); - // - break; - } - } - // - if (String.IsNullOrEmpty(libPath) == false) - return Assembly.LoadFrom(libPath); - // - return null; - } - - public WebApplicationGallery() - : this(WAG_DEFAULT_FEED_URL) - { - } - - public WebApplicationGallery(string feedXmlURI) - { - cache = CacheFactory.GetCacheManager(); - // - this.feedXmlURI = feedXmlURI; - } - - public XmlDocument GetServiceXmlFeed() - { - XmlDocument xmldoc = (XmlDocument)cache[WAG_XML_FEED_CACHE_KEY]; - // - if (xmldoc == null) - { - // First trying to load as usual... - try - { - // - xmldoc = new XmlDocument(); - xmldoc.Load(feedXmlURI); - - // Add XML to the cache - cache.Add(WAG_XML_FEED_CACHE_KEY, xmldoc); - } - catch (Exception ex) - { - Log.WriteError( - String.Format(@"Could not load xml feed in a usual way from '{0}', -thus proceed to XML-FEED-RECOVERY section to try download it again in an advanced way. -No action is required the message for information purposes only.", feedXmlURI), ex); - } - // Unable to load feed in the usual way, so lets try to "fix" content-encoding issue - if (!xmldoc.HasChildNodes) - { - // - int numOfRetries = 0; - // - try - { - WebClient wc = new WebClient(); - wc.Headers.Add(HttpRequestHeader.UserAgent, WEB_PI_USER_AGENT_HEADER); - // Setting response encoding explicitly - wc.Encoding = Encoding.UTF8; - // - string feedXmlString = wc.DownloadString(feedXmlURI); - // Loading XML for several times with shift the from the beginning may helps - // to eliminate encoding issue (somtimes several starting bytes are not recognized - // by the parser and thus feed load is failed) - do - { - try - { - xmldoc.LoadXml(feedXmlString.Substring(numOfRetries)); - - // Add XML to the cache - cache.Add(WAG_XML_FEED_CACHE_KEY, xmldoc); - // - Log.WriteInfo("XML feed has been successfully added into the cache. See its content below."); - Log.WriteInfo(xmldoc.OuterXml); - // Exit from the loop if XML is loaded successfully - break; - } - catch(Exception ex) - { - // Log an exception - Log.WriteError( - String.Format("XML-FEED-RECOVERY is failed at {0} attempt. {1} attempts left.", numOfRetries, XML_FEED_RECOVERY_ATTEMPTS-numOfRetries), ex); - // - numOfRetries++; - } - } - while (numOfRetries <= XML_FEED_RECOVERY_ATTEMPTS); - } - catch (Exception ex) - { - // Log an exception - Log.WriteError(@"XML-FEED-RECOVERY is failed to recover the feed automatically. -Please ensure that the feed is a correct XML file if you use a custom one, -otherwise contact WebsitePanel Software for further assistance.", ex); - } - } - //// - //XmlNamespaceManager nsmgr = GetXmlNsManager(xmldoc.NameTable); - //// - //XmlNode rootNode = xmldoc.DocumentElement.SelectSingleNode("atom:dependencies", nsmgr); - //// - //XmlNodeList idRefNodes = rootNode.SelectNodes(".//atom:dependency[@idref]", nsmgr); - //// - //foreach (XmlNode idRefNode in idRefNodes) - //{ - // // - // XmlNode idRefRepo = xmldoc.DocumentElement.SelectSingleNode( - // String.Format("//atom:dependency[@id='{0}']", idRefNode.Attributes["idref"].Value), nsmgr); - // // - // if (idRefRepo != null) - // { - // idRefNode.ParentNode.ReplaceChild(idRefRepo.Clone(), idRefNode); - // } - //} - - //// - //idRefNodes = xmldoc.DocumentElement.SelectNodes("//atom:dependency[@idref]", nsmgr); - //// - //foreach (XmlNode idRefNode in idRefNodes) - //{ - // // - // XmlNode idRefRepo = xmldoc.DocumentElement.SelectSingleNode( - // String.Format("//atom:dependency[@id='{0}']", idRefNode.Attributes["idref"].Value), nsmgr); - // // - // if (idRefRepo != null) - // { - // idRefNode.ParentNode.ReplaceChild(idRefRepo.Clone(), idRefNode); - // } - //} - } - // - return xmldoc; - } - - public bool IsMsDeployInstalled() - { - // - try - { - Assembly.Load(MS_DEPLOY_ASSEMBLY_NAME); - return true; - } - catch - { - // type could not be instantiated - return false; - } - } - - public List GetCategories() - { - XmlDocument xmldoc = GetServiceXmlFeed(); - // - if (xmldoc == null) - return null; - - // get namespace manager - XmlNamespaceManager nsmgr = GetXmlNsManager(xmldoc.NameTable); - - // get the list of all categories that are used by applications - List appCategories = new List(); - foreach (XmlNode node in xmldoc.SelectNodes("//atom:entry[@type='application']/atom:keywords/atom:keywordId", nsmgr)) - appCategories.Add(node.InnerText); - - // get the list of all categories defined in the feed - // and filter them - List categories = new List(); - foreach (XmlNode node in xmldoc.SelectNodes("/atom:feed/atom:keywords/atom:keyword", nsmgr)) - { - string id = node.Attributes["id"].Value; - string name = node.InnerText; - if(appCategories.Contains(id)) - categories.Add(new GalleryCategory { Id = id, Name = name }); - } - - return categories; - } - - public List GetApplications(string categoryName) - { - XmlDocument xmldoc = GetServiceXmlFeed(); - // - if (xmldoc == null) - return null; - // - XmlNamespaceManager nsmgr = GetXmlNsManager(xmldoc.NameTable); - // - string xQuery = String.IsNullOrEmpty(categoryName) ? "//atom:entry[@type='application']" - : String.Format("//atom:entry[@type='application' and atom:keywords[atom:keywordId='{0}']]", categoryName); - // - List appList = new List(); - // - foreach (XmlNode node in xmldoc.SelectNodes(xQuery, nsmgr)) - { - appList.Add(DeserializeGalleryApplication(node, nsmgr)); - } - - // sort apps alphabetically - appList.Sort( (a,b) => { return String.Compare(a.Title, b.Title, true); }); - - // - return appList; - } - - public GalleryApplication GetApplicationByProductId(string productId) - { - XmlDocument xmldoc = GetServiceXmlFeed(); - // - if (xmldoc == null) - return null; - // - XmlNamespaceManager nsmgr = GetXmlNsManager(xmldoc.NameTable); - // - string xQuery = String.Format("//atom:entry[@type='application' and atom:productId='{0}']", productId); - // - XmlNode node = xmldoc.SelectSingleNode(xQuery, nsmgr); - // - GalleryApplication app = DeserializeGalleryApplication(node, nsmgr); - // - return app; - } - - public string GetApplicationPackagePath(string productId) - { - return GetApplicationPackagePath(GetApplicationByProductId(productId)); - } - - public string GetApplicationPackagePath(GalleryApplication app) - { - // - string appPackagePath = null; - // - if (app != null) - { - InstallerFile installerFile = null; - // Acquire root installer item - #region Atom Feed Version 0.2 - if (app.InstallerItems.Count > 0) - { - InstallerItem installerItem_0 = app.InstallerItems[0]; - if (installerItem_0 == null) - { - Log.WriteWarning(WEB_PI_APP_PACK_ROOT_INSTALLER_ITEM_MISSING, app.Title); - return appPackagePath; - } - // Ensure web app package can be reached - installerFile = installerItem_0.InstallerFile; - } - #endregion - - #region Atom Feed Version 2.0.1.0 - else if (app.Installers.Count > 0) - { - Installer installerItem_0 = app.Installers[0]; - if (installerItem_0 == null) - { - Log.WriteWarning(WEB_PI_APP_PACK_ROOT_INSTALLER_ITEM_MISSING, app.Title); - return appPackagePath; - } - // Ensure web app package can be reached - installerFile = installerItem_0.InstallerFile; - } - #endregion - - if (installerFile == null || String.IsNullOrEmpty(installerFile.InstallerUrl)) - { - Log.WriteWarning(WEB_PI_APP_PACK_DISPLAY_URL_MISSING, app.Title); - return appPackagePath; - } - // - Log.WriteInfo("Web App Download URL: {0}", installerFile.InstallerUrl); - // Trying to match the original file name - HttpWebRequest webReq = (HttpWebRequest)HttpWebRequest.Create(installerFile.InstallerUrl); - { - // - Regex regex = new Regex("filename=\"(?.{0,})\""); - string packageName = null; - // - webReq.UserAgent = WEB_PI_USER_AGENT_HEADER; - // - using (HttpWebResponse webResp = (HttpWebResponse)webReq.GetResponse()) - { - string httpHeader = webResp.Headers["Content-Disposition"]; - // - if (!String.IsNullOrEmpty(httpHeader)) - { - string fileName = Array.Find(httpHeader.Split(';'), - x => x.Trim().StartsWith("filename=")); - // - Match match = regex.Match(fileName); - // Match has been acquired - if (match != null && match.Success) - { - packageName = match.Groups["packageName"].Value; - } - } - } - // Download URL points to the download package directly - if (String.IsNullOrEmpty(packageName)) - { - packageName = Path.GetFileName(installerFile.InstallerUrl); - } - // - if (HttpContext.Current != null) - { - appPackagePath = HttpContext.Current.Server.MapPath(String.Format("~/App_Cache/{0}", packageName)); - } - else - { - string assemblyPath = Path.GetDirectoryName(this.GetType().Assembly.Location); - appPackagePath = Path.Combine(assemblyPath, String.Format(@"App_Cache\{0}", packageName)); - } - } - } - // - return appPackagePath; - } - - public List GetApplicationParameters(string productId) - { - string packageFile = GetApplicationPackagePath(productId); - // - if (String.IsNullOrEmpty(packageFile)) - return null; - // - List appParams = new List(); - // - DeploymentObject iisApplication = null; - // - try - { - iisApplication = DeploymentManager.CreateObject(DeploymentWellKnownProvider.Package, packageFile); - // - foreach (DeploymentSyncParameter parameter in iisApplication.SyncParameters) - { - DeploymentParameter p = new DeploymentParameter - { - Name = parameter.Name, - FriendlyName = !String.IsNullOrEmpty(parameter.FriendlyName) ? parameter.FriendlyName : parameter.Name, - Value = parameter.Value, - DefaultValue = parameter.DefaultValue, - Description = parameter.Description, - ValidationKind = (DeploymentParameterValidationKind)parameter.Validation.Kind, - ValidationString = parameter.Validation.ValidationString, - WellKnownTags = (DeploymentParameterWellKnownTag)parameter.WellKnownTags - }; - - // add to the list - appParams.Add(p); - - // fix tags for parameters with hard-coded names - if(wellKnownParameters.ContainsKey(p.Name)) - p.WellKnownTags |= wellKnownParameters[p.Name]; - } - } - catch (Exception ex) - { - // Log an error - Log.WriteError( - String.Format("Could not read deployment parameters from '{0}' package.", packageFile), ex); - // - throw; - } - finally - { - if (iisApplication != null) - iisApplication.Dispose(); - } - // - return appParams; - } - - public string InstallApplication(string productId, List updatedParameters) - { - string packageFile = GetApplicationPackagePath(productId); - string applicationPath = null; - - if (String.IsNullOrEmpty(packageFile)) - return null; - - Log.WriteInfo("WebApp Package Path: {0}", packageFile); - - if (!File.Exists(packageFile)) - throw new Exception(GalleryErrors.PackageFileNotFound); - - // Setup source deployment options - DeploymentBaseOptions sourceOptions = new DeploymentBaseOptions(); - - // Add tracing capabilities - sourceOptions.Trace += new EventHandler(sourceOptions_Trace); - sourceOptions.TraceLevel = TraceLevel.Verbose; - - // Setup deployment provider - DeploymentProviderOptions providerOptions = new DeploymentProviderOptions(DeploymentWellKnownProvider.Package); - - // Set the package path location - providerOptions.Path = packageFile; - - // Prepare the package deployment procedure - using (DeploymentObject iisApplication = DeploymentManager.CreateObject(providerOptions, sourceOptions)) - { - // Setup destination deployment options - DeploymentBaseOptions destinationOptions = new DeploymentBaseOptions(); - // Add tracing capabilities - destinationOptions.Trace += new EventHandler(sourceOptions_Trace); - destinationOptions.TraceLevel = TraceLevel.Verbose; - - // MSDEPLOY TEAM COMMENTS: For each parameter that was specified in the UI, set its value - DeploymentParameterWellKnownTag databaseEngine = DeploymentParameterWellKnownTag.None; - - int i = 0; - while(i < iisApplication.SyncParameters.Count) - { - // try to find parameter in updated parameters - string name = iisApplication.SyncParameters[i].Name; - DeploymentParameter updatedParameter = updatedParameters.Find( p => { return String.Compare(p.Name, name) == 0; }); - - if(updatedParameter != null) - { - // parameter found - // update its value - iisApplication.SyncParameters[i].Value = updatedParameter.Value; - i++; // advance to the next parameter - - // check for selected database engine - if ((updatedParameter.WellKnownTags & DeploymentParameterWellKnownTag.MySql) == DeploymentParameterWellKnownTag.MySql) - databaseEngine = DeploymentParameterWellKnownTag.MySql; - else if ((updatedParameter.WellKnownTags & DeploymentParameterWellKnownTag.Sql) == DeploymentParameterWellKnownTag.Sql) - databaseEngine = DeploymentParameterWellKnownTag.Sql; - - // get application path - if ((updatedParameter.WellKnownTags & DeploymentParameterWellKnownTag.IisApp) == DeploymentParameterWellKnownTag.IisApp) - applicationPath = updatedParameter.Value; - } - else - { - // parameter not found - // delete it - iisApplication.SyncParameters.Remove(name); - } - } - - - // Skip SQL Server database scripts if not SQL Server was selected - if (databaseEngine != DeploymentParameterWellKnownTag.Sql) - sourceOptions.SkipDirectives.Add(SkipMsSQL); - - // Skip MySQL database scripts if not MySQL was selected - if (databaseEngine != DeploymentParameterWellKnownTag.MySql) - sourceOptions.SkipDirectives.Add(SkipMySQL); - - // Setup deployment options - DeploymentSyncOptions syncOptions = new DeploymentSyncOptions(); - // Add tracing capabilities - //syncOptions..Action += new EventHandler(syncOptions_Action); - // Issue a syncronization signal between the parties - iisApplication.SyncTo(DeploymentWellKnownProvider.Auto, applicationPath, destinationOptions, syncOptions); - // - Log.WriteInfo("{0}: {1}", "Application path", applicationPath); - // - } - // - return applicationPath; - } - - #region Helper methods - - private XmlNamespaceManager GetXmlNsManager(XmlNameTable nt) - { - XmlNamespaceManager nsmgr = new XmlNamespaceManager(nt); - nsmgr.AddNamespace("atom", "http://www.w3.org/2005/Atom"); - // - return nsmgr; - } - - private GalleryApplication DeserializeGalleryApplication(XmlNode node, XmlNamespaceManager nsmgr) - { - XmlSerializer xs = new XmlSerializer(typeof(GalleryApplication), AtomFeedNamespace); - GalleryApplication app = (GalleryApplication)xs.Deserialize(new XmlNodeReader(node)); - // - app.LastUpdated = XmlToDateTime(GetAtomNodeText(node, nsmgr, "updated"), "yyyy-M-dTHH:mm:ssZ"); - app.Published = XmlToDateTime(GetAtomNodeText(node, nsmgr, "published"), "yyyy-M-dTHH:mm:ssZ"); - app.Link = GetAtomNodeAttribute(node, nsmgr, "link", "href"); - // - app.IconUrl = GetAtomNodeText(node, nsmgr, "images/atom:icon"); - - // parse well-known dependencies - UpdateApplicationWellKnownDependencies(app, app.Dependency); - - // - return app; - } - - private void UpdateApplicationWellKnownDependencies(GalleryApplication app, Dependency dependency) - { - if (dependency == null) - return; - - if (dependency.IdRef != null && wellKnownDependencies.ContainsKey(dependency.IdRef)) - app.WellKnownDependencies |= wellKnownDependencies[dependency.IdRef]; - - // process "And" - foreach (Dependency d in dependency.And) - UpdateApplicationWellKnownDependencies(app, d); - - // process "Or" - foreach (Dependency d in dependency.Or) - UpdateApplicationWellKnownDependencies(app, d); - - // process "LogicalAnd" - foreach (Dependency d in dependency.LogicalAnd) - UpdateApplicationWellKnownDependencies(app, d); - - // process "LogicalOr" - foreach (Dependency d in dependency.LogicalOr) - UpdateApplicationWellKnownDependencies(app, d); - } - - private string GetAtomNodeText(XmlNode app, XmlNamespaceManager nsmgr, string nodeName) - { - XmlNode node = app.SelectSingleNode("atom:" + nodeName, nsmgr); - if (node == null) - return null; - return node.InnerText; - } - - private string GetAtomNodeAttribute(XmlNode app, XmlNamespaceManager nsmgr, string nodeName, string attributeName) - { - XmlNode node = app.SelectSingleNode("atom:" + nodeName, nsmgr); - if (node == null) - return null; - string ret = null; - XmlAttribute attribute = node.Attributes[attributeName]; - if (attribute != null) - ret = attribute.Value; - return ret; - } - - private DateTime XmlToDateTime(string val, string format) - { - DateTime ret = DateTime.MinValue; - - try - { - if (!string.IsNullOrEmpty(val)) - ret = XmlConvert.ToDateTime(val, format); - } - catch (Exception) { } - return ret; - } - - private static string GetAtomNodeText(XmlNode node) - { - if (node == null) - return null; - return node.InnerText; - } - - private void sourceOptions_Trace(object sender, DeploymentTraceEventArgs e) - { - Log.WriteInfo(e.Message); - Log.WriteInfo("Event Level: " + e.EventLevel); - Log.WriteInfo("Event Data: "); - // - foreach (string keyName in e.EventData.Keys) - { - Log.WriteInfo(keyName + " => " + e.EventData[keyName]); - } - } - - /*private void syncOptions_Action(object sender, DeploymentActionEventArgs e) - { - Log.WriteInfo(e.Message); - Log.WriteInfo("Operation Type: " + e.OperationType); - Log.WriteInfo("Event Data: "); - // - foreach (string keyName in e.EventData.Keys) - { - Log.WriteInfo(keyName + " => " + e.EventData[keyName]); - } - }*/ - - #endregion - } - - public class DownloadQueueItem - { - public String ItemKey; - public WebClient ConnectionPoint; - public DownloadProgressChangedEventArgs Progress; - public string DownloadItemURI; - public string LocalFilePathToStore; - - public void StartItemDownloadAsync(Object state) - { - ConnectionPoint.DownloadFileAsync(new Uri(DownloadItemURI), LocalFilePathToStore); - } - } - - public sealed class AppPackagesDownloader - { - private static List downloadQueue; - - static AppPackagesDownloader() - { - downloadQueue = new List(); - } - - // - public static bool CheckApplicationPackageHashSum_MD5(string localFilePath, string md5) - { - if (!File.Exists(localFilePath)) - return false; - // - bool md5OK = false; - // - try - { - // - MD5 md5File = new MD5CryptoServiceProvider(); - // - string fileMd5Sum = BitConverter.ToString( - md5File.ComputeHash(File.ReadAllBytes(localFilePath))).Replace("-", String.Empty); - // - md5OK = String.Equals(md5, fileMd5Sum, StringComparison.InvariantCultureIgnoreCase); - } - catch (Exception ex) - { - Log.WriteError(String.Format("Failed to compute MD5 sum for {0} package.", localFilePath), ex); - } - // - return md5OK; - } - - // - public static bool CheckApplicationPackageHashSum_SHA1(string localFilePath, string sha1) - { - if (!File.Exists(localFilePath)) - return false; - // - bool sha1OK = false; - // - try - { - // - SHA1 sha1File = new SHA1CryptoServiceProvider(); - // - string fileSha1Sum = BitConverter.ToString( - sha1File.ComputeHash(File.ReadAllBytes(localFilePath))).Replace("-", String.Empty); - // - sha1OK = String.Equals(sha1, fileSha1Sum, StringComparison.InvariantCultureIgnoreCase); - // - if (!sha1OK) - Log.WriteWarning("SHA1-XML FEED: {0}; SHA1-FILE ON DISK: {1};", sha1, fileSha1Sum); - } - catch (Exception ex) - { - Log.WriteError(String.Format("Failed to compute SHA1 sum for {0} package.", localFilePath), ex); - } - // - return sha1OK; - } - - // - public static bool IsApplicationInDownloadQueue(string appName) - { - bool exists = false; - // - if (!String.IsNullOrEmpty(appName)) - { - ICollection ic = downloadQueue as ICollection; - // - lock (ic.SyncRoot) - { - exists = Array.Exists(downloadQueue.ToArray(), - x => x.ItemKey == appName.ToLower()); - } - } - // - return exists; - } - - // - public static void StartApplicationDownload(string appName, string packageUrl, string localPathToStore) - { - // - bool appInQueue = IsApplicationInDownloadQueue(appName); - // - if (!appInQueue) - { - ICollection ic = downloadQueue as ICollection; - // - lock (ic.SyncRoot) - { - // - DownloadQueueItem qi = new DownloadQueueItem - { - ItemKey = appName.ToLower(), - ConnectionPoint = new WebClient(), - Progress = null - }; - // - qi.DownloadItemURI = packageUrl; - qi.LocalFilePathToStore = localPathToStore; - qi.ConnectionPoint.Headers.Add(HttpRequestHeader.UserAgent, WebApplicationGallery.WEB_PI_USER_AGENT_HEADER); - qi.ConnectionPoint.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(wc_DownloadFileCompleted); - qi.ConnectionPoint.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged); - // - downloadQueue.Add(qi); - // Start async download (10 attempts) - int numOfAttempt = 0; - do - { - try - { - bool success = ThreadPool.QueueUserWorkItem( - new WaitCallback(qi.StartItemDownloadAsync)); - // Exit the loop if the item successfuly queued - if (success) - break; - } - catch (Exception ex) - { - numOfAttempt++; - // Log an exception - Log.WriteError(String.Format("Could not start distibutive download from the following URI: {0}", qi.DownloadItemURI), ex); - } - } - while (numOfAttempt <= 10); - } - } - } - - public static int GetApplicationDownloadProgress(string appName) - { - int appProgress = 0; - // - bool appInQueue = IsApplicationInDownloadQueue(appName); - // - if (appInQueue) - { - ICollection ic = downloadQueue as ICollection; - // - lock (ic.SyncRoot) - { - DownloadQueueItem qi = Array.Find(downloadQueue.ToArray(), - x => x.ItemKey == appName.ToLower()); - // - if (qi.Progress != null) - appProgress = qi.Progress.ProgressPercentage; - } - } - // - return appProgress; - } - - static void wc_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) - { - ICollection ic = downloadQueue as ICollection; - // - lock (ic.SyncRoot) - { - DownloadQueueItem qi = Array.Find(downloadQueue.ToArray(), - x => x.ConnectionPoint == sender); - // - if (e.Error != null) - { - // - if (qi != null) - Log.WriteError(String.Format("Could not download app {0}", qi.ItemKey), e.Error); - else - Log.WriteError(e.Error); - } - // - downloadQueue.Remove(qi); - } - } - - static void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) - { - ICollection ic = downloadQueue as ICollection; - // - lock (ic.SyncRoot) - { - DownloadQueueItem qi = Array.Find(downloadQueue.ToArray(), - x => x.ConnectionPoint == sender); - - if (qi != null) - qi.Progress = e; - } - } - } -} \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/WebsitePanel.Providers.Web.IIs60.csproj b/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/WebsitePanel.Providers.Web.IIs60.csproj index 3e06a8b4..d14ee66c 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/WebsitePanel.Providers.Web.IIs60.csproj +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/WebsitePanel.Providers.Web.IIs60.csproj @@ -93,7 +93,6 @@ - diff --git a/WebsitePanel/Sources/WebsitePanel.Server/Code/WPIHelper.cs b/WebsitePanel/Sources/WebsitePanel.Server/Code/WPIHelper.cs index 09ec94c2..1976ea33 100644 --- a/WebsitePanel/Sources/WebsitePanel.Server/Code/WPIHelper.cs +++ b/WebsitePanel/Sources/WebsitePanel.Server/Code/WPIHelper.cs @@ -57,8 +57,6 @@ namespace WebsitePanel.Server.Code private readonly List _feeds; private string _webPIinstallersFolder; - //private const string MainWpiFeed = "https://www.microsoft.com/web/webpi/3.0/webproductlist.xml"; - private const string MainWpiFeed = "https://www.microsoft.com/web/webpi/4.0/WebProductList.xml"; private const string IisChoiceProduct = "StaticContent"; private const string WebMatrixChoiceProduct = "WebMatrix"; private ProductManager _productManager; @@ -79,6 +77,14 @@ namespace WebsitePanel.Server.Code public WpiHelper(IEnumerable feeds) { + // check feeds is not empty + if (null == feeds || !feeds.Any()) + { + throw new Exception("WpiHelper error: empty feed list in constructor"); + } + + + // by default feeds must contains main MS WPI feed url and Zoo feed url _feeds = new List(); _feeds.AddRange(feeds); @@ -135,7 +141,6 @@ namespace WebsitePanel.Server.Code } #endregion - #region Keywords public ReadOnlyCollection GetKeywords() { @@ -158,8 +163,6 @@ namespace WebsitePanel.Server.Code } #endregion - - #region Products public List GetProductsToInstall(string FeedLocation, string keywordId) { @@ -546,6 +549,7 @@ namespace WebsitePanel.Server.Code } #endregion + #endregion Public interface @@ -553,12 +557,6 @@ namespace WebsitePanel.Server.Code private void Initialize() { - // insert Main WebPI xml file - if (!_feeds.Contains(MainWpiFeed, StringComparer.OrdinalIgnoreCase)) - { - _feeds.Insert(0, MainWpiFeed); - } - // create cache folder if not exists //_webPIinstallersFolder = Environment.ExpandEnvironmentVariables(@"%LocalAppData%\Microsoft\Web Platform Installer\installers"); _webPIinstallersFolder = Path.Combine( diff --git a/WebsitePanel/Sources/WebsitePanel.Server/WindowsServer.asmx.cs b/WebsitePanel/Sources/WebsitePanel.Server/WindowsServer.asmx.cs index 8940e917..c6398bf5 100644 --- a/WebsitePanel/Sources/WebsitePanel.Server/WindowsServer.asmx.cs +++ b/WebsitePanel/Sources/WebsitePanel.Server/WindowsServer.asmx.cs @@ -477,11 +477,7 @@ namespace WebsitePanel.Server } - static string[] FEEDS = new string[] - { - // "https://www.microsoft.com/web/webpi/3.0/WebProductList.xml", - // "http://www.helicontech.com/zoo/feed/" - }; + static private string[] _feeds = new string[]{}; [WebMethod] public void InitWPIFeeds(string feedUrls) @@ -491,18 +487,18 @@ namespace WebsitePanel.Server throw new Exception("Empty feed list"); } - string[] newFEEDS = feedUrls.Split(';'); + string[] newFeeds = feedUrls.Split(';'); - if (newFEEDS.Length == 0) + if (newFeeds.Length == 0) { throw new Exception("Empty feed list"); } - if (!ArraysEqual(newFEEDS, FEEDS)) + if (!ArraysEqual(newFeeds, _feeds)) { Log.WriteInfo("InitWPIFeeds - new value: " + feedUrls); //Feeds settings have been channged - FEEDS = newFEEDS; + _feeds = newFeeds; wpi = null; } @@ -604,7 +600,7 @@ namespace WebsitePanel.Server WPIServiceContract client = new WPIServiceContract(); - client.Initialize(FEEDS); + client.Initialize(_feeds); client.BeginInstallation(products); @@ -795,14 +791,14 @@ namespace WebsitePanel.Server static WpiHelper wpi = null; WpiHelper GetWpiFeed() { - if (FEEDS.Length == 0) + if (_feeds.Length == 0) { throw new Exception("Empty feed list"); } if (null == wpi) { - wpi = new WpiHelper(FEEDS); + wpi = new WpiHelper(_feeds); } return wpi; } diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/SystemSettings.ascx.resx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/SystemSettings.ascx.resx index 1b0c52e9..feb70193 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/SystemSettings.ascx.resx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/SystemSettings.ascx.resx @@ -147,4 +147,10 @@ Enable SSL: + + Main feed URL: + + + Custom feeds: + \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx index f8d61d60..55b85a1a 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx @@ -35,34 +35,28 @@ - - + +
- - - -<%-- + TargetControlID="WpiPanel" meta:resourcekey="lclWpiSettings" Text="Web Platform Installer Settings"/> + + +
- - + + - - - + -
Enable Microsoft feed - -
Enable HeliconTech feed - + +
---%> - +
diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx.cs index 69b9cc37..e1462225 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx.cs @@ -36,7 +36,7 @@ using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; - +using WebsitePanel.EnterpriseServer.Base.Common; using WSP = WebsitePanel.EnterpriseServer; namespace WebsitePanel.Portal @@ -48,12 +48,12 @@ namespace WebsitePanel.Portal public const string SMTP_USERNAME = "SmtpUsername"; public const string SMTP_PASSWORD = "SmtpPassword"; public const string SMTP_ENABLE_SSL = "SmtpEnableSsl"; - public const string BACKUPS_PATH = "BackupsPath"; - public const string FEED_ULS = "FeedUrls"; + /* public const string FEED_ENABLE_MICROSOFT = "FeedEnableMicrosoft"; public const string FEED_ENABLE_HELICON = "FeedEnableHelicon"; + */ protected void Page_Load(object sender, EventArgs e) { @@ -95,20 +95,31 @@ namespace WebsitePanel.Portal // WPI - settings = ES.Services.System.GetSystemSettings( - WSP.SystemSettings.WPI_SETTINGS); + settings = ES.Services.System.GetSystemSettings(WSP.SystemSettings.WPI_SETTINGS); + /* if (settings != null) { wpiMicrosoftFeed.Checked = Utils.ParseBool(settings[FEED_ENABLE_MICROSOFT],true); wpiHeliconTechFeed.Checked = Utils.ParseBool(settings[FEED_ENABLE_HELICON],true); - wpiEditFeedsList.Value = settings[FEED_ULS]; } else { wpiMicrosoftFeed.Checked = true; wpiHeliconTechFeed.Checked = true; + } + */ + if (null != settings) + { + wpiEditFeedsList.Value = settings[WSP.SystemSettings.FEED_ULS_KEY]; + + string mainFeedUrl = settings[WSP.SystemSettings.WPI_MAIN_FEED_KEY]; + if (string.IsNullOrEmpty(mainFeedUrl)) + { + mainFeedUrl = WebPlatformInstaller.MAIN_FEED_URL; + } + txtMainFeedUrl.Text = mainFeedUrl; } @@ -152,13 +163,21 @@ namespace WebsitePanel.Portal // WPI - settings[FEED_ULS] = wpiEditFeedsList.Value; + /* settings[FEED_ENABLE_MICROSOFT] = wpiMicrosoftFeed.Checked.ToString(); settings[FEED_ENABLE_HELICON] = wpiHeliconTechFeed.Checked.ToString(); + */ + + settings[WSP.SystemSettings.FEED_ULS_KEY] = wpiEditFeedsList.Value; + string mainFeedUrl = txtMainFeedUrl.Text; + if (string.IsNullOrEmpty(mainFeedUrl)) + { + mainFeedUrl = WebPlatformInstaller.MAIN_FEED_URL; + } + settings[WSP.SystemSettings.WPI_MAIN_FEED_KEY] = mainFeedUrl; - result = ES.Services.System.SetSystemSettings( - WSP.SystemSettings.WPI_SETTINGS, settings); + result = ES.Services.System.SetSystemSettings(WSP.SystemSettings.WPI_SETTINGS, settings); if (result < 0) { diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx.designer.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx.designer.cs index ec0fcd8a..18d80e0f 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx.designer.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx.designer.cs @@ -130,15 +130,6 @@ namespace WebsitePanel.Portal { /// protected global::System.Web.UI.WebControls.Panel BackupPanel; - /// - /// Localize1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Localize Localize1; - /// /// txtBackupsPath control. /// @@ -167,22 +158,13 @@ namespace WebsitePanel.Portal { protected global::System.Web.UI.WebControls.Panel WpiPanel; /// - /// wpiMicrosoftFeed control. + /// txtMainFeedUrl control. /// /// /// Auto-generated field. /// To modify move field declaration from designer file to code-behind file. /// - protected global::System.Web.UI.WebControls.CheckBox wpiMicrosoftFeed; - - /// - /// wpiHeliconTechFeed control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.CheckBox wpiHeliconTechFeed; + protected global::System.Web.UI.WebControls.TextBox txtMainFeedUrl; /// /// wpiEditFeedsList control. From fc7eeb0df6f901b55b5cca24420707f4324386e7 Mon Sep 17 00:00:00 2001 From: ruslanht Date: Thu, 31 Jan 2013 16:35:29 +0200 Subject: [PATCH 7/9] WPI: load only main (Microsoft) feed if other feeds loading failed --- .../WebsitePanel.Server/Code/WPIHelper.cs | 95 +++++++++++++++---- .../ServersEditWebPlatformInstaller.ascx | 1 + 2 files changed, 79 insertions(+), 17 deletions(-) diff --git a/WebsitePanel/Sources/WebsitePanel.Server/Code/WPIHelper.cs b/WebsitePanel/Sources/WebsitePanel.Server/Code/WPIHelper.cs index 1976ea33..5ad0f643 100644 --- a/WebsitePanel/Sources/WebsitePanel.Server/Code/WPIHelper.cs +++ b/WebsitePanel/Sources/WebsitePanel.Server/Code/WPIHelper.cs @@ -55,7 +55,7 @@ namespace WebsitePanel.Server.Code #region private fields - private readonly List _feeds; + private List _feeds; private string _webPIinstallersFolder; private const string IisChoiceProduct = "StaticContent"; private const string WebMatrixChoiceProduct = "WebMatrix"; @@ -568,28 +568,89 @@ namespace WebsitePanel.Server.Code Directory.CreateDirectory(_webPIinstallersFolder); } - // load feeds - _productManager = new ProductManager(); - - - foreach (string feed in _feeds) - { - WriteLog(string.Format("Loading feed {0}", feed)); - if (feed.StartsWith("https://www.microsoft.com", StringComparison.OrdinalIgnoreCase)) - { - _productManager.Load(new Uri(feed), true, true, true, _webPIinstallersFolder); - } - else - { - _productManager.LoadExternalFile(new Uri(feed)); - } - } + LoadFeeds(); WriteLog(string.Format("{0} products loaded", _productManager.Products.Count)); //LogDebugInfo(); } + private void LoadFeeds() + { + if (null == _feeds || !_feeds.Any()) + { + throw new Exception("WpiHelper: no feeds provided"); + } + + _productManager = new ProductManager(); + + if (TryLoadFeeds()) + { + // ok, all feeds loaded + } + else + { + // feed loading failed + + if (_feeds.Count > 1) + { + // exclude feeds except first (default microsoft feed) + _feeds = new List {_feeds[0]}; + + // re-create product manager + _productManager = new ProductManager(); + if (TryLoadFeeds()) + { + // loaded first (default) feed only + } + else + { + throw new Exception(string.Format("WpiHelper: download all feeds failed")); + } + } + else + { + throw new Exception(string.Format("WpiHelper: download all feeds failed")); + } + } + } + + private bool TryLoadFeeds() + { + string loadingFeed = null; + + try + { + foreach (string feed in _feeds) + { + loadingFeed = feed; + WriteLog(string.Format("Loading feed {0}", feed)); + if (feed.IndexOf("microsoft.com", StringComparison.OrdinalIgnoreCase) > 0) + { + // it is internal Microsoft feed + _productManager.Load(new Uri(feed), true, true, true, _webPIinstallersFolder); + } + else + { + _productManager.LoadExternalFile(new Uri(feed)); + } + } + } + catch (Exception ex) + { + if (!string.IsNullOrEmpty(loadingFeed)) + { + // error occured on loading this feed + // log this + WriteLog(string.Format("Feed {0} loading error: {1}", loadingFeed, ex)); + + return false; + } + } + + return true; + } + private Language GetLanguage(string languageId) { if (!string.IsNullOrEmpty(languageId)) diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ServersEditWebPlatformInstaller.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ServersEditWebPlatformInstaller.ascx index 301eb036..9a656fa7 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ServersEditWebPlatformInstaller.ascx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ServersEditWebPlatformInstaller.ascx @@ -32,6 +32,7 @@ ul.WPIKeywordList { ul.WPIKeywordList>li { padding: .4em .4em; margin-right: .4em; + line-height: 2em; display: inline; list-style-type: none; } From a2102cd342c9038b3dc59ace38feaebf184ee8e3 Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Thu, 31 Jan 2013 10:29:02 -0500 Subject: [PATCH 8/9] Added tag build-2.1.0.32 for changeset 8d2b18c66dc4 From 1629c738695d990f93a95c7ef79224cdb6e37429 Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Thu, 31 Jan 2013 10:39:35 -0500 Subject: [PATCH 9/9] Added tag build-2.1.0.34 for changeset d39f7d552cb3