diff --git a/Src/A69WD/A69WD.csproj b/Src/A69WD/A69WD.csproj index e824ec6..3e8851e 100644 --- a/Src/A69WD/A69WD.csproj +++ b/Src/A69WD/A69WD.csproj @@ -68,13 +68,11 @@ - - Form diff --git a/Src/A69WD/Data/DBTools.cs b/Src/A69WD/Data/DBTools.cs index e73bf57..3a2f511 100644 --- a/Src/A69WD/Data/DBTools.cs +++ b/Src/A69WD/Data/DBTools.cs @@ -1075,7 +1075,7 @@ namespace A69WD { /// Importa il racconto passato sul DB /// /// Racconto d aimportare - /// 1 se tutto ok, -1 se importazione abortita per errore, -10 se importazione abortita per duplicato, .... + /// IDrac se tutto ok, -1 se importazione abortita per errore, -10 se importazione abortita per duplicato, .... public int ImportRac(cRac rac) { lock (objLock) { // Inizializzo le variabili che occorrono diff --git a/Src/A69WD/General/Cfg.cs b/Src/A69WD/General/Cfg.cs index 61b3126..f048c40 100644 --- a/Src/A69WD/General/Cfg.cs +++ b/Src/A69WD/General/Cfg.cs @@ -237,6 +237,12 @@ namespace A69WD { } private string pathAnalizadedRaccFile = ""; + + public virtual string PathSrcDone => System.IO.Path.Combine(PathDownloadWorking, "Done"); + public virtual string PathIdxDone => System.IO.Path.Combine(PathDownloadWorking, "Idx"); + public virtual string PathSrcErrOnExtract => System.IO.Path.Combine(PathDownloadWorking, "ErrOnExtract"); + public virtual string PathSrcErrOnSave => System.IO.Path.Combine(PathDownloadWorking, "ErrOnSave"); + #endregion diff --git a/Src/A69WD/General/cTools.cs b/Src/A69WD/General/cTools.cs index 67d9d91..230de02 100644 --- a/Src/A69WD/General/cTools.cs +++ b/Src/A69WD/General/cTools.cs @@ -47,6 +47,12 @@ namespace A69WD { } + public static void SaveToFile(string txtHTML, string filePath, string fileName) { + System.IO.StreamWriter tsw = new System.IO.StreamWriter(System.IO.Path.Combine(filePath, fileName), false, Encoding.UTF8); + tsw.Write(txtHTML); + } + + /// /// Metodo che legge un testo da file (UTF8) /// diff --git a/Src/A69WD/Net/cLink_A69.cs b/Src/A69WD/Net/cLink_A69.cs index cceba20..b7337ea 100644 --- a/Src/A69WD/Net/cLink_A69.cs +++ b/Src/A69WD/Net/cLink_A69.cs @@ -745,7 +745,7 @@ namespace A69WD.Net { /// /// Indica se siamo autenticati al sito /// - public bool Autenticated => autenticated; + public static bool Autenticated => autenticated; /// @@ -867,14 +867,11 @@ namespace A69WD.Net { /// public async Task> CrawlPageAsync() { var newlinks = new List(); - if (!autenticated) { - // Sito non autenticato, non posso fare nulla - Logger.Warning("A69 - Sito non autenticato. Download non permessi."); - return newlinks; - } + try { Console.WriteLine($"A69 - Scarico: {URL}"); HtmlDocument tdoc = null; + string thtml = ""; #region ToConfirm if (Status == eLinkState.ToConfirm) { @@ -900,13 +897,11 @@ namespace A69WD.Net { return newlinks; } // Scarico la pagina - var thtml = await client.GetStringAsync(URL); + thtml = await client.GetStringAsync(URL); tdoc = new HtmlDocument(); tdoc.LoadHtml(thtml); // Salvo il file downloadato - //System.IO.StreamWriter tsw = new System.IO.StreamWriter(lk.DstFilePath, false, Encoding.UTF8); - System.IO.StreamWriter tsw = new System.IO.StreamWriter(System.IO.Path.Combine(FilePath, FileName), false, Encoding.UTF8); - tsw.Write(thtml); + //SaveToFile(thtml, lk.FilePath, lk.FileName); Status = eLinkState.ToAnalize; } @@ -916,6 +911,7 @@ namespace A69WD.Net { { if (Status == eLinkState.ToAnalize) { List tmpLk = new List(); + #region Estraggo gli url ad indici: { /* @@ -934,22 +930,22 @@ namespace A69WD.Net { * * */ - // Estraggo i link alle altre pagine: - var tnodes = tdoc.DocumentNode.SelectNodes("//div[@id='pagination']//ul//li//a[@href]"); - if (tnodes != null) { - foreach (var link in tnodes) { - var href = link.GetAttributeValue("href", ""); - if (!string.IsNullOrEmpty(href) && href.StartsWith("/racconti-erotici/racconti_lista.php?genere=")) - tmpLk.Add(href); //tmpLk.Add(cLink_A69.PageBase + href); - } - } - // Rimuove duplicati e ordina alfabeticamente - tmpLk = tmpLk - .OrderBy(s => s) // ordina alfabeticamente - .Distinct() // elimina duplicati - .ToList(); - // Inserisco i link trovati try { + // Estraggo i link alle altre pagine: + var tnodes = tdoc.DocumentNode.SelectNodes("//div[@id='pagination']//ul//li//a[@href]"); + if (tnodes != null) { + foreach (var link in tnodes) { + var href = link.GetAttributeValue("href", ""); + if (!string.IsNullOrEmpty(href) && href.StartsWith("/racconti-erotici/racconti_lista.php?genere=")) + tmpLk.Add(href); //tmpLk.Add(cLink_A69.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[] separator = new string[] { "&pagina=" }; string[] txt = ilk.Split(separator, StringSplitOptions.RemoveEmptyEntries); @@ -957,7 +953,10 @@ namespace A69WD.Net { string name = txt[0].Replace("/racconti-erotici/racconti_lista.php?genere=", "_A69_") + "_" + int.Parse(txt[1]).ToString("0000") + ".html"; newlinks.Add(new cLink_A69(url, name)); } - } catch (Exception ex) { Logger.Error("Errore analisi Idx link dal " + FileName + " - " + ex.Message); } + } catch (Exception ex) { + Logger.Error("Errore analisi Idx link dal " + FileName + " - " + ex.Message); + cTools.SaveToFile(thtml, Cfg.Settings.PathSrcErrOnExtract, FileName); + } } #endregion @@ -970,30 +969,33 @@ namespace A69WD.Net { * Continua a leggere » * */ - // Estraggo i link ai racconti: - tmpLk = new List(); - // Estraggo i link alle altre pagine: - var tnodes = tdoc.DocumentNode.SelectNodes("//div[@class='continua']//a[@href]"); - if (tnodes != null) { - foreach (var link in tnodes) { - var href = link.GetAttributeValue("href", ""); - if (!string.IsNullOrEmpty(href) && href.StartsWith("/racconti-erotici/") && (href.EndsWith(".html") || href.EndsWith(".htm"))) - tmpLk.Add(href); //tmpLk.Add(cLink_A69.PageBase + href); - } - } - // Rimuove duplicati e ordina alfabeticamente - tmpLk = tmpLk - .OrderBy(s => s) // ordina alfabeticamente - .Distinct() // elimina duplicati - .ToList(); - // Inserisco i link trovati try { + // Estraggo i link ai racconti: + tmpLk = new List(); + // Estraggo i link alle altre pagine: + var tnodes = tdoc.DocumentNode.SelectNodes("//div[@class='continua']//a[@href]"); + if (tnodes != null) { + foreach (var link in tnodes) { + var href = link.GetAttributeValue("href", ""); + if (!string.IsNullOrEmpty(href) && href.StartsWith("/racconti-erotici/") && (href.EndsWith(".html") || href.EndsWith(".htm"))) + tmpLk.Add(href); //tmpLk.Add(cLink_A69.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_A69.PageBase + ilk; string name = ilk.Replace("/racconti-erotici/", "A69_").Replace(@"/", "_"); newlinks.Add(new cLink_A69(url, name)); } - } catch (Exception ex) { Logger.Error("Errore analisi Idx link dal " + FileName + " - " + ex.Message); } + } catch (Exception ex) { + Logger.Error("Errore analisi Idx link dal " + FileName + " - " + ex.Message); + cTools.SaveToFile(thtml, Cfg.Settings.PathSrcErrOnExtract, FileName); + } } #endregion @@ -1003,8 +1005,21 @@ namespace A69WD.Net { cRac rac = EstraiRac(tdoc); if (rac != null) { // Racconto estratto correttamente, lo salvo sul DB - App.DB.ImportRac(rac); + 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 @@ -1039,7 +1054,7 @@ namespace A69WD.Net { } catch (Exception ex) { Console.WriteLine($"Errore con {URL}: {ex.Message}"); Status = eLinkState.Error; - //App.DB.LinkLog(lk); + App.DB.LinkLog(this); } return newlinks; } diff --git a/Src/A69WD/Net/iLink.cs b/Src/A69WD/Net/iLink.cs index 59da2de..2a43c80 100644 --- a/Src/A69WD/Net/iLink.cs +++ b/Src/A69WD/Net/iLink.cs @@ -47,6 +47,33 @@ namespace A69WD.Net { cRac EstraiRac(HtmlDocument doc); + + + + // #region Gestione Sito + // + // /// + // /// Booleano per sapere se siamo autenticati al sito + // /// (sempre true per i siti senza autenticazione) + // /// + // bool Autenticated { get; } + // + // /// + // /// Esegue l'autenticazione al sito + // /// + // Task Authenticate(); + // + // /// + // /// Elaborazione della pagina linkata: + // /// Scarica il link e analizza quanto downloadato + // /// + // /// + // /// + // Task> CrawlPageAsync(iLink lk); + // + // #endregion + + }//interface iLink }//namespace A69WD.Net diff --git a/Src/A69WD/Properties/AssemblyInfo.cs b/Src/A69WD/Properties/AssemblyInfo.cs index afdef1b..25d85c1 100644 --- a/Src/A69WD/Properties/AssemblyInfo.cs +++ b/Src/A69WD/Properties/AssemblyInfo.cs @@ -32,8 +32,26 @@ 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.1.0")] -[assembly: AssemblyFileVersion("0.5.1.0")] +[assembly: AssemblyVersion("0.5.2.0")] +[assembly: AssemblyFileVersion("0.5.2.0")] + + +/* + * + * Vrs 0.5.2.0 + * + * Compilata da CSiCoAlm il 2026/01/01 + * Refactoring del downloader per poterlo utilizzare in ATDB: + * - imglobata la classe iSite nella iLink + * - impostato cartelle di destinazione dei file per distinguere la diagnostica del lavoro + * + * + * 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 dfe5e41..daaaf42 100644 --- a/Src/A69WD/Service/Service_Crawler.cs +++ b/Src/A69WD/Service/Service_Crawler.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Net.Http; using System.Text; @@ -8,7 +9,6 @@ using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using A69WD.Net; -using A69WD.Site; @@ -29,9 +29,6 @@ namespace A69WD.Service { private int _completati = 0; private int _errori = 0; - // HttpClient autenticato (fornito da AuthService) - private iSiteType _site; - // Riferimenti ai controlli UI per aggiornare i contatori e la progress bar private readonly StatusStrip _sb; @@ -46,8 +43,7 @@ namespace A69WD.Service { /// /// Avvia il thread worker che consuma la coda di URL. /// - public void StartWorker(iSiteType site) { - _site = site; + public void StartWorker() { _workerThread = new Thread(ProcessQueue) { IsBackground = true }; _workerThread.Start(); } @@ -70,16 +66,29 @@ namespace A69WD.Service { /// /// Thread worker: consuma la coda ed avvia task di download. /// - private void ProcessQueue() { + private async void ProcessQueue() { + + // Verifico cartelle di destinazione: + if (!Directory.Exists(Cfg.Settings.PathIdxDone)) Directory.CreateDirectory(Cfg.Settings.PathIdxDone); + if (!Directory.Exists(Cfg.Settings.PathSrcDone)) Directory.CreateDirectory(Cfg.Settings.PathSrcDone); + if (!Directory.Exists(Cfg.Settings.PathSrcErrOnExtract)) Directory.CreateDirectory(Cfg.Settings.PathSrcErrOnExtract); + if (!Directory.Exists(Cfg.Settings.PathSrcErrOnSave)) Directory.CreateDirectory(Cfg.Settings.PathSrcErrOnSave); + + // Autenticazione ai siti: + if (!cLink_A69.Autenticated) { await cLink_A69.Authenticate(); } + + // Ciclo per ciascun elemento della FIFO: foreach (iLink link in _urlQueue.GetConsumingEnumerable()) { Logger.Information("ProcessQueue: Start url " + link.FileName); + Task.Run(async () => { Interlocked.Increment(ref _inCorso); UpdateCounters(); await _semaphore.WaitAsync(); try { - List urls = await _site.CrawlPageAsync(link); + cLink_A69 clk = link as cLink_A69; + List 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/Service/Service_Importer.cs b/Src/A69WD/Service/Service_Importer.cs index 0cdfe9c..822ac18 100644 --- a/Src/A69WD/Service/Service_Importer.cs +++ b/Src/A69WD/Service/Service_Importer.cs @@ -8,7 +8,6 @@ using System.Threading.Tasks; using System.Windows.Forms; using A69WD.Data; using A69WD.Net; -using A69WD.Site; @@ -95,12 +94,10 @@ namespace A69WD.Service { UpdateCounters(); // Verifico cartelle di destinazione - string pathErrOnExtract = System.IO.Path.Combine(Cfg.Settings.PathDownloadWorking, "ErrOnExtract"); - if (!Directory.Exists(pathErrOnExtract)) Directory.CreateDirectory(pathErrOnExtract); - string pathErrOnSave = System.IO.Path.Combine(Cfg.Settings.PathDownloadWorking, "ErrOnSave"); - if (!Directory.Exists(pathErrOnSave)) Directory.CreateDirectory(pathErrOnSave); - string pathDone = System.IO.Path.Combine(Cfg.Settings.PathDownloadWorking, "Done"); - if (!Directory.Exists(pathDone)) Directory.CreateDirectory(pathDone); + if (!Directory.Exists(Cfg.Settings.PathSrcDone)) Directory.CreateDirectory(Cfg.Settings.PathSrcDone); + if (!Directory.Exists(Cfg.Settings.PathSrcErrOnExtract)) Directory.CreateDirectory(Cfg.Settings.PathSrcErrOnExtract); + if (!Directory.Exists(Cfg.Settings.PathSrcErrOnSave)) Directory.CreateDirectory(Cfg.Settings.PathSrcErrOnSave); + // Ciclo su ciascun file foreach (string file in fileCasuali) { string name = System.IO.Path.GetFileName(file); @@ -117,19 +114,19 @@ namespace A69WD.Service { Logger.Warning($"Import - errore nel salvataggio: {name}"); Interlocked.Increment(ref _errori); // - Sposto il file - System.IO.File.Move(file, System.IO.Path.Combine(pathErrOnSave, System.IO.Path.GetFileName(file))); + System.IO.File.Move(file, System.IO.Path.Combine(Cfg.Settings.PathSrcErrOnSave, System.IO.Path.GetFileName(file))); } else { // salvataggio ok Logger.Warning($"Import - racconto salvato: {name}"); Interlocked.Increment(ref _completati); // - Sposto il file - System.IO.File.Move(file, System.IO.Path.Combine(pathDone, System.IO.Path.GetFileName(file))); + System.IO.File.Move(file, System.IO.Path.Combine(Cfg.Settings.PathSrcDone, System.IO.Path.GetFileName(file))); } } else { Logger.Warning($"Import - estrazione errata: {name}"); Interlocked.Increment(ref _errori); // - Sposto il file - System.IO.File.Move(file, System.IO.Path.Combine(pathErrOnExtract, System.IO.Path.GetFileName(file))); + System.IO.File.Move(file, System.IO.Path.Combine(Cfg.Settings.PathSrcErrOnExtract, System.IO.Path.GetFileName(file))); } UpdateCounters(); } diff --git a/Src/A69WD/Site/cSite_A69.cs b/Src/A69WD/Site/cSite_A69.cs deleted file mode 100644 index 86d164e..0000000 --- a/Src/A69WD/Site/cSite_A69.cs +++ /dev/null @@ -1,357 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Text; -using System.Threading.Tasks; -using A69WD.Data; -using A69WD.Net; -using HtmlAgilityPack; - -namespace A69WD.Site { - - - public class cSite_A69 : iSiteType { - - private readonly HttpClient client; - private readonly string nickname = @"Toky78"; - private readonly string password = @"p!fw05Q9Hc6j5"; - private bool logged = false; - - - public bool Logged => logged; - - /// - /// 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 virificare il corretto login - /// - public async Task Authenticate() { - try { - // 1) GET pagina di login - Console.WriteLine("A69 - Richiedo la pagina di login..."); - Logger.Information("A69 - Richiedo la pagina di login..."); - string loginPageHtml = await client.GetStringAsync(cLink_A69.LoginPageUrl); - - // 2) Parsing HTML per estrarre ts e token - var doc = new HtmlAgilityPack.HtmlDocument(); - doc.LoadHtml(loginPageHtml); - - string ts = doc.DocumentNode - .SelectSingleNode("//input[@name='ts']") - ?.GetAttributeValue("value", ""); - string token = doc.DocumentNode - .SelectSingleNode("//input[@name='token']") - ?.GetAttributeValue("value", ""); - - if (string.IsNullOrWhiteSpace(ts) || string.IsNullOrWhiteSpace(token)) { - Console.WriteLine("A69 - Impossibile estrarre 'ts' o 'token' dalla pagina di login."); - Logger.Information("A69 - Impossibile estrarre 'ts' o 'token' dalla pagina di login."); - return logged; - } - Console.WriteLine($"A69 - Parametri dinamici trovati: ts={ts}, token={token}"); - Logger.Information($"A69 - Parametri dinamici trovati: ts={ts}, token={token}"); - - // 3) POST login con valori dinamici - var loginData = new FormUrlEncodedContent(new[] - { - new KeyValuePair("nick", nickname), - new KeyValuePair("pwd", password), - new KeyValuePair("ricordami","1"), - new KeyValuePair("login", "Entra"), - new KeyValuePair("ts", ts), - new KeyValuePair("token", token) - }); - - Console.WriteLine("Invio credenziali di login..."); - var loginResponse = await client.PostAsync(cLink_A69.LoginPostUrl, loginData); - - if (!loginResponse.IsSuccessStatusCode) { - Console.WriteLine($"A69 - Login fallito. HTTP {(int)loginResponse.StatusCode} {loginResponse.ReasonPhrase}"); - Logger.Information($"A69 - Login fallito. HTTP {(int)loginResponse.StatusCode} {loginResponse.ReasonPhrase}"); - return logged; - } - - // Verifica semplice: sulla pagina di login effettuato, ricerco il nome dell'utente: - string loginResult = await loginResponse.Content.ReadAsStringAsync(); - if (loginResult.Contains(nickname)) { - Console.WriteLine("A69 - Login effettuato con successo! Sessione autenticata attiva."); - Logger.Information("A69 - Login effettuato con successo! Sessione autenticata attiva."); - logged = true; - } else { - Console.WriteLine("A69 - Login non riuscito: il server ha restituito un messaggio di errore."); - Logger.Information("A69 - Login non riuscito: il server ha restituito un messaggio di errore."); - logged = false; - } - - } catch (Exception ex) { - Console.WriteLine($"Errore generale: {ex.Message}"); - Logger.Information($"Errore generale: {ex.Message}"); - } - return logged; - } - - /// - /// Codice da eseguire per ciascun A69 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(iLink lk) { - var newlinks = new List(); - try { - Console.WriteLine($"A69 - Scarico: {lk.URL}"); - HtmlDocument tdoc = null; - - #region ToConfirm - if (lk.Status == eLinkState.ToConfirm) { - // Eseguo la verifica se link da downloadare - lk.Status = eLinkState.ToDownload; - } - #endregion - - #region ToDownload - if (lk.Status == eLinkState.ToDownload) { - lk.Status = eLinkState.OnDownload; - } - #endregion - - #region OnDownload - if (lk.Status == eLinkState.OnDownload) { - // Scarico il file - var resp = await client.GetAsync(lk.URL); - if (!resp.IsSuccessStatusCode) { - Console.WriteLine($"A69 - Errore HTTP {(int)resp.StatusCode} {resp.ReasonPhrase} per {lk.URL}"); - lk.Status = eLinkState.Error; - //App.DB.LinkLog(lk); - return newlinks; - } - // Scarico la pagina - var thtml = await client.GetStringAsync(lk.URL); - tdoc = new HtmlDocument(); - tdoc.LoadHtml(thtml); - // Salvo il file downloadato - //System.IO.StreamWriter tsw = new System.IO.StreamWriter(lk.DstFilePath, false, Encoding.UTF8); - System.IO.StreamWriter tsw = new System.IO.StreamWriter(System.IO.Path.Combine(lk.FilePath, lk.FileName), false, Encoding.UTF8); - tsw.Write(thtml); - - lk.Status = eLinkState.ToAnalize; - } - #endregion - - #region ToAnalize - { - if (lk.Status == eLinkState.ToAnalize) { - List tmpLk = new List(); - #region Estraggo gli url ad indici: - { - /* - * Gli url delle pagine di indice sono del tipo: - * - * - * - */ - // Estraggo i link alle altre pagine: - var tnodes = tdoc.DocumentNode.SelectNodes("//div[@id='pagination']//ul//li//a[@href]"); - if (tnodes != null) { - foreach (var link in tnodes) { - var href = link.GetAttributeValue("href", ""); - if (!string.IsNullOrEmpty(href) && href.StartsWith("/racconti-erotici/racconti_lista.php?genere=")) - tmpLk.Add(href); //tmpLk.Add(cLink_A69.PageBase + href); - } - } - // Rimuove duplicati e ordina alfabeticamente - tmpLk = tmpLk - .OrderBy(s => s) // ordina alfabeticamente - .Distinct() // elimina duplicati - .ToList(); - // Inserisco i link trovati - try { - foreach (string ilk in tmpLk) { - string[] separator = new string[] { "&pagina=" }; - string[] txt = ilk.Split(separator, StringSplitOptions.RemoveEmptyEntries); - string url = cLink_A69.PageBase + ilk; - string name = txt[0].Replace("/racconti-erotici/racconti_lista.php?genere=", "_A69_") + "_" + int.Parse(txt[1]).ToString("0000") + ".html"; - newlinks.Add(new cLink_A69(url, name)); - } - } catch (Exception ex) { Logger.Error("Errore analisi Idx link dal " + lk.FileName + " - " + ex.Message); } - } - #endregion - - #region Estraggo gli url a racconti: - { - /* - * - * I link ai racconti sono dei pulsanti così formati: - * - */ - // Estraggo i link ai racconti: - tmpLk = new List(); - // Estraggo i link alle altre pagine: - var tnodes = tdoc.DocumentNode.SelectNodes("//div[@class='continua']//a[@href]"); - if (tnodes != null) { - foreach (var link in tnodes) { - var href = link.GetAttributeValue("href", ""); - if (!string.IsNullOrEmpty(href) && href.StartsWith("/racconti-erotici/") && (href.EndsWith(".html") || href.EndsWith(".htm"))) - tmpLk.Add(href); //tmpLk.Add(cLink_A69.PageBase + href); - } - } - // Rimuove duplicati e ordina alfabeticamente - tmpLk = tmpLk - .OrderBy(s => s) // ordina alfabeticamente - .Distinct() // elimina duplicati - .ToList(); - // Inserisco i link trovati - try { - foreach (string ilk in tmpLk) { - string url = cLink_A69.PageBase + ilk; - string name = ilk.Replace("/racconti-erotici/", "A69_").Replace(@"/","_"); - newlinks.Add(new cLink_A69(url, name)); - } - } catch (Exception ex) { Logger.Error("Errore analisi Idx link dal " + lk.FileName + " - " + ex.Message); } - } - #endregion - - #region Estraggo il racconto dal file e lo inserisco nel DB - if (lk.FileName.StartsWith("A69_")) { - // Link ad un racconto - cRac rac = lk.EstraiRac(tdoc); - if (rac != null) { - // Racconto estratto correttamente, lo salvo sul DB - App.DB.ImportRac(rac); - } - } - #endregion - - lk.Status = eLinkState.End; - App.DB.LinkLog(lk); - } - } - #endregion - - #region End - if (lk.Status == eLinkState.End) { - } - #endregion - - #region Error - if (lk.Status == eLinkState.Error) { - } - #endregion - - #region Abort - if (lk.Status == eLinkState.Abort) { - } - #endregion - - #region Cancel - if (lk.Status == eLinkState.Cancel) { - } - #endregion - - Console.WriteLine("Link.Count=" + newlinks.Count.ToString("00")); - - } catch (Exception ex) { - Console.WriteLine($"Errore con {lk.URL}: {ex.Message}"); - lk.Status = eLinkState.Error; - //App.DB.LinkLog(lk); - } - return newlinks; - } - - public async Task> CrawlPageAsyncTest1(iLink lk) { - var newlinks = new List(); - try { - // Scarico il file - var resp = await client.GetAsync(lk.URL); - if (!resp.IsSuccessStatusCode) { - Console.WriteLine($"A69 - Errore HTTP {(int)resp.StatusCode} {resp.ReasonPhrase} per {lk.URL}"); - lk.Status = eLinkState.Error; - //App.DB.LinkLog(lk); - return newlinks; - } - // Scarico la pagina - var thtml = await client.GetStringAsync(lk.URL); - // Salvo il file downloadato - System.IO.StreamWriter tsw = new System.IO.StreamWriter(System.IO.Path.Combine(lk.FilePath, lk.FileName), false, Encoding.UTF8); - tsw.Write(thtml); - - Console.WriteLine("Link.Count=" + newlinks.Count.ToString("00")); - - } catch (Exception ex) { - Console.WriteLine($"Errore con {lk.URL}: {ex.Message}"); - lk.Status = eLinkState.Error; - //App.DB.LinkLog(lk); - } - return newlinks; - } - - public async Task> CrawlPageAsyncTest2(iLink lk) { - var newlinks = new List(); - try { - // Scarico il file - var resp = await client.GetAsync(lk.URL); - if (!resp.IsSuccessStatusCode) { - Console.WriteLine($"A69 - Errore HTTP {(int)resp.StatusCode} {resp.ReasonPhrase} per {lk.URL}"); - lk.Status = eLinkState.Error; - //App.DB.LinkLog(lk); - return newlinks; - } - // Scarico la pagina - HttpClient tmpClient = new HttpClient(_handler); - var thtml = await tmpClient.GetStringAsync(lk.URL); - // Salvo il file downloadato - System.IO.StreamWriter tsw = new System.IO.StreamWriter(System.IO.Path.Combine(lk.FilePath, lk.FileName), false, Encoding.UTF8); - tsw.Write(thtml); - - Console.WriteLine("Link.Count=" + newlinks.Count.ToString("00")); - - } catch (Exception ex) { - Console.WriteLine($"Errore con {lk.URL}: {ex.Message}"); - lk.Status = eLinkState.Error; - //App.DB.LinkLog(lk); - } - return newlinks; - } - - public cSite_A69() { - _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_A69.LoginPageUrl); - } - HttpClientHandler _handler = null; - - - - - }//class cSite_A69 - -}//namespace A69WD.Site diff --git a/Src/A69WD/Site/iSiteType.cs b/Src/A69WD/Site/iSiteType.cs deleted file mode 100644 index 737f06d..0000000 --- a/Src/A69WD/Site/iSiteType.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using A69WD.Net; - - -/* - * - * Interfaccia iSiteType - * --------------------- - * Questa interfaccia definisce il contratto per le diverse tipologie di siti gestiti dal crawler. - * Ogni sito deve implementare: - * - Authenticate(): eventuale autenticazione al sito (PUT, POST, ecc.) - * - ValidateLink(string href): regole di validazione dei link estratti - * - CrawlPageAsync(string url): scarica una pagina e la analizza - * - * In questo modo il programma principale può distinguere facilmente tra siti autenticati e pubblici, - * mantenendo il codice modulare ed estensibile. - * - */ - - - -namespace A69WD.Site { - - /// - /// Interfaccia per gestire le operazioni da fare su un sito - /// - public interface iSiteType { - - /// - /// Booleano per sapere se siamo autenticati al sito - /// (sempre true per i siti senza autenticazione) - /// - bool Logged { get; } - - /// - /// Esegue l'autenticazione al sito - /// - Task Authenticate(); - - /// - /// Elaborazione della pagina linkata: - /// Scarica il link e analizza quanto downloadato - /// - /// - /// - Task> CrawlPageAsync(iLink lk); - - }//interface iSiteType - -}//namespace A69WD.Site diff --git a/Src/A69WD/UI/frmReader.Designer.cs b/Src/A69WD/UI/frmReader.Designer.cs index f73280f..346d918 100644 --- a/Src/A69WD/UI/frmReader.Designer.cs +++ b/Src/A69WD/UI/frmReader.Designer.cs @@ -28,24 +28,22 @@ this.sbMessage = new System.Windows.Forms.ToolStripStatusLabel(); this.sbProgressBar = new System.Windows.Forms.ToolStripProgressBar(); this.sbStatusLabel = new System.Windows.Forms.ToolStripStatusLabel(); - this.btnTest = new System.Windows.Forms.Button(); - this.btnTest2 = new System.Windows.Forms.Button(); - this.btnTest3 = new System.Windows.Forms.Button(); + this.btnTest1 = new System.Windows.Forms.Button(); + this.pnlTop = new System.Windows.Forms.Panel(); this.sb.SuspendLayout(); + this.pnlTop.SuspendLayout(); this.SuspendLayout(); // // rtb // - this.rtb.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); this.rtb.BackColor = System.Drawing.Color.White; this.rtb.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.rtb.Dock = System.Windows.Forms.DockStyle.Fill; this.rtb.Font = new System.Drawing.Font("Verdana", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.rtb.Location = new System.Drawing.Point(0, 54); + this.rtb.Location = new System.Drawing.Point(0, 42); this.rtb.Name = "rtb"; - this.rtb.Size = new System.Drawing.Size(700, 366); - this.rtb.TabIndex = 3; + this.rtb.Size = new System.Drawing.Size(700, 378); + this.rtb.TabIndex = 2; this.rtb.Text = ""; this.rtb.KeyDown += new System.Windows.Forms.KeyEventHandler(this.KeyDownAnalisi); // @@ -59,7 +57,7 @@ this.sb.Location = new System.Drawing.Point(0, 420); this.sb.Name = "sb"; this.sb.Size = new System.Drawing.Size(700, 24); - this.sb.TabIndex = 2; + this.sb.TabIndex = 1; this.sb.Text = "statusStrip1"; // // sbMessage @@ -95,35 +93,24 @@ this.sbStatusLabel.Tag = "Label"; this.sbStatusLabel.ToolTipText = "Stato di eventuali operazioni in background"; // - // btnTest + // btnTest1 // - this.btnTest.Location = new System.Drawing.Point(4, 4); - this.btnTest.Name = "btnTest"; - this.btnTest.Size = new System.Drawing.Size(62, 48); - this.btnTest.TabIndex = 4; - this.btnTest.Text = "Test"; - this.btnTest.UseVisualStyleBackColor = true; - this.btnTest.Click += new System.EventHandler(this.btnTest_Click); + this.btnTest1.Location = new System.Drawing.Point(11, 5); + this.btnTest1.Name = "btnTest1"; + this.btnTest1.Size = new System.Drawing.Size(62, 32); + this.btnTest1.TabIndex = 4; + this.btnTest1.Text = "Test"; + this.btnTest1.UseVisualStyleBackColor = true; + this.btnTest1.Click += new System.EventHandler(this.btnTest1_Click); // - // btnTest2 + // pnlTop // - this.btnTest2.Location = new System.Drawing.Point(72, 4); - this.btnTest2.Name = "btnTest2"; - this.btnTest2.Size = new System.Drawing.Size(62, 48); - this.btnTest2.TabIndex = 5; - this.btnTest2.Text = "Test 2"; - this.btnTest2.UseVisualStyleBackColor = true; - this.btnTest2.Click += new System.EventHandler(this.btnTest2_Click); - // - // btnTest3 - // - this.btnTest3.Location = new System.Drawing.Point(140, 4); - this.btnTest3.Name = "btnTest3"; - this.btnTest3.Size = new System.Drawing.Size(62, 48); - this.btnTest3.TabIndex = 6; - this.btnTest3.Text = "Test 3"; - this.btnTest3.UseVisualStyleBackColor = true; - this.btnTest3.Click += new System.EventHandler(this.btnTest3_Click); + this.pnlTop.Controls.Add(this.btnTest1); + this.pnlTop.Dock = System.Windows.Forms.DockStyle.Top; + this.pnlTop.Location = new System.Drawing.Point(0, 0); + this.pnlTop.Name = "pnlTop"; + this.pnlTop.Size = new System.Drawing.Size(700, 42); + this.pnlTop.TabIndex = 0; // // frmReader // @@ -131,10 +118,8 @@ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(700, 444); this.ControlBox = false; - this.Controls.Add(this.btnTest3); - this.Controls.Add(this.btnTest2); - this.Controls.Add(this.btnTest); this.Controls.Add(this.rtb); + this.Controls.Add(this.pnlTop); this.Controls.Add(this.sb); this.Name = "frmReader"; this.Text = "PlugIn_App_Reader.UI Reader (DB vrs1.3, App" + @@ -142,6 +127,7 @@ this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.frmReader_FormClosing); this.sb.ResumeLayout(false); this.sb.PerformLayout(); + this.pnlTop.ResumeLayout(false); this.ResumeLayout(false); } @@ -153,8 +139,7 @@ private System.Windows.Forms.ToolStripStatusLabel sbMessage; private System.Windows.Forms.ToolStripProgressBar sbProgressBar; private System.Windows.Forms.ToolStripStatusLabel sbStatusLabel; - private System.Windows.Forms.Button btnTest; - private System.Windows.Forms.Button btnTest2; - private System.Windows.Forms.Button btnTest3; + private System.Windows.Forms.Button btnTest1; + private System.Windows.Forms.Panel pnlTop; } } \ No newline at end of file diff --git a/Src/A69WD/UI/frmReader.cs b/Src/A69WD/UI/frmReader.cs index 00782d8..9014c2e 100644 --- a/Src/A69WD/UI/frmReader.cs +++ b/Src/A69WD/UI/frmReader.cs @@ -11,7 +11,6 @@ using System.Windows.Forms; using A69WD.Data; using A69WD.Net; using A69WD.Service; -using A69WD.Site; namespace A69WD.UI { public partial class frmReader : Form { @@ -23,7 +22,6 @@ namespace A69WD.UI { private Service_Crawler serviceCrawler = null; private Service_Importer ServiceImporter = null; - A69WD.Site.iSiteType siteA69 = null; public frmReader() { InitializeComponent(); @@ -63,6 +61,10 @@ namespace A69WD.UI { mImpStart.Enabled = true; mImpStop.Enabled = false; + // Update UI + pnlTop.Enabled = false; + pnlTop.Visible = false; + } /// @@ -676,20 +678,6 @@ namespace A69WD.UI { mImpStart.Enabled = false; mImpStop.Enabled = false; - // - Creo istanza del client per il sito con autenticazione: - sbStatusLabel.Text = "Login on A69"; - siteA69 = new cSite_A69(); - - // - Eseguo l'autenticazione - bool res = await siteA69.Authenticate(); - if (res) { - sbStatusLabel.Text = "A69 autenticated"; - Logger.Information("Sito A69 loggato: " + res.ToString()); - } else { - Logger.Information("Login Fault"); - return; - } - // - Verifico path per il download if (!System.IO.Directory.Exists(Cfg.Settings.PathDownloadWorking)) System.IO.Directory.CreateDirectory(Cfg.Settings.PathDownloadWorking); @@ -701,7 +689,7 @@ namespace A69WD.UI { return; } // avvio il servizio - serviceCrawler.StartWorker(siteA69); + serviceCrawler.StartWorker(); } void MenuItem_Skraping_Stop_Click(object sender, EventArgs e) { @@ -746,111 +734,11 @@ namespace A69WD.UI { cTools.ShowOnNotepad(Cfg.Settings.PathFileLogs); } - private async void btnTest_Click(object sender, EventArgs e) { + private void btnTest1_Click(object sender, EventArgs e) { // Test download multipli con sempre lo stesso client per condividere la sessione - - // - Creo istanza del client per il sito con autenticazione: - sbStatusLabel.Text = "Login on A69"; - cSite_A69 site = new cSite_A69(); - - // - Eseguo l'autenticazione - bool res = await site.Authenticate(); - if (res) { - sbStatusLabel.Text = "A69 autenticated"; - Logger.Information("Sito A69 loggato: " + res.ToString()); - } else { - Logger.Information("Login Fault"); - return; - } - - // - Verifico path per il download - if (!System.IO.Directory.Exists(Cfg.Settings.PathDownloadWorking)) System.IO.Directory.CreateDirectory(Cfg.Settings.PathDownloadWorking); - cLink_A69[] lks = new cLink_A69[26]; - for (int i = 1; i < lks.Length; i++) { - lks[i] = new cLink_A69($"https://www.annunci69.it/racconti-erotici/racconti_lista.php?genere=altro&pagina={i}", $"_A69_altro_{i.ToString("0000")}.html"); - } - - DateTime start = DateTime.Now; - // - Download dei link come finora fato (steso client per condividere la sessione): - for (int i = 1; i < lks.Length; i++) { - List urls = await site.CrawlPageAsyncTest1(lks[i]); - } - DateTime end = DateTime.Now; - - sbStatusLabel.Text = (start - end).ToString(); - + ; } - private async void btnTest2_Click(object sender, EventArgs e) { - - // Test download multipli con client diversi ma che condividono solo la sessione - - // - Creo istanza del client per il sito con autenticazione: - sbStatusLabel.Text = "Login on A69"; - cSite_A69 site = new cSite_A69(); - - // - Eseguo l'autenticazione - bool res = await site.Authenticate(); - if (res) { - sbStatusLabel.Text = "A69 autenticated"; - Logger.Information("Sito A69 loggato: " + res.ToString()); - } else { - Logger.Information("Login Fault"); - return; - } - - // - Verifico path per il download - if (!System.IO.Directory.Exists(Cfg.Settings.PathDownloadWorking)) System.IO.Directory.CreateDirectory(Cfg.Settings.PathDownloadWorking); - cLink_A69[] lks = new cLink_A69[26]; - for (int i = 1; i < lks.Length; i++) { - lks[i] = new cLink_A69($"https://www.annunci69.it/racconti-erotici/racconti_lista.php?genere=altro&pagina={i}", $"_A69_altro_{i.ToString("0000")}.html"); - } - - DateTime start = DateTime.Now; - // - Download dei link come finora fato (steso client per condividere la sessione): - for (int i = 1; i < lks.Length; i++) { - List urls = await site.CrawlPageAsyncTest1(lks[i]); - } - DateTime end = DateTime.Now; - - sbStatusLabel.Text = (start - end).ToString(); - - } - - private async void btnTest3_Click(object sender, EventArgs e) { - - // Test download multipli con client diversi ma che condividono solo la sessione e nuovo refactoring - - // - Eseguo l'autenticazione - bool res = await cLink_A69.Authenticate(); - if (res) { - sbStatusLabel.Text = "A69 autenticated"; - Logger.Information("Sito A69 loggato: " + res.ToString()); - } else { - sbStatusLabel.Text = "Fault Login"; - Logger.Information("Login Fault"); - return; - } - - // - Verifico path per il download - if (!System.IO.Directory.Exists(Cfg.Settings.PathDownloadWorking)) System.IO.Directory.CreateDirectory(Cfg.Settings.PathDownloadWorking); - cLink_A69[] lks = new cLink_A69[26]; - for (int i = 1; i < lks.Length; i++) { - lks[i] = new cLink_A69($"https://www.annunci69.it/racconti-erotici/racconti_lista.php?genere=altro&pagina={i}", $"_A69_altro_{i.ToString("0000")}.html"); - } - - DateTime start = DateTime.Now; - // - Download dei link come finora fato (steso client per condividere la sessione): - for (int i = 1; i < lks.Length; i++) { - List urls = await lks[i].CrawlPageAsync(); - } - DateTime end = DateTime.Now; - - sbStatusLabel.Text = (start - end).ToString(); - - } - - } }