diff --git a/Src/A69WD/.vs/A69WD.csproj.dtbcache.json b/Src/A69WD/.vs/A69WD.csproj.dtbcache.json
index 754ebdc..8f64603 100644
--- a/Src/A69WD/.vs/A69WD.csproj.dtbcache.json
+++ b/Src/A69WD/.vs/A69WD.csproj.dtbcache.json
@@ -1 +1 @@
-{"RootPath":"C:\\Commesse\\_zPrivate\\A69WD\\Src\\A69WD","ProjectFileName":"A69WD.csproj","Configuration":"Debug|AnyCPU","FrameworkPath":"","Sources":[{"SourceFile":"App.cs"},{"SourceFile":"Data\\cNota.cs"},{"SourceFile":"Data\\cRac.cs"},{"SourceFile":"Data\\DBTools.cs"},{"SourceFile":"Data\\Helper.cs"},{"SourceFile":"General\\Navigator.cs"},{"SourceFile":"Net\\eLinkState.cs"},{"SourceFile":"Net\\cLink_A69.cs"},{"SourceFile":"Service\\Service_Crawler.cs"},{"SourceFile":"Service\\Service_Importer.cs"},{"SourceFile":"Site\\cSite_A69.cs"},{"SourceFile":"UI\\frmDownloader.cs"},{"SourceFile":"UI\\frmDownloader.Designer.cs"},{"SourceFile":"General\\Cfg.cs"},{"SourceFile":"General\\cTools.cs"},{"SourceFile":"General\\Logger.cs"},{"SourceFile":"Net\\iLink.cs"},{"SourceFile":"Properties\\AssemblyInfo.cs"},{"SourceFile":"Site\\iSiteType.cs"},{"SourceFile":"UI\\frmReader.cs"},{"SourceFile":"UI\\frmReader.Designer.cs"},{"SourceFile":"Properties\\Resources.Designer.cs"},{"SourceFile":"Properties\\Settings.Designer.cs"},{"SourceFile":"obj\\Debug\\.NETFramework,Version=v4.8.AssemblyAttributes.cs"}],"References":[{"Reference":"C:\\Commesse\\_zPrivate\\A69WD\\Src\\_Lib\\HtmlAgilityPack.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\Microsoft.CSharp.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\mscorlib.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Core.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Data.DataSetExtensions.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Data.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Commesse\\_zPrivate\\A69WD\\Src\\_Lib\\System.Data.SQLite.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Deployment.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Drawing.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Net.Http.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Windows.Forms.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Xml.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Xml.Linq.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""}],"Analyzers":[],"Outputs":[{"OutputItemFullPath":"C:\\Commesse\\_zPrivate\\A69WD\\Src\\A69WD\\bin\\Debug\\A69WD.exe","OutputItemRelativePath":"A69WD.exe"},{"OutputItemFullPath":"","OutputItemRelativePath":""}],"CopyToOutputEntries":[]}
\ No newline at end of file
+{"RootPath":"C:\\Commesse\\_zPrivate\\A69WD\\Src\\A69WD","ProjectFileName":"A69WD.csproj","Configuration":"Debug|AnyCPU","FrameworkPath":"","Sources":[{"SourceFile":"App.cs"},{"SourceFile":"Data\\cNota.cs"},{"SourceFile":"Data\\cRac.cs"},{"SourceFile":"Data\\DBTools.cs"},{"SourceFile":"Data\\Helper.cs"},{"SourceFile":"General\\Navigator.cs"},{"SourceFile":"Net\\eLinkState.cs"},{"SourceFile":"Net\\cLink_A69.cs"},{"SourceFile":"Service\\Service_Crawler.cs"},{"SourceFile":"Service\\Service_Importer.cs"},{"SourceFile":"General\\Cfg.cs"},{"SourceFile":"General\\cTools.cs"},{"SourceFile":"General\\Logger.cs"},{"SourceFile":"Net\\iLink.cs"},{"SourceFile":"Properties\\AssemblyInfo.cs"},{"SourceFile":"UI\\frmReader.cs"},{"SourceFile":"UI\\frmReader.Designer.cs"},{"SourceFile":"Properties\\Resources.Designer.cs"},{"SourceFile":"Properties\\Settings.Designer.cs"},{"SourceFile":"obj\\Debug\\.NETFramework,Version=v4.8.AssemblyAttributes.cs"}],"References":[{"Reference":"C:\\Commesse\\_zPrivate\\A69WD\\Src\\_Lib\\HtmlAgilityPack.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\Microsoft.CSharp.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\mscorlib.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Core.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Data.DataSetExtensions.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Data.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Commesse\\_zPrivate\\A69WD\\Src\\_Lib\\System.Data.SQLite.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Deployment.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Drawing.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Net.Http.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Windows.Forms.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Xml.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.8\\System.Xml.Linq.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""}],"Analyzers":[],"Outputs":[{"OutputItemFullPath":"C:\\Commesse\\_zPrivate\\A69WD\\Src\\A69WD\\bin\\Debug\\A69WD.exe","OutputItemRelativePath":"A69WD.exe"},{"OutputItemFullPath":"","OutputItemRelativePath":""}],"CopyToOutputEntries":[]}
\ No newline at end of file
diff --git a/Src/A69WD/A69WD.csproj b/Src/A69WD/A69WD.csproj
index 3e8851e..a012960 100644
--- a/Src/A69WD/A69WD.csproj
+++ b/Src/A69WD/A69WD.csproj
@@ -64,6 +64,7 @@
+
diff --git a/Src/A69WD/Net/cLink_A69.cs b/Src/A69WD/Net/cLink_A69.cs
index b7337ea..45afd91 100644
--- a/Src/A69WD/Net/cLink_A69.cs
+++ b/Src/A69WD/Net/cLink_A69.cs
@@ -45,7 +45,7 @@ namespace A69WD.Net {
return !App.DB.IsPresent(URL);
}
}
- }
+ }
public eLinkState Status { get => status; set { status = value; } }
@@ -87,7 +87,7 @@ namespace A69WD.Net {
return false;
}
}
-
+
public static bool InsertStartLink(Service_Crawler service) {
//string url = LinkIdxBase.Replace("{Categoria}", "altro").Replace("{ID}", "1"); //LinkIdxBase.Replace("{Categoria}", "trio").Replace("{ID}", "1");
@@ -176,7 +176,7 @@ namespace A69WD.Net {
rac.Title = cTools.FormattaTesto(nodes[0].InnerText.Trim(), false);
if (string.IsNullOrEmpty(rac.Title)) {
Logger.Error($"A69 - Import - No Title - {filePathName}");
- return null;
+ return null;
}
} catch (Exception ex) { Logger.Error(string.Format("Fallita estrazione titolo dal file {0}\r\n{1}", FileName, ex.Message)); return null; }
#endregion
@@ -224,7 +224,7 @@ namespace A69WD.Net {
if (parts.Length == 3) {
CultureInfo culture = CultureInfo.CreateSpecificCulture("it-IT");
DateTimeStyles styles = DateTimeStyles.None;
- DateTime tmpDT = DateTime.Now;
+ DateTime tmpDT = DateTime.Now;
if (!DateTime.TryParse(parts[0].Trim(), culture, styles, out tmpDT)) {
Logger.Error($"A69 - Import - No data - {filePathName}");
}
@@ -764,7 +764,7 @@ namespace A69WD.Net {
try {
#region 1) Prepare HTML Client
-
+
HttpClientHandler _handler = new HttpClientHandler {
CookieContainer = new CookieContainer(),
UseCookies = true,
@@ -776,7 +776,7 @@ namespace A69WD.Net {
client.Timeout = TimeSpan.FromSeconds(60);
client.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
client.DefaultRequestHeaders.Referrer = new Uri(cLink_A69.LoginPageUrl);
-
+
#endregion
#region 2) GET pagina di login
@@ -784,7 +784,7 @@ namespace A69WD.Net {
Console.WriteLine("A69 - Richiedo la pagina di login...");
Logger.Information("A69 - Richiedo la pagina di login...");
string loginPageHtml = await client.GetStringAsync(cLink_A69.LoginPageUrl);
-
+
#endregion
#region 3) Parsing HTML per estrarre ts e token
diff --git a/Src/A69WD/Net/cLink_eRac.cs b/Src/A69WD/Net/cLink_eRac.cs
new file mode 100644
index 0000000..91a8298
--- /dev/null
+++ b/Src/A69WD/Net/cLink_eRac.cs
@@ -0,0 +1,654 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+using A69WD.Data;
+using A69WD.Service;
+using HtmlAgilityPack;
+using System.Globalization;
+using System.Xml.Serialization;
+
+
+
+namespace A69WD.Net {
+
+ public class cLink_eRac : iLink {
+
+ private readonly string filename;
+ private readonly string filepath;
+ private eLinkState status = eLinkState.ToConfirm;
+ private string fields = "";
+
+ public static string PageBase { get { return "https://www.eroticiracconti.it"; } }
+
+ public static string LinkIdxBase { get { return "https://www.eroticiracconti.it/archivio/Tutto/{ID}"; } }
+ public static string LinkRacBase { get { return "https://www.eroticiracconti.it/racconto/{RacID}"; } }
+
+ public string ID => "eRac";
+
+ public string URL { get; }
+
+ public string FileName => filename;
+
+ public string FilePath { get => filepath; }
+
+ public bool Validate {
+ get {
+ if (URL.StartsWith("https://www.eroticiracconti.it/archivio/Tutto/")) {
+ // URL di tipo Idx, devo lavorare i link nuovo o rilavorare i link più obsoleti di 6 ore.
+ return !App.DB.IsPresent(URL, -6);
+ } else {
+ // URL di tipo Rac, devo lavorare solo i link nuovi
+ return !App.DB.IsPresent(URL);
+ }
+ }
+ }
+
+ public eLinkState Status { get => status; set { status = value; } }
+
+ public string Fields { get => fields; set => fields = value; }
+
+ public cLink_eRac(string Url, string Filename, string fields = "none", string Filepath = "") {
+ this.URL = Url;
+ this.filename = Filename;
+ this.fields = fields;
+ this.filepath = string.IsNullOrEmpty(Filepath) ? Cfg.Settings.PathDownloadWorking : Filepath;
+ this.status = eLinkState.ToConfirm;
+ }
+
+
+ public static bool InsertStartLink(Service_Crawler service) {
+ try {
+ int i = 0;
+ string url = LinkIdxBase.Replace("{ID}", i.ToString());
+ string name = $"_eRac_Idx_{i.ToString("0000")}.html";
+ service.EnqueueUrl(new cLink_eRac(url, name));
+ return true;
+ } catch (Exception ex) {
+ Logger.Error("Errore inserendo eRac Start Link - " + ex.Message);
+ return false;
+ }
+ }
+
+
+ public cRac EstraiRac(HtmlDocument doc) {
+ /*
+ * Analisi html dei racconti aggiornata al 2025/12/27:
+ *
+ *
+ * Per ciascun file html, si ha un unico racconto che ha un formato interno pari a:
+ *
+ *
+ *
+ * ...
+ * Quante voglie. | Erotici Racconti
+ *
+ *
+ *
+ *
+ *
+ *
{Title}
+ *
+ *
+ *
+ *
+ * di
+ * {Autor}
+ *
+ *
+ *
+ * genere
+ * {Genere}
+ *
+ *
+ *
+ *
+ * {Trama}
+ *
+ *
+ *
+ *
+ *
+ * scritto il
+ * {Data}
+ *
+ *
+ *
+ * 5.1K
+ *
+ * visite
+ *
+ *
+ *
+ *
+ *
+ *
+ * 3
+ *
+ * voti
+ *
+ *
+ *
+ * valutazione
+ *
2
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * il tuo voto
+ *
+ *
+ *
+ * ...
+ *
+ * ...
+ *
+ * ...
+ *
+ *
+ *
+ *
+ * quindi i dati del racconto che si possono estrapolare sono:
+ * Titolo: --> Testo del nodo {Title}
+ * SubTitle: --> Sempre Vuoto
+ * Autore: --> Testo del nodo
+ * Creato: --> Estrarre la parte dal
+ * Tags: --> Testo del nodo
+ * Trama: --> Testo del nodo
+ * Notes: --> SrcFile - Nome del file che si analizza
+ * Origini: --> Sempre l'ID della sorgente web
+ * Voto: --> Sempre "Non Letto"
+ * Updated: --> Data attuale
+ *
+ */
+ cRac rac = new cRac();
+ HtmlNodeCollection nodes;
+ try {
+ Console.WriteLine($"eRac - Importo: {FileName}");
+
+ // Ricavo il nodo radice del racconto:
+ //HtmlNode root = doc.DocumentNode;
+ HtmlNode root = doc.DocumentNode.SelectSingleNode("//div[@class='story']");
+
+ if (root == null) {
+ // racconto non presente
+ return null;
+ }
+
+ #region Origini: --> Sempre l'ID della sorgente web
+ rac.Origini = new List
{ ID };
+ #endregion
+
+ #region Titolo: --> Testo del nodo {Title}
+ try {
+ nodes = root.SelectNodes("//h1[@class='tit']");
+ rac.Title = cTools.FormattaTesto(nodes[0].InnerText.Trim(), false);
+ if (string.IsNullOrEmpty(rac.Title)) {
+ Logger.Error($"eRac - Import - No Title - {FileName}");
+ return null;
+ }
+ } catch (Exception ex) { Logger.Error(string.Format("Fallita estrazione titolo dal file {0}\r\n{1}", FileName, ex.Message)); return null; }
+ #endregion
+
+ #region SubTitle: --> Sempre Vuoto
+ rac.SubTitle = "";
+ #endregion
+
+ #region Autore: --> Testo del nodo
+ try {
+ //nodes = root.SelectNodes("//h2//span[@class='infos']//span[]//a");
+ nodes = root.SelectNodes("//a[@rel='author']");
+ List items = new List();
+ foreach (HtmlNode nd in nodes) {
+ string aut = nd.ParentNode.InnerText.Replace(" ", "").Trim();
+ if (aut.StartsWith("di")) {
+ items.Add(aut.Replace("di", "").Trim());
+ }
+ }
+ items.Sort();
+ string tmp = "";
+ rac.Autori = new List();
+ // Rimuovo eventuali duplicati
+ foreach (string aut in items) {
+ if (tmp != aut) {
+ rac.Autori.Add(aut);
+ tmp = aut;
+ }
+ }
+ if (rac.Autori == null || string.IsNullOrEmpty(rac.Autori[0])) {
+ Logger.Error($"eRac - Import - No Autors - {FileName}");
+ return null;
+ }
+ } catch (Exception ex) { Logger.Error(string.Format("Fallita estrazione autore dal file {0}\r\n{1}", FileName, ex.Message)); return null; }
+ #endregion
+
+ #region Creato: --> Estrarre la parte dal
+ rac.Creato = DateTime.Now;
+ try {
+ // Creato --> Estrarre la prima parte dal
+ nodes = root.SelectNodes("//div[@class='infos']//div");
+ foreach (HtmlNode nd in nodes) {
+ string txt = nd.InnerText.Trim().Replace(" ", "");
+ if (txt.StartsWith("scritto il")) {
+ CultureInfo culture = CultureInfo.CreateSpecificCulture("it-IT");
+ DateTimeStyles styles = DateTimeStyles.None;
+ DateTime tmpDT = DateTime.Now;
+ if (!DateTime.TryParse(txt.Replace("scritto il", "").Trim(), culture, styles, out tmpDT)) {
+ Logger.Error($"eRac - Import - No data - {FileName}");
+ }
+ rac.Creato = tmpDT;
+ break;
+ }
+ }
+ } catch (Exception ex) { Logger.Warning(string.Format("Data non riconosciuta nel file {0}\r\n{1}", FileName, ex.Message)); return null; }
+ #endregion
+
+ #region Updated: --> Data attuale
+ rac.Updated = DateTime.Now;
+ #endregion
+
+ #region Tags: --> Testo del nodo
+ try {
+ //nodes = root.SelectNodes("//h2//span[@class='infos']//span//a");
+ nodes = root.SelectNodes("//h2//span[@class='infos']//span");
+ List
items = new List();
+ foreach (HtmlNode nd in nodes) {
+ string txt = nd.InnerText.Trim();
+ if (txt.StartsWith("genere")) {
+ items.Add(cTools.FormattaTesto(txt.Replace("genere", "").Trim(), false));
+ }
+ }
+ //items.Sort();
+ items = items
+ .OrderBy(s => s) // ordina alfabeticamente
+ .Distinct() // elimina duplicati
+ .ToList();
+ Format_Insert_Tags(rac, items); // rac.Tags = items;
+ } catch (Exception ex) { Logger.Warning(string.Format("Fallita estrazione Tags dal file {0}\r\n{1}", FileName, ex.Message)); return null; }
+ #endregion
+
+ #region Trama: --> Testo del nodo a cui si levano i DIV interni.
+ try {
+ nodes = root.SelectNodes("//div[@class='tes']");
+ foreach (HtmlNode nd in nodes) {
+ foreach (HtmlNode n in nd.ChildNodes) {
+ if (n.Name.ToUpper() == "#TEXT") { rac.Trama += cTools.FormattaTesto(n.InnerText.Trim(), false); }
+ if (n.Name.ToUpper() == "BR") { rac.Trama += "\r"; }
+ if (n.Name.ToUpper() == "DIV") {; }
+ }
+ }
+ } catch (Exception ex) { Logger.Error(string.Format("Fallita estrazione Trama dal file {0}\r\n{1}", FileName, ex.Message)); return null; }
+ #endregion
+
+ #region Voto: --> Sempre "Non Letto"
+ rac.Voto = "Non Letto";
+ #endregion
+
+ #region Notes: --> SrcFile - Nome del file che si analizza
+ rac.Notes = new List
();
+ rac.Notes.Add(new Data.cNota("SrcFile", System.IO.Path.GetFileName(FileName)));
+ #endregion
+
+ // Formalizzo esito estrazione:
+ if (!rac.Validate()) {
+ rac = null;
+ }
+
+ } catch (Exception ex) {
+ Logger.Error($"eRac - Import Error - {FileName}: {ex.Message}");
+ Console.WriteLine($"eRac - Import Error - {FileName}: {ex.Message}");
+ return null;
+ }
+ return rac;
+ }
+
+
+
+
+ protected virtual void Format_Insert_Tags(Data.cRac rac, List items) {
+ // Per ora riporto tutti i tag rilevati, mentre in futuro dovrò:
+ // - parsare la lista e formattare correttamente i tag
+ // - ordinare la lista dei tag formattati ed eliminare i duplicati
+ // - se non sono rimasti tag, inserisco il tag generale per indicare che non vi sono tag
+ // - altrimenti inserisco tutti i tag rimasti.
+ rac.Tags = new List();
+ try {
+ items.Sort();
+ string tmp = "";
+ foreach (string item in items) {
+ string it = item.Trim().ToLower();
+ if (tmp != it) {
+ #region switch per formattare il testo
+ switch (it) {
+ //case "Gay & Bisex":
+ // rac.Tags.Add("Bisex");
+ // rac.Tags.Add("Gay");
+ // break;
+ //case "tradimenti":
+ // rac.Tags.Add("Tradimenti");
+ // break;
+ //case "Lui & Lei":
+ // rac.Tags.Add("Lui & Lei");
+ // break;
+ //case "trans":
+ // rac.Tags.Add("Trans");
+ // break;
+ //case "Prime Esperienze":
+ // rac.Tags.Add("Prime Esperienze");
+ // break;
+ //case "trio":
+ // rac.Tags.Add("Trio");
+ // break;
+ //case "incesto":
+ // rac.Tags.Add("Incesto");
+ // break;
+ //case "orge":
+ // rac.Tags.Add("Orge");
+ // break;
+ //case "bdsm":
+ // rac.Tags.Add("BDSM");
+ // break;
+ //case "lesbo":
+ // rac.Tags.Add("Lesbo");
+ // break;
+ //case "Scambio di Coppia":
+ // rac.Tags.Add("Scambio di Coppia");
+ // break;
+ default:
+ rac.Tags.Add(item);
+ break;
+ }
+ #endregion
+ tmp = it;
+
+ }//if
+
+ }//foreach
+
+ } catch (Exception ex) {
+ Logger.Error(string.Format("Error Code: {0} - Errore in {1}.{2}: {3}", "ER00040", System.Reflection.MethodInfo.GetCurrentMethod().DeclaringType.FullName, System.Reflection.MethodInfo.GetCurrentMethod().Name, ex.Message));
+ } finally {
+ if (rac.Tags.Count == 0) rac.Tags.Add("_None_");
+ }
+ }//function
+
+
+ #region Gestione Sito eRac
+
+ private static HttpClient client = null;
+ private static bool autenticated = false;
+
+ ///
+ /// Indica se siamo autenticati al sito
+ ///
+ public static bool Autenticated => autenticated;
+
+
+ ///
+ /// Esegue l'autenticazione al sito:
+ /// - Scarica la pagina di autenticazione
+ /// - analizza quanto scaricato per determinare i campi dinamici 'ts' e 'token'
+ /// - prepara la risposta al form di identificazione
+ /// - invia il POST di autenticazione
+ /// - analizza la risposta per verificare il corretto login
+ ///
+ public static async Task Authenticate() {
+ if (autenticated) {
+ // Autenticazione già fatta, posso proseguire senza altro fare
+ Logger.Warning("eRac - Autenticazione già effettuata.");
+ }
+ try {
+
+ #region 1) Prepare HTML Client
+
+ HttpClientHandler _handler = new HttpClientHandler {
+ CookieContainer = new CookieContainer(),
+ UseCookies = true,
+ AllowAutoRedirect = true,
+ AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
+ };
+
+ client = new HttpClient(_handler);
+ client.Timeout = TimeSpan.FromSeconds(60);
+ client.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
+ client.DefaultRequestHeaders.Referrer = new Uri(cLink_eRac.PageBase);
+
+ #endregion
+
+ autenticated = true;
+
+ } catch (Exception ex) {
+ Console.WriteLine($"Errore generale: {ex.Message}");
+ Logger.Information($"Errore generale: {ex.Message}");
+ }
+ return autenticated;
+ }
+
+
+ ///
+ /// Codice da eseguire per ciascun eRac link:
+ /// - scarico l'url indicato
+ /// - se richiesto lo salvo come file di testo
+ /// - analizzo il documento html ed estraggo tutti gli url ad altre pagine di link
+ /// - analizzo il documento html ed estraggo tutti gli url a racconti
+ /// - analizzo il documento html ed estraggo il testo del racconto
+ ///
+ ///
+ ///
+ public async Task> CrawlPageAsync() {
+ var newlinks = new List();
+
+ try {
+ Console.WriteLine($"eRac - Scarico: {URL}");
+ HtmlDocument tdoc = null;
+ string thtml = "";
+
+ #region ToConfirm
+ if (Status == eLinkState.ToConfirm) {
+ // Eseguo la verifica se link da downloadare
+ Status = eLinkState.ToDownload;
+ }
+ #endregion
+
+ #region ToDownload
+ if (Status == eLinkState.ToDownload) {
+ Status = eLinkState.OnDownload;
+ }
+ #endregion
+
+ #region OnDownload
+ if (Status == eLinkState.OnDownload) {
+ // Scarico il file
+ var resp = await client.GetAsync(URL);
+ if (!resp.IsSuccessStatusCode) {
+ Console.WriteLine($"eRac - Errore HTTP {(int)resp.StatusCode} {resp.ReasonPhrase} per {URL}");
+ Status = eLinkState.Error;
+ //App.DB.LinkLog(lk);
+ return newlinks;
+ }
+ // Scarico la pagina
+ thtml = await client.GetStringAsync(URL);
+ tdoc = new HtmlDocument();
+ tdoc.LoadHtml(thtml);
+ // Salvo il file downloadato
+ //SaveToFile(thtml, lk.FilePath, lk.FileName);
+
+ Status = eLinkState.ToAnalize;
+ }
+ #endregion
+
+ #region ToAnalize
+ {
+ if (Status == eLinkState.ToAnalize) {
+ List tmpLk = new List();
+
+ #region Estraggo gli url ad indici:
+ {
+ /*
+ * Gli url delle pagine di indice sono del tipo:
+ *
+ *
+ *
+ */
+ try {
+ // Estraggo i link alle altre pagine:
+ var tnodes = tdoc.DocumentNode.SelectNodes("//div[@class='pagination']//a[@href]");
+ if (tnodes != null) {
+ foreach (var link in tnodes) {
+ var href = link.GetAttributeValue("href", "");
+ if (!string.IsNullOrEmpty(href) && href.StartsWith("/archivio/Tutto/"))
+ tmpLk.Add(href); //tmpLk.Add(cLink_eRac.PageBase + href);
+ }
+ }
+ // Rimuove duplicati e ordina alfabeticamente
+ tmpLk = tmpLk
+ .OrderBy(s => s) // ordina alfabeticamente
+ .Distinct() // elimina duplicati
+ .ToList();
+ // Inserisco i link trovati
+ foreach (string ilk in tmpLk) {
+ string url = cLink_eRac.PageBase + ilk;
+ int offset = int.Parse(ilk.Replace("/archivio/Tutto/", ""));
+ string name = $"_eRac_Idx_{offset.ToString("0000")}.html";
+ newlinks.Add(new cLink_eRac(url, name));
+ }
+ } catch (Exception ex) {
+ Logger.Error("Errore analisi Idx link dal " + FileName + " - " + ex.Message);
+ cTools.SaveToFile(thtml, Cfg.Settings.PathSrcErrOnExtract, FileName);
+ }
+ }
+ #endregion
+
+ #region Estraggo gli url a racconti:
+ {
+ /*
+ *
+ * I link ai racconti sono dei pulsanti così formati:
+ *
+ *
+ */
+ try {
+ // Estraggo i link ai racconti:
+ tmpLk = new List();
+ // Estraggo i link alle altre pagine:
+ var tnodes = tdoc.DocumentNode.SelectNodes("//a[@class='rac']");
+ if (tnodes != null) {
+ foreach (var link in tnodes) {
+ var href = link.GetAttributeValue("href", "");
+ if (!string.IsNullOrEmpty(href) && href.StartsWith("/racconto/"))
+ tmpLk.Add(href); //tmpLk.Add(cLink_eRac.PageBase + href);
+ }
+ }
+ // Rimuove duplicati e ordina alfabeticamente
+ tmpLk = tmpLk
+ .OrderBy(s => s) // ordina alfabeticamente
+ .Distinct() // elimina duplicati
+ .ToList();
+ // Inserisco i link trovati
+ foreach (string ilk in tmpLk) {
+ string url = cLink_eRac.PageBase + ilk;
+ string name = ilk.Replace("/racconto/", "eRac_").Replace(@"/", "_") + ".html";
+ newlinks.Add(new cLink_eRac(url, name));
+ }
+ } catch (Exception ex) {
+ Logger.Error("Errore analisi Idx link dal " + FileName + " - " + ex.Message);
+ cTools.SaveToFile(thtml, Cfg.Settings.PathSrcErrOnExtract, FileName);
+ }
+ }
+ #endregion
+
+ #region Estraggo il racconto dal file e lo inserisco nel DB
+ if (FileName.StartsWith("eRac_")) {
+ // Link ad un racconto
+ cRac rac = EstraiRac(tdoc);
+ if (rac != null) {
+ // Racconto estratto correttamente, lo salvo sul DB
+ int res = App.DB.ImportRac(rac);
+ if (res > 0) {
+ // Racconto salvato correttamente sul DB
+ cTools.SaveToFile(thtml, Cfg.Settings.PathSrcDone, FileName);
+ } else {
+ // Errore nel salvataggio sul DB
+ cTools.SaveToFile(thtml, Cfg.Settings.PathSrcErrOnSave, FileName);
+ }
+ } else {
+ // Estrazione del racconto fallita
+ cTools.SaveToFile(thtml, Cfg.Settings.PathSrcErrOnExtract, FileName);
+ }
+ } else {
+ // Link ad un indice
+ cTools.SaveToFile(thtml, Cfg.Settings.PathIdxDone, FileName);
+ }
+ #endregion
+
+ Status = eLinkState.End;
+ App.DB.LinkLog(this);
+ }
+ }
+ #endregion
+
+ #region End
+ if (Status == eLinkState.End) {
+ }
+ #endregion
+
+ #region Error
+ if (Status == eLinkState.Error) {
+ }
+ #endregion
+
+ #region Abort
+ if (Status == eLinkState.Abort) {
+ }
+ #endregion
+
+ #region Cancel
+ if (Status == eLinkState.Cancel) {
+ }
+ #endregion
+
+ Console.WriteLine("Link.Count=" + newlinks.Count.ToString("00"));
+
+ } catch (Exception ex) {
+ Console.WriteLine($"Errore con {URL}: {ex.Message}");
+ Status = eLinkState.Error;
+ App.DB.LinkLog(this);
+ }
+ return newlinks;
+ }
+
+ #endregion
+
+
+ }//class cLink_eRac
+
+}//namespace A69WD.Net
diff --git a/Src/A69WD/Properties/AssemblyInfo.cs b/Src/A69WD/Properties/AssemblyInfo.cs
index 25d85c1..3a476fb 100644
--- a/Src/A69WD/Properties/AssemblyInfo.cs
+++ b/Src/A69WD/Properties/AssemblyInfo.cs
@@ -32,8 +32,24 @@ using System.Runtime.InteropServices;
// È possibile specificare tutti i valori oppure impostare valori predefiniti per i numeri relativi alla revisione e alla build
// usando l'asterisco '*' come illustrato di seguito:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.5.2.0")]
-[assembly: AssemblyFileVersion("0.5.2.0")]
+[assembly: AssemblyVersion("0.5.3.0")]
+[assembly: AssemblyFileVersion("0.5.3.0")]
+
+
+/*
+ *
+ * Vrs 0.5.3.0
+ *
+ * Compilata da CSiCoAlm il 2026/01/02
+ * Inserito nello skraping anche la sorgente eRac
+ *
+ *
+ * ToDo:
+ * - Aggiungere gestione parallela della FIFO secondo vecchi modello per aumentare il feedback alla UI
+ * - Inserire anche l'estrazione dei racconti
+ * - Inserire funzionalità avanzate sul lettore
+ *
+ */
/*
diff --git a/Src/A69WD/Service/Service_Crawler.cs b/Src/A69WD/Service/Service_Crawler.cs
index daaaf42..c1ca6b1 100644
--- a/Src/A69WD/Service/Service_Crawler.cs
+++ b/Src/A69WD/Service/Service_Crawler.cs
@@ -76,6 +76,7 @@ namespace A69WD.Service {
// Autenticazione ai siti:
if (!cLink_A69.Autenticated) { await cLink_A69.Authenticate(); }
+ if (!cLink_eRac.Autenticated) { await cLink_eRac.Authenticate(); }
// Ciclo per ciascun elemento della FIFO:
foreach (iLink link in _urlQueue.GetConsumingEnumerable()) {
@@ -87,8 +88,16 @@ namespace A69WD.Service {
await _semaphore.WaitAsync();
try {
- cLink_A69 clk = link as cLink_A69;
- List urls = await clk.CrawlPageAsync();
+ List urls = null;
+ if (link is cLink_A69) {
+ cLink_A69 clk = link as cLink_A69;
+ urls = await clk.CrawlPageAsync();
+ } else {
+ if (link is cLink_eRac) {
+ cLink_eRac clk = link as cLink_eRac;
+ urls = await clk.CrawlPageAsync();
+ }
+ }
Logger.Information("ProcessQueue: end url " + link.FileName + " - URL trovati: " + urls.Count.ToString("000"));
foreach (iLink url in urls) {
if (url.Validate) {
diff --git a/Src/A69WD/UI/frmReader.cs b/Src/A69WD/UI/frmReader.cs
index 9014c2e..6a31982 100644
--- a/Src/A69WD/UI/frmReader.cs
+++ b/Src/A69WD/UI/frmReader.cs
@@ -684,7 +684,13 @@ namespace A69WD.UI {
// Preparo il servizio
serviceCrawler = new Service_Crawler(sb);
// Inserisco i link iniziali nella coda
+ if (!cLink_eRac.InsertStartLink(serviceCrawler)) {
+ Logger.Warning("eRac - Insert start link Fault");
+ sbStatusLabel.Text = "eRac fault.";
+ return;
+ }
if (!cLink_A69.InsertStartLink(serviceCrawler)) {
+ Logger.Warning("A69 - Insert start link Fault");
sbStatusLabel.Text = "A69 fault.";
return;
}
@@ -735,8 +741,28 @@ namespace A69WD.UI {
}
private void btnTest1_Click(object sender, EventArgs e) {
- // Test download multipli con sempre lo stesso client per condividere la sessione
- ;
+ // Test skraping eRac
+
+
+ // - Verifico path per il download
+ if (!System.IO.Directory.Exists(Cfg.Settings.PathDownloadWorking)) System.IO.Directory.CreateDirectory(Cfg.Settings.PathDownloadWorking);
+
+ // Preparo il servizio
+ serviceCrawler = new Service_Crawler(sb);
+ // Inserisco i link iniziali nella coda
+ if (!cLink_eRac.InsertStartLink(serviceCrawler)) {
+ Logger.Warning("eRac - Insert start link Fault");
+ sbStatusLabel.Text = "eRac fault.";
+ return;
+ }
+
+ //// Inserisco link di un racconto:
+ //string url = "https://www.eroticiracconti.it/racconto/105286-nicole-gis-il-culto-della-terza-notte"; // "https://www.eroticiracconti.it/racconto/112763-elara-capitolo-2-il-cambiamento";
+ //string name = "eRac_112763-elara-capitolo-2-il-cambiamento.html";
+ //serviceCrawler.EnqueueUrl(new cLink_eRac(url, name));
+
+ // avvio il servizio
+ serviceCrawler.StartWorker();
}