trans-autoclean – Auto Remove Completed Torrents from Transmission

Filed in Software Developement Leave a comment

Do you have an awesome set & forget server setup that automatically grabs torrents for you in the background? Do you use transmission-daemon to accomplish this? Have you ever wondered why there’s no way to automatically remove completed torrents? I sure have.

I started using FlexGet about a year ago, I even wrote my own plugin to handle magnet links back when I was still using rtorrent. I left rtorrent because transmission has really matured and is much easier to work with (RPC-wise). The problem I kept facing is that every now and then I would check on the web interface and found a large number of completed torrents just sitting there. This became a semi-regular task, log into the web interface, clear the completed torrents. Today I decided that this is a very simple problem to solve so I’ll just kill an hour and make this work. Turns out it only took about 15 minutes, but I spent the other 45 creating a github account, project, and writing this entry.

Anyways, here is the project:

This script is perfect for those who have a couch potato like setup. Hopefully some of you find it useful.


LINQ, GroupJoin, and Left Outer Joins

Filed in Software Developement Leave a comment

This is a topic which involves me scouring the internet every time I need to do this task. outer joins in LINQ are one of the few LINQ concepts that is not very simple to execute.

Essentially, an Outer Join maps to GroupJoin. GroupJoin is almost identical to Join, except that your right side lambda parameter is a collection (of potentially zero items) instead of an object reference. Because it is a collection it doesn’t really help you out if you need to do a real left outer join. To solve this we make use of SelectMany and DefaultIfEmpty LINQ methods.

SelectMany will allow us to expand the collection, and DefaultIfEmpty will retain the empty collections, together we can supply a value of null (or whatever you want) to a column that is not joined. Below is an example to illustrate.

    .GroupJoin(Orders, x => x.CustomerID, x => x.CustomerID, (a, b) => new { a.Name, b })
    .SelectMany(x => x.b.DefaultIfEmpty(), (a, b) => a.Name, OrderID = (b == null ? (int?)null : b.OrderID)

, , , ,

LINQ(-to-SQL), DateTimeOffset, and Time Zones

Filed in Software Developement Leave a comment

Today I was requested to produce a report on some timestamped data, but with the timestamps in the time zone where the data was collected.  Now long ago I learned the valuable lesson of using DateTimeOffset to store data and there is no change with this scenario, but something I had never actually tried before was getting LINQ-to-SQL (LINQPad) to emit timestamp data in a time zone other than my current system time zone.  This is really more of a general .NET solution to the same problem as i don’t believe LINQ-to-SQL actually converts any timestamp data on the data side (nor should it, we only want the DateTimeOffset values).

The crucial type in this case is TimeZoneInfo. First you need to figure out which time zone you want as your target (destination) time zone.  Use TimeZoneInfo.GetSystemTimeZones() to figure that one out, and make note of the Id property.  Now you need to create the proper TimeZoneInfo instance, you could use the results of that list, but more simply you can create the instance from the Id property using TimeZoneInfo.FindSystemTimeZoneById("Id") or for a real world example: TimeZoneInfo.FindSystemTimeZoneById("Newfoundland Standard Time"). The last part is to use TimeZoneInfo.ConvertTime(DateTimeOffset, TimeZoneInfo) to offset your DateTimeOffset to the proper amount.

Here is a full example:

TimeStampedData.Select(x => new { x.Name, Timestamp = TimeZoneInfo.ConvertTime(x.Timestamp, TimeZoneInfo.FindSystemTimeZoneById("Newfoundland Standard Time")) })

Nice and simple, but a little bit of a pain to actually get the right time zone.  Ideally, .NET would have static accessors to all the common standard time zones (as TimeZoneInfo static instances), but otherwise this is a reasonably easy solution to achieve.

, , , ,