public void Run(IrcMessage theMessage) { List <Labordaten> daten = LaborDaten.GetItem(true); if (LaborDaten.Renewed == DateTime.MinValue) { theMessage.Answer("Ich konnte leider keine Daten von der Laborwebseite abrufen und mein Cache ist leer"); return; } if (!LaborDaten.IsUpToDate) { theMessage.Answer("Es war mir nicht möglich den Labor Cache zu erneuern. Grund: " + LaborDaten.LastUpdateFail?.Message + ". Verwende Cache vom " + LaborDaten.Renewed.ToString()); } if (String.IsNullOrEmpty(theMessage.CommandLine)) { theMessage.Answer("Aktuelle Labor Daten: " + daten.Select(x => $"{x.Typ}: {x.Datum}").Join(", ") + " - Zum Labor: " + Toolbox.ShortUrl("http://www.avm.de/de/Service/Service-Portale/Labor/index.php")); } else { string BoxName = BoxDatabase.GetShortName(theMessage.CommandLine); if (daten.FirstOrDefault(x => x.Typ == BoxName) is { } first) { theMessage.Answer($"Die neueste {first.Typ} labor Version ist am {first.Datum} erschienen mit der Versionsnummer: {first.Version} - Laborseite: {first.Url}"); }
private static List <FtpDirectory> FindDirectory(List <FtpDirectory> directories, Box?box, string name) { FtpDirectory? idMatch = null; FtpDirectory? directMatch = null; List <FtpDirectory> roughMatches = new List <FtpDirectory>(); foreach (FtpDirectory directory in directories) { if (box != null && BoxDatabase.FindBoxes(directory.Name).Any(x => x == box)) { idMatch = directory; break; } else if (directory.Name.Equals(name, StringComparison.OrdinalIgnoreCase)) { directMatch = directory; } else if (directory.Name.IndexOf(name, StringComparison.OrdinalIgnoreCase) != -1) { roughMatches.Add(directory); } } return(idMatch == null && directMatch == null ? roughMatches : new List <FtpDirectory> { idMatch ?? directMatch ! });
private static void BoxDbAdd(IrcMessage theMessage) { Match match = Regex.Match(theMessage.CommandLine, "boxdb add \"(?<short>[^\"]*)\" \"(?<full>[^\"]*)\" (?<regex>.*)"); if (!match.Success) { theMessage.Answer("Zu wenig Parameter: boxdb add \"(?<short>[^\"]*)\" \"(?<full>[^\"]*)\" (?<regex>.*)"); return; } Box box = BoxDatabase.GetBoxByShortName(match.Groups["short"].Value); string[] regexes = Regex.Matches(match.Groups["regex"].Value, "\"(?<value>[^\"]*)\"").Cast <Match>().Select(x => x.Groups["value"].Value).ToArray(); if (box == null) { box = BoxDatabase.AddBox(match.Groups["short"].Value, match.Groups["full"].Value, regexes); theMessage.Answer("Box erfolgreich hinzugefügt"); } else { box.FullName = match.Groups["full"].Value; box.AddRegex(regexes); theMessage.Answer("Box Infos geupdated"); } }
public bool HasBox(string input) { if (BoxDatabase.TryFindExactBox(input, out Box? result)) { return(_context.BoxEntries.Any(x => x.User.Id == _user.Id && (x.Text == input || x.Box !.Id == result.Id))); } return(_context.BoxEntries.Any(x => x.User.Id == _user.Id && x.Text == input)); }
private static IEnumerable <string> OnlyReadableNames(IEnumerable <string> files) { foreach (string name in files) { if (BoxDatabase.TryGetShortName(name, out string?shortName)) { yield return(shortName); } } }
public void ReAssociateBoxes() { List <BoxEntry> userBoxEntries = _context.BoxEntries.Where(x => x.User.Id == _user.Id).ToList(); foreach (BoxEntry entry in userBoxEntries) { entry.Box = BoxDatabase.TryFindExactBox(entry.Text, out Box? result) ? result : null; } _context.SaveChanges(); }
private static void BoxDbInfo(IrcMessage theMessage) { Box box = BoxDatabase.GetBoxByShortName(theMessage.CommandArgs[2]); if (box == null) { theMessage.Answer("So eine Box habe ich nicht gefunden"); return; } theMessage.Answer($"ShortName: {box.ShortName}, FullName: {box.FullName}, RegexPatterns: {box.RegexPattern.Select(x => x.Pattern).Join(", ")}"); }
private static void BoxDbRemove(IrcMessage theMessage) { Box box = BoxDatabase.GetBoxByShortName(theMessage.CommandArgs.Skip(2).Join(" ")); if (box == null) { theMessage.Answer("So eine Box habe ich nicht gefunden"); return; } using (var context = new BotContext()) { context.Boxes.Remove(box); theMessage.Answer("Box entfernt"); } }
public BoxEntry AddBox(string input) { BoxEntry entry = new BoxEntry(); entry.User = _user; entry.Text = input; if (BoxDatabase.TryFindExactBox(input, out Box? result)) { entry.Box = result; _context.Boxes.Attach(result); } _context.BoxEntries.Add(entry); _context.SaveChanges(); return(entry); }
private static void BoxDbRegex(IrcMessage theMessage) { Match match = Regex.Match(theMessage.CommandLine, "boxdb regex \"(?<short>[^\"]*)\" (?<regex>.*)"); if (!match.Success) { theMessage.Answer("Zu wenig Parameter: boxdb regex \"(?<short>[^\"]*)\" (?<regex>.*)"); return; } Box box = BoxDatabase.GetBoxByShortName(match.Groups["short"].Value); if (box == null) { theMessage.Answer("Für diesen ShortName konnte ich keine Box ermitteln"); return; } string[] regexes = Regex.Matches(match.Groups["regex"].Value, "\"(?<value>[^\"]*)\"").Cast <Match>().Select(x => x.Groups["value"].Value).ToArray(); box.AddRegex(regexes); theMessage.Answer("Regex(e) erfolgreich hinzugefügt"); }
public void Run(IrcMessage theMessage) { using (var context = new BotContext()) { IQueryable <BoxEntry> filtered; if (BoxDatabase.TryFindExactBox(theMessage.CommandLine, out Box? result)) { filtered = context.BoxEntries.Where(x => x.Box !.Id == result.Id); } else { filtered = context.BoxEntries.Where(x => x.Text.Contains(theMessage.CommandLine)); } string besitzer = filtered.Select(x => x.User.LastUsedName.Name).Where(x => !String.IsNullOrEmpty(x)).Distinct().OrderBy(x => x).Join(", "); if (!String.IsNullOrEmpty(besitzer)) { theMessage.SendPrivateMessage("Folgende Benutzer scheinen diese Box zu besitzen: " + besitzer); } else { theMessage.SendPrivateMessage("Diese Box scheint niemand zu besitzen!"); } } }
public async Task WorkerThread(CancellationToken token) { // https://osp.avm.de/fritzbox/ while (true) { if (FWCheckEnabled) { FtpDirectory CurrentScan; using (FtpClient ftp = GetClient()) { try { CurrentScan = RecurseFTP(ftp, "/fritz.box"); } catch (Exception ex) { Log.Warning(ex, "Fehler beim FTP Scan"); await Task.Delay(FWCheckIntervall, token); continue; } } if (LastScan == null) { LastScan = CurrentScan; await Task.Delay(FWCheckIntervall, token); continue; } List <string> neu = new List <string>(); List <string> gelöscht = new List <string>(); List <string> geändert = new List <string>(); var joinedDirectories = LastScan.Folders.Flatten(x => x.Folders).FullOuterJoin(CurrentScan.Folders.Flatten(x => x.Folders), x => x.FullName, x => x.FullName, (o, c, _) => new { Original = o, Current = c }); foreach (var directory in joinedDirectories) { if (directory.Original == null) // Neuer Ordner { neu.Add("[" + directory.Current !.FullName + (directory.Current.Files.Any() ? "(" + directory.Current.Files.Select(x => x.Name).Join(", ") + ")]" : "]")); } else if (directory.Current == null) // Ordner gelöscht { gelöscht.Add("[" + directory.Original.FullName + (directory.Original.Files.Any() ? "(" + directory.Original.Files.Select(x => x.Name).Join(", ") + ")]" : "]")); } else { var joinedFiles = directory.Original.Files.FullOuterJoin(directory.Current.Files, x => x.Name, x => x.Name, (o, c, _) => new { Original = o, Current = c }); List <string> fileChanges = new List <string>(); foreach (var file in joinedFiles) { if (file.Original == null) // Neue Datei { fileChanges.Add(file.Current !.Name + "(neu)"); } else if (file.Current == null) // Datei gelöscht { fileChanges.Add(file.Original.Name + "(gelöscht)"); } else if (file.Original.Modified != file.Current.Modified) // Datei geändert { fileChanges.Add(file.Original.Name + "(" + file.Original.Modified.ToString() + "/" + file.Current.Modified.ToString() + ")"); } } if (fileChanges.Count > 0) { geändert.Add("[" + directory.Current.FullName + "(" + fileChanges.Join(", ") + ")]"); } } } int summarizedCount = neu.Count + gelöscht.Count + geändert.Count; if (summarizedCount > 20) { Log.Warning("{SummarizedCount} überschreitet limit an Änderungen, ignoriere...", summarizedCount); } else if (summarizedCount > 0) { string labors = "Änderungen auf dem FTP gesichtet! - "; if (neu.Count > 0) { labors += "Neue { " + neu.Join(" ") + " } "; } if (gelöscht.Count > 0) { labors += "Gelöscht { " + gelöscht.Join(" ") + " } "; } if (geändert.Count > 0) { labors += "Geändert { " + geändert.Join(" ") + " } "; } labors = labors.TrimEnd() + " - Zum FTP: ftp://ftp.avm.de/fritz.box/"; ServerManager.AnnounceGlobal(labors); NotifySubscribers(labors, neu.Concat(geändert).Select(x => BoxDatabase.GetShortName(x)).ToArray()); } LastScan = CurrentScan; await Task.Delay(FWCheckIntervall, token); } else { await Task.Delay(30000, token); } } }
public void Run(IrcMessage theMessage) { bool recovery = false; bool source = false; bool firmware = false; Box box = BoxDatabase.FindBoxes(theMessage.CommandLine).FirstOrDefault(); List <string> nameSegments = new List <string>(); string rawName; if (theMessage.CommandArgs.Count > 1) { foreach (string argument in theMessage.CommandArgs) { if (argument.Equals("all", StringComparison.OrdinalIgnoreCase) || argument.Equals("alles", StringComparison.OrdinalIgnoreCase)) { firmware = true; recovery = true; source = true; break; } else if (argument.Equals("source", StringComparison.OrdinalIgnoreCase) || argument.Equals("sources", StringComparison.OrdinalIgnoreCase) || argument.Equals("src", StringComparison.OrdinalIgnoreCase)) { source = true; } else if (argument.Equals("recovery", StringComparison.OrdinalIgnoreCase) || argument.Equals("recoveries", StringComparison.OrdinalIgnoreCase)) { recovery = true; } else if (argument.Equals("firmware", StringComparison.OrdinalIgnoreCase) || argument.Equals("firmwares", StringComparison.OrdinalIgnoreCase)) { firmware = true; } else { nameSegments.Add(argument); } } rawName = nameSegments.Join(" "); } else { firmware = true; rawName = theMessage.CommandLine; } FtpDirectory? Scan = LastScan; FtpDirectory? match = null; List <FtpDirectory>?matches = null; bool shouldRefresh = false; if (Scan != null) { matches = FindDirectory(Scan.Folders, box, rawName); if (matches.Count > 1) { theMessage.Answer("Bitte genauer spezifizieren: " + OnlyReadableNames(matches.Select(x => x.Name)).Join(", ")); return; } match = matches.FirstOrDefault(); shouldRefresh = true; } if (match == null) { List <FtpDirectory> FreshScanned; using (FtpClient client = GetClient()) { FreshScanned = client.GetListing("/fritz.box").Where(x => x.Type == FtpFileSystemObjectType.Directory).Select(x => new FtpDirectory { FullName = x.FullName }).ToList(); matches = FindDirectory(FreshScanned, box, rawName); if (matches.Count > 1) { theMessage.Answer("Bitte genauer spezifizieren: " + OnlyReadableNames(matches.Select(x => x.Name)).Join(", ")); return; } match = matches.FirstOrDefault(); if (match != null) { match = RecurseFTP(client, match.FullName); shouldRefresh = false; } } } if (match == null) { theMessage.Answer("Ich habe zu deiner Suche leider kein Verzeichnis gefunden"); return; } string output = FormatResult(match, recovery, source, firmware); if (!String.IsNullOrEmpty(output)) { theMessage.Answer(output); } if (shouldRefresh) { using (FtpClient client = GetClient()) { match = RecurseFTP(client, match.FullName); string refreshedOutput = FormatResult(match, recovery, source, firmware); if (String.IsNullOrEmpty(output) && !String.IsNullOrEmpty(refreshedOutput)) { theMessage.Answer(refreshedOutput); return; } if (output != refreshedOutput) { theMessage.Answer("Wups, meine Angabe war nicht mehr Up-to-Date, hier kommen die aktuellen Ergebnisse:"); theMessage.Answer(refreshedOutput); } } } }
private List <Labordaten> GetFTPBetas() { List <Tuple <Labordaten, string> > ftpBetas = new List <Tuple <Labordaten, string> >(); var betaCache = Path.Combine(Path.GetDirectoryName(typeof(Program).Assembly.Location), "betaCache"); if (!Directory.Exists(betaCache)) { Directory.CreateDirectory(betaCache); } using (FtpClient ftp = new FtpClient()) { ftp.Host = "ftp.avm.de"; ftp.Credentials = new NetworkCredential("anonymous", ""); ftp.SetWorkingDirectory("/fritz.box/beta"); List <FtpListItem> files = ftp.GetListing().Where(x => x.Type == FtpFileSystemObjectType.File).ToList(); foreach (FtpListItem file in files) { Labordaten daten = new Labordaten(); daten.Datum = (file.Modified == DateTime.MinValue && ftp.HasFeature(FtpCapability.MDTM) ? ftp.GetModifiedTime(file.FullName) : file.Modified).ToString("dd.MM.yyyy HH:mm:ss"); daten.Url = "ftp://ftp.avm.de" + file.FullName; string target = Path.Combine(betaCache, file.Name); if (!File.Exists(target)) { using (Stream f = ftp.OpenRead(file.Name)) using (FileStream fi = File.Create(target)) f.CopyTo(fi); } ftpBetas.Add(new Tuple <Labordaten, string>(daten, target)); } } foreach (Tuple <Labordaten, string> fw in ftpBetas) { try { using (Stream file = File.OpenRead(fw.Item2)) using (ZipArchive archive = new ZipArchive(file, ZipArchiveMode.Read)) { ZipArchiveEntry firmware = archive.Entries.FirstOrDefault(x => x.Name.Contains("_Labor.") || x.Name.Contains(".Labor.") || x.Name.Contains("_LabBETA.") || x.Name.Contains(".LabBETA.")); if (firmware == null) { Log.Error("Firmware {Firmware} hat keine erkannte Labor Firmware", fw.Item2); continue; } string RawName = firmware.Name; fw.Item1.Version = Regex.Match(RawName, @"((\d{2,3}\.)?\d\d\.\d\d(-\d{1,6})?).image$").Groups[1].Value; if (!BoxDatabase.TryGetShortName(RawName, out string tmp)) { if (RawName.LastIndexOf(' ') != -1) { fw.Item1.Typ = RawName.AsSpan(RawName.LastIndexOf(' ')).Trim().ToString(); } else { fw.Item1.Typ = RawName.Trim(); } } else { fw.Item1.Typ = tmp; } } } catch (InvalidDataException ex) //'System.IO.InvalidDataException' in System.IO.Compression.dll("Das Ende des Datensatzes im zentralen Verzeichnis wurde nicht gefunden.") { var betaCachePath = Path.GetDirectoryName(fw.Item2); var name = Path.GetFileNameWithoutExtension(fw.Item2); var extension = Path.GetExtension(fw.Item2); string corruptedFilePath = Path.Combine(betaCachePath, $"{name}_corrupted_{DateTime.Now:dd_MM_yyyy_hh_mm_ss}{extension}"); File.Move(fw.Item2, corruptedFilePath); Log.Error(ex, "Korruptes Zip {Filename} gefunden. Zip umbenannt zu {NewFilename}", fw.Item2, corruptedFilePath); } } return(ftpBetas.Select(x => x.Item1).ToList()); }