func WalkDirZip(fsys fs.FS, root string, fn WalkDirFunc) error { return fs.WalkDir(fsys, root, func(path string, d fs.DirEntry, err error) error { if d.IsDir() || !strings.EqualFold(filepath.Ext(path), ".zip") { return fn(fsys, path, d, err) } else if f, err := fsys.Open(path); err != nil { return err } else if s, err := f.Stat(); err != nil { return err } else if zfs, err := zip.NewReader(f.(io.ReaderAt), s.Size()); err != nil { return err } else { return fs.WalkDir(zfs, ".", func(path string, d fs.DirEntry, err error) error { return fn(zfs, path, d, err) }) } }) } type WalkDirFunc func(fsys fs.FS, path string, d fs.DirEntry, err error) error
Nathan Baulch
Wednesday, February 16, 2022
Traverse into zip files when walking the file system
Friday, December 13, 2019
Recursively compact git repositories within a directory
find -name .git -exec echo {} \; -execdir git gc --aggressive ";"
Thursday, October 6, 2016
Generic extension method for traversing object graphs
public static IEnumerableTraverse (this T root, Func > getChildren) { return Enumerable.Repeat(root, 1) .Concat((getChildren(root) ?? Enumerable.Empty ()) .SelectMany(child => Traverse(child, getChildren))); }
Tuesday, August 23, 2016
Extract attachments and inline files from a MIME message
MimeMessage msg; using (var stream = File.OpenRead(fileName)) { msg = MimeMessage.Load(stream); } foreach (var part in msg.BodyParts.OfTypeMimeKit().Where(part => !string.IsNullOrEmpty(part.FileName))) { using (var stream = File.OpenWrite(Path.Combine(Path.GetDirectoryName(fileName), part.FileName))) { part.ContentObject.DecodeTo(stream); } }
Tuesday, April 8, 2014
Deserialize an anonymous type using SimpleJson
var json = "{\"name\": \"Joe\"," + "\"age\": 25," + "\"address\": {\"city\": \"Paris\"}," + "\"emails\": [\"joe@home.com\", \"joe@work.com\"]," + "\"phones\": [{\"type\": \"Mobile\", \"number\": \"555 1234\"}]}"; var prototype = new { name = default(string), age = default(int), address = new {city = default(string)}, emails = new string[0], phones = new[] {new {type = default(string), number = default(string)}} }; var result = SimpleJsonExt.DeserializeAnonymousObject(json, prototype); using CacheEntry = KeyValuePair<ParameterInfo[], ReflectionUtils.ConstructorDelegate>; public static class SimpleJsonExt { public static T DeserializeAnonymousObject<T>(string json, T prototype) { return SimpleJson.SimpleJson.DeserializeObject<T>(json, new Strategy()); } private class Strategy : PocoJsonSerializerStrategy { private readonly IDictionary<Type, CacheEntry> _ctorCache = new ReflectionUtils.ThreadSafeDictionary<Type, CacheEntry>(CreateConstructorDelegate); private static CacheEntry CreateConstructorDelegate(Type key) { var ctors = key.GetConstructors(); if (ctors.Length == 1) { var ctor = ctors[0]; var parms = ctor.GetParameters(); if (parms.Length > 0) { return new CacheEntry(parms, ReflectionUtils.GetContructor(ctor)); } } return default(CacheEntry); } public override object DeserializeObject(object value, Type type) { var dict = value as IDictionary<string, object>; if (dict != null) { var ctor = _ctorCache[type]; if (ctor.Key != null) { return ctor.Value(ctor.Key .Select(param => DeserializeObject( dict.TryGetValue(param.Name, out value) ? value : null, param.ParameterType)) .ToArray()); } } return base.DeserializeObject(value, type); } } }SimpleJson
Sunday, November 24, 2013
Recursively search and replace files from one folder into another
$filter = '*.dll', '*.pdb' $copied = 0; $skipped = 0; $failed = 0 $sourceFiles = $filter | % { Get-ChildItem $sourceDir -Filter $_ -Recurse } ` | sort @{expression={$_.FullName.Length}} -Descending ` | group Name -AsHashTable $targetFiles = $filter | % { Get-ChildItem $targetDir -Filter $_ -Recurse } ` | ? { $sourceFiles.ContainsKey($_.Name) } ` | sort FullName $targetFiles | % { $target = $_ $sourceFiles[$target.Name] | % { $source = $_ if ($target.FullName.EndsWith($source.FullName.Substring($sourceDir.Length), 'InvariantCultureIgnoreCase')) { if ($target.LastWriteTime.AddSeconds(2) -lt $source.LastWriteTime) { Write-Host $target.FullName try { Copy-Item $source.FullName $target.FullName -Force $copied++ } catch { Write-Error $_.Message $failed++ } } else { $skipped++ } return } } } Write-Host "$copied copied, $skipped skipped, $failed failed in $($watch.Elapsed)"
Thursday, March 14, 2013
Programmatically configure a simple log4net trace appender
var hierarchy = (Hierarchy) LogManager.GetRepository(); var logger = (Logger) hierarchy.GetLogger(loggerName); logger.Level = Level.Debug; logger.AddAppender(new TraceAppender {Layout = new SimpleLayout()}); hierarchy.Configured = true;log4net
Monday, January 28, 2013
Convert an SQL like pattern into a regular expression pattern
var pattern = Regex.Replace( likePattern, @"[%_]|\[[^]]*\]|[^%_[]+", match => { if (match.Value == "%") { return ".*"; } if (match.Value == "_") { return "."; } if (match.Value.StartsWith("[") && match.Value.EndsWith("]")) { return match.Value; } return Regex.Escape(match.Value); });
Saturday, January 12, 2013
Load test a web site using asynchronous requests and the TPL
var queue = new Queue<Task>(); while (true) { if (queue.Count >= 50) { var task = queue.Dequeue(); task.Wait(); task.Dispose(); } var request = (HttpWebRequest) WebRequest.Create(url); var watch = Stopwatch.StartNew(); queue.Enqueue(Task.Factory .FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null) .ContinueWith(task => { using (var response = (HttpWebResponse) task.Result) { Console.WriteLine("{0}\t{1}\t{2}", response.StatusCode, response.ContentType, watch.Elapsed); } })); }Task Parallel Library (TPL)
Thursday, June 28, 2012
Calculate the exponential moving average of a stream of numbers
public static IEnumerable<double> ExponentialMovingAverage(this IEnumerable<double> source, double alpha) { double? last = null; return source.Select( value => { var average = last != null ? alpha*value + (1 - alpha)*last.Value : value; last = average; return average; }); }
Thursday, February 16, 2012
Create a fast compiled method invoker using LINQ
var method = new Func<double, double, double>(Math.Pow).Method; var parameter = Expression.Parameter(typeof(object[])); var args = method.GetParameters() .Select((param, i) => Expression.Convert( Expression.ArrayIndex(parameter, Expression.Constant(i)), param.ParameterType)); var expr = Expression.Lambda<Func<object[], object>>( Expression.Convert(Expression.Call(method, args), typeof(object)), parameter); var invoker = expr.Compile(); var result = invoker(new object[] {Math.PI, 2.0});
Friday, February 10, 2012
Create a Google calendar event in an existing calendar
var credentials = new GDataCredentials(userName, password); var service = new CalendarService(null) {Credentials = credentials}; var query = new CalendarQuery("https://www.google.com/calendar/feeds/default/owncalendars/full"); var feed = service.Query(query); var eventFeedLink = feed.Entries.Cast<CalendarEntry>() .Where(item => item.Title.Text == calendarName) .SelectMany(item => item.Links) .First(link => link.Rel == GDataParserNameTable.NSGCal + "#eventFeed"); var entry = new EventEntry(title) {Times = {new When(start, end, allDay)}}; service.Insert(new Uri(eventFeedLink.AbsoluteUri), entry);Google Data API .NET client library
Thursday, February 2, 2012
Page through potentially large NHibernate criteria query results
public static IEnumerable<T> Enumerate<T>(this ICriteria criteria, int pageSize = 1000) { var entityCount = CriteriaTransformer.TransformToRowCount(criteria).UniqueResult<int>(); var pageCount = (int) Math.Ceiling(entityCount/(double) pageSize); criteria = CriteriaTransformer.Clone(criteria).SetMaxResults(pageSize); return Enumerable.Range(0, pageCount) .SelectMany(pageNum => criteria.SetFirstResult(pageNum*pageSize).List<T>()); }NHibernate
Friday, January 20, 2012
Create a YouTube playlist containing all the uploads of a given user
var credentials = new GDataCredentials(userName, password); var service = new YouTubeService(applicationName, developerKey) {Credentials = credentials}; var entry = new AtomEntry {Title = {Text = playlistName}}; entry = service.Insert(new Uri(YouTubeQuery.CreatePlaylistsUri(null)), entry); var id = ((XmlExtension) entry.FindExtension("playlistId", YouTubeNameTable.NSYouTube)).Node.InnerText; var batchUri = new Uri(string.Format("https://gdata.youtube.com/feeds/api/playlists/{0}/batch", id)); var query = new YouTubeQuery(YouTubeQuery.CreateUserUri(sourceUser)) {StartIndex = 1}; AtomFeed feed; do { feed = service.Query(query); service.Batch(feed, batchUri); query.StartIndex += feed.Entries.Count; } while (query.StartIndex < feed.TotalResults);Google Data API .NET client library
Sunday, January 8, 2012
List the users of a TFS project associated with a local workspace path
var workspace = Workstation.Current.GetLocalWorkspaceInfo(path); var tfs = new TfsTeamProjectCollection(workspace.ServerUri); var gss = tfs.GetService<IGroupSecurityService>(); var grp = gss.ReadIdentity(SearchFactor.EveryoneApplicationGroup, null, QueryMembership.Expanded); var names = gss.ReadIdentities(SearchFactor.Sid, grp.Members, QueryMembership.None) .Where(identity => identity.Type == IdentityType.WindowsUser) .Select(identity => string.Format(@"{0}\{1}", identity.Domain, identity.AccountName)) .ToArray();
Friday, January 6, 2012
Quartz scheduler job that re-triggers itself on completion
public class RetriggerJob : IInterruptableJob { private bool _interrupted; public void Execute(IJobExecutionContext context) { Thread.Sleep(1000); if (_interrupted) { return; } context.Scheduler.TriggerJob(context.JobDetail.Key); if (_interrupted) { context.Scheduler.Interrupt(context.JobDetail.Key); } } public void Interrupt() { _interrupted = true; } }Quartz.NET
Friday, December 30, 2011
Read a published Google spreadsheet into a DataTable using GData
var service = new SpreadsheetsService(null); var query = new ListQuery("0AjD5UGMt5CGDdEcwaS10S2IzVzJFNDYtaEo5anN2RHc", "1", "public", "values"); var feed = service.Query(query); var table = new DataTable(); foreach (ListEntry entry in feed.Entries) { var row = table.NewRow(); foreach (ListEntry.Custom element in entry.Elements) { var column = table.Columns[element.LocalName] ?? table.Columns.Add(element.LocalName); row[column] = element.Value; } table.Rows.Add(row); }Google Data API .NET client library
Saturday, December 17, 2011
Determine if a WinForms control resource file is localized
XPathDocument doc; using (var stream = File.OpenRead(fileName)) { doc = new XPathDocument(stream); } var nav = doc.CreateNavigator(); var itr = nav.Select("root/data[@name = '>>$this.Name']"); var localized = itr.Count > 0;
Remove matching C# region directives using LINQ
var flag = false; var modified = false; var lines = File.ReadLines(fileName) .Where(line => { if ((!flag && line.Contains("#region " + regionName)) || (flag && line.Contains("#endregion"))) { flag = !flag; modified = true; return false; } return true; }) .ToArray(); if (modified) { File.WriteAllLines(fileName, lines); }
Thursday, December 8, 2011
Compile and execute a stateful T4 template using Mono.TextTemplating
var input = "<#@ template language=\"C#\" debug=\"true\" #>" + "<#+ static int num; #>" + "<#= num++ #>"; var generator = new TemplateGenerator(); var compiled = generator.CompileTemplate(input); Debug.Assert(Equals(compiled.Process(), "0")); Debug.Assert(Equals(compiled.Process(), "1")); Debug.Assert(Equals(compiled.Process(), "2"));Mono.TextTemplating
Subscribe to:
Posts (Atom)