Using System;
Using System. Collections. Generic;
Using System. Linq;
Using System. Text;
Using System. IO;
Using System. Web;
Using System. Threading;
/// <Summary>
/// Class used to generate the product detail page
/// </Summary>
Public class ProductHtmlCreate
{
/// <Summary>
/// Folder path for storing static product files, which is set to the absolute path of the disk in Application_Start event
/// </Summary>
Public static string ProductFolder = "~ /Pro /";
/// <Summary>
/// Generate a static file based on the product ID
/// </Summary>
/// <Param name = "pid"> item ID </param>
/// <Param name = "productUrl"> absolute Url of the product page </param>
/// <Param name = "useProTypeFolder"> whether to store Static Page folders based on the product type. If this parameter is set to true, static page folders are stored based on the product type, otherwise, use ProductHtmlCreate. folder specified by ProductFolder </param>
Public static void CreateHtml (ProductHtmlSaveConfig config, string productUrl, bool useProTypeFolder)
{
// Obtain HTML
String html = MySpider. GetResponseText (string. Format (productUrl + "? Pid = {0} ", config. ProductID), null );
// Folder path for storing static HTML files
String folderPath = ProductFolder;
If (useProTypeFolder)
{
FolderPath = GetFolderByProType (config. TypeID );
If (! Directory. Exists (folderPath ))
{
Directory. CreateDirectory (folderPath );
}
}
// Local path of the static file
String filePath = folderPath + config. ProductID + ". html ";
Var model = AppCache. Product. GetProduct (int. Parse (config. ProductID ));
If (model! = Null)
{
// If a static file already exists, delete it.
If (! String. IsNullOrEmpty (model. HtmlPath ))
{
String oldFilePath = HttpRuntime. AppDomainAppPath + model. HtmlPath. Substring (1). Replace ('/','\\');
If (File. Exists (oldFilePath ))
{
File. Delete (oldFilePath );
}
}
}
// Update the path of the static file to the database
AppCache. product. setHtmlPath (int. parse (config. productID), "/" + filePath. toLower (). substring (HttpRuntime. appDomainAppPath. length ). replace ('\\','/'));
// Replace all href with the correct relative path
Html = RegexCollection. RegHref. Replace (html, (mat) =>
{
Return "href =" + mat. Groups [1]. Value + GetHref (productUrl, mat. Groups [2]. Value) + mat. Groups [1]. Value;
});
// Replace all src with the correct relative path
Html = RegexCollection. RegSrc. Replace (html, (mat) =>
{
Return "src =" + mat. Groups [1]. Value + GetHref (productUrl, mat. Groups [2]. Value) + mat. Groups [1]. Value;
});
// Generate static files
Using (StreamWriter writer = new StreamWriter (filePath, false, Encoding. UTF8 ))
{
Writer. Write (html );
}
}
/// <Summary>
/// Generate static pages of commodity detail pages in batches from a collection of commodity types
/// </Summary>
/// <Param name = "arr"> item information configuration set </param>
/// <Param name = "productUrl"> absolute product page url </param>
/// <Param name = "isAsyn"> whether to use Asynchronization </param>
/// <Param name = "act"> delegate called after asynchronous termination </param>
/// <Param name = "useProTypeFolder"> whether to select a storage folder based on the product type </param>
Public static void CreateHtmlList (IEnumerable <ProductHtmlSaveConfig> arr, string productUrl, bool isAsyn, Action <int, int> act, bool useProTypeFolder)
{
If (isAsyn)
{
Action asynAct = () =>
{
Int successCount = 0;
Foreach (var item in arr)
{
Try
{
CreateHtml (item, productUrl, useProTypeFolder );
// If an html file is not successfully generated, successCount auto-Increment
SuccessCount ++;
}
Catch (Exception ex)
{
}
}
If (act! = Null)
{
Act (arr. Count (), successCount );
}
};
AsynAct. BeginInvoke (new AsyncCallback (
Isr => (Action) isr. AsyncState). EndInvoke (isr)
), AsynAct );
}
Else
{
Foreach (var item in arr)
{
CreateHtml (item, productUrl, useProTypeFolder );
}
}
}
/// <Summary>
/// Generate an absolute url address for referencing resources based on the page url and resource url
/// </Summary>
/// <Param name = "currentUrl"> url of the page </param>
/// <Param name = "href"> resource url </param>
/// <Returns> </returns>
Public static string GetHref (string currentUrl, string href)
{
Href = href. Trim (). ToLower ();
// If JS is called in href, the current JS call is returned.
If (href. StartsWith ("javascript "))
{
Return href;
}
String scheme = "";
If (href. Length> 5)
{
Scheme = href. Substring (0, 6). ToLower ();
}
// If it starts with http, return directly
If (scheme. StartsWith ("http:") | href. StartsWith ("https :"))
{
Return href;
}
Uri uri = new Uri (currentUrl );
// Get, domain name plus port number, similar to http://a.com: 789
String start = uri. Scheme + ": //" + uri. Authority;
// If href uses an absolute path, the absolute path is directly returned.
If (href. StartsWith ("/"))
{
Return href;
} // If href uses relative paths such ../
Else if (href. StartsWith ("../"))
{
Int count = 0;
Int index = 0;
While ('.' = href [index] & '.' = href [index + 1] & '/' = href [index + 2])
{
Count ++;
Index + = 3;
}
For (int I = 0; I <uri. Segments. Length-1-count; I ++)
{
Start + = uri. Segments [I];
}
Start + = href. Substring (index );
// Returns the absolute path of the resource.
Return new Uri (start). AbsolutePath;
} // If the href and the current path are in the same directory
Else
{
// If currentUrl is similar to a http://aa.com or a class like http://aa.com/aa/, the last string in uri.segmentsshould also be included
For (int I = 0; I <(uri. Segments [uri. Segments. Length-1]. EndsWith ("/")? Uri. Segments. Length: uri. Segments. Length-1); I ++)
{
Start + = uri. Segments [I];
}
Start + = href;
// Returns the absolute path of the resource.
Return new Uri (start). AbsolutePath;
}
}
/// <Summary>
/// Obtain the complete directory saved on the Static Page of the product based on the product type ID
/// </Summary>
/// <Param name = "typeId"> </param>
/// <Returns> </returns>
Public static string GetFolderByProType (string typeId)
{
// If no product category is used, the top-level directory that stores the static page of the product is returned.
If (typeId = "0 ")
{
Return ProductFolder;
}
Var list = MyCache. GetCache <Dictionary <string, ProType> (CacheConfigList. AllProType. Name, CacheConfigList. AllProType. Func, CacheConfigList. AllProType. TimeSpan );
StringBuilder sb = new StringBuilder (50 );
Sb. Append (ProductFolder );
Int index = sb. Length;
// Recursive product type
While (list. ContainsKey (typeId ))
{
Sb. Insert (index, list [typeId]. ImgFolderName );
Index + = list [typeId]. ImgFolderName. Length;
Sb. Insert (index ,'\\');
TypeId = list [typeId]. FatherID. ToString ();
}
Return sb. ToString ();
}
}
/// <Summary>
/// Parameters required to save the static page of a product
/// </Summary>
Public class ProductHtmlSaveConfig
{
Public string ProductID {get; set ;}
Public string TypeID {get; set ;}
}