git rev-list --reverse HEAD -- words.csv | \ xargs -I {} sh -c 'echo $(git show -s --date=short --format="%ad" {}) $(git show {}:./words.csv | wc -l)'
Nathan Baulch
Sunday, October 6, 2024
Extract line count of file at each git revision
Wednesday, February 16, 2022
Traverse into zip files when walking the file system
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
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)