• No recently listened tracks.

Modem Monitor Update [Updated]

I bought a new modem today, slightly hoping that it will fix whatever connection issues i’m having, it’s a newer model surfboard (SB6190) and as such I’ve had to update my script which checks the status. Please see below πŸ™‚

import requests
import datetime
from bs4 import BeautifulSoup
#import dateparser
import tweepy
import re

#Set up Twitter creds
CONSUMER_KEY='[REPLACE ME]'
CONSUMER_SECRET='[REPLACE ME]'
ACCESS_KEY='[REPLACE ME]'
ACCESS_SECRET='[REPLACE ME]'

#Authenticate with Twitter
auth=tweepy.OAuthHandler(CONSUMER_KEY,CONSUMER_SECRET)
auth.set_access_token(ACCESS_KEY,ACCESS_SECRET)
api=tweepy.API(auth)

#Set up regex patterns
timespanPattern = re.compile("^(\d+)\s+d:\s+(\d{1,2})\s+h:\s+(\d{1,2})\s+m$")

#scrape the modem page
page = requests.get("http://[REPLACE WITH INTERNAL IP OF MODEM]/cgi-bin/swinfo")
soup = BeautifulSoup(page.content, 'html.parser')

#navigate the DOM to get the desired data
modeminfo = list(soup.find_all('table', {"class": "simpleTable"})[1])
#print modeminfo
uptime = list(modeminfo[3].children)[3]
#print uptime
timestr = uptime.get_text()
#print timestr

#Take the text and get the time data out
matches = timespanPattern.match(timestr)
#print "Days: " + matches.group(1)
#print "Hours: " + matches.group(2)
#print "Minutes: " + matches.group(3)
days = int(matches.group(1))
hours = int(matches.group(2))
minutes = int(matches.group(3))

#create timespan so we can figure out at what time the reboot happened
span = datetime.timedelta(days=days,hours=hours,minutes=minutes)
currenttime = datetime.datetime.now()
timespan = currenttime - span
status = ""

if minutes < 5  and days == 0:
        status="Hey @Comcast, my modem just rebooted at " + timespan.strftime("%Y-%m-%d %H:%M:%S")
        api.update_status(status)
        print status
else:
        print "Modem has been up since " + timespan.strftime("%Y-%m-%d %H:%M:%S")

Update 7/15/2017 19:04
It looks like the new modem doesn’t behave like the old one. The old one would reboot automatically when things got unstable and would log a bunch of T3 and T4 errors. The new one does similar, but doesn’t reboot, it’ll just stay up. I’ll have to find a new approach to annoy Comcast πŸ˜› Today the internet connection wouldn’t stay up for longer than an hour after I put the new modem on. I got in contact with Comcast’s online support and they did some magic on their end and after a few modem reboots and reboot of my firewall, things seem to be more stable. At this point the connection has been up for ~2 hours without incident. Here’s to hoping we’ll get a few weeks more of uptime πŸ™‚

Comcast can’t keep it up? I’ll let them know about it

So over the last few months my internet service with Comcast has been less than stellar. My connection would drop out at random times throughout the day, on some days I wouldn’t stay connected for more than 20 or so minutes at a time. At first, I was hoping that it was a random issue and it would go away on its own (wishful thinking, right?). Well, it didn’t. I contacted customer support and they told me that my modem levels were high, but they couldn’t do anything about it remotely and that a tech would have to come out. I find this weird because last year I was having a similar issue and the rep was able to resolve my problems remotely. Anyway, I scheduled an appointment and a tech came out and took a look at my equipment and was unable to find anything wrong. The only thing he said may be causing an issue was that I’d put in a splitter that wasn’t “one of theirs”. After he left i checked mine against his, and the frequency ranges on both the splitters was identical.. so.. whatever. Needless to say, my issue was not resolved. So a few days later when the issue cropped up again, I scheduled another appointment for a tech to come out. This time the guy busted his butt (much respect!) and ran brand new cable from the pole to the house, cleaned up the rats nest of cabling the initial installers left behind when we first got service and even put in an outdoor service box.

This was a few weeks ago, and up until the last few days the problem seemed to have been resolved. But then it started again. And I was about to schedule another appointment, but I’d gotten my bill that morning. Come to find out they charge you to come out and fix the issues they can’t seem to keep resolved. $30 bucks a pop! Needless to say, before I give them another excuse to gouge me for more money, I figure some internet noise is required.

I’ve decided to write a small python script that scrapes the uptime from my modem (an Arris SurfboardΒ SB6141), and if it’s less than 5 minutes, pop a tweet at Comcast letting them know. Feel free to use this or improve upon it!

The script runs from an Ubuntu server every 5 minutes via crobjob.

Dependencies (installed with pip)

  • requests
  • datetime
  • BeautifulSoup
  • dateparser
  • tweepy

Script

import requests
import datetime
from bs4 import BeautifulSoup
import dateparser
import tweepy

CONSUMER_KEY='[REPLACE ME]'
CONSUMER_SECRET='[REPLACE ME]'
ACCESS_KEY='[REPLACE ME]'
ACCESS_SECRET='[REPLACE ME]'

auth=tweepy.OAuthHandler(CONSUMER_KEY,CONSUMER_SECRET)
auth.set_access_token(ACCESS_KEY,ACCESS_SECRET)
api=tweepy.API(auth)

page = requests.get("http://[REPLACE WITH INTERNAL IP OF MODEM]/indexData.htm")
soup = BeautifulSoup(page.content, 'html.parser')

modeminfo = list(soup.find_all('table')[1].children)
uptime = list(modeminfo[1].children)[5]
timestr = list(uptime.children)[3].get_text()
timespan = dateparser.parse(timestr)
currenttime = datetime.datetime.now()
span = currenttime - timespan
minutes = span.seconds/60
days = span.days
status = ""
if minutes <= 5 and days == 0:
    status="Hey @Comcast, my modem just rebooted at " + timespan.strftime("%Y-%m-%d %H:%M:%S")
    api.update_status(status)
else:
    print "Modem has been up since " + timespan.strftime("%Y-%m-%d %H:%M:%S")

Setting up Comchap’s Comcut with ComSkip, ffmpeg, and HandbrakeCLI

I’ve been running Plex for years now and with their addition of Plex DVR last year I started recording many of the television shows I’d been acquiring other ways before. It saves on bandwidth, it saves on time spent searching for the right quality from a trusted group, but what it doesn’t save on is space. An hour show can easily run 6GB if recorded at 1080p. To help with that I’ve implemented a two stage strategy.

  1. Remove the commercials, which take up almost a third of a show.
  2. Compress the show a bit with x264 using Handbrake.

First we’ll need to cover exactly what we’re going to need:

  1. A linux server which will do the compression for you — I’m running Ubuntu
  2. git — we’ll be getting a few libraries from github repos.
    1. ComSkip:Β https://github.com/erikkaashoek/Comskip
    2. ComChap:Β https://github.com/BrettSheleski/comchap
  3. enough hard drive space to do all this — 20GB should work for a work space.

Ok, so first things first. We’ll want to make sure that your server is set up to build code as well as some other dependencies.

For my version of Ubuntu I installed the following:

apt-get install -y git handbrake-cli build-essential libargtable2-dev libavformat-ffmpeg-dev libsdl1.2-dev autoconf automake libass-dev libfreetype6-dev libsdl2-dev libtheora-dev libtool libva-dev libvdpau-dev libvorbis-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev pkg-config texinfo zlib1g-dev

Next, we’ll want to ensure we have a version of ffmpeg that will work. I’ve personally run into issues using ffmpeg which shipped with my release of Ubuntu (I’m running 16.04.02). The simplest way that I’ve found to get around this is to compile ffmpeg from source. I followed the directions here:Β https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu

Some things to keep in mind. If you’re going to need to download the sources for any of the dependencies in that guide instead of just installing them via the package manager, you’ll probably want to make sure that you’re getting the latest version of that library instead of what’s listed in the guide. Some of those libraries seem quite old.

After ffmpeg is installed, it should reside in your users’ ~/bin folder. If you want, you can link/copy it to somewhere more accessible if more than that user need to use it (something like /usr/local/bin?)

Now we’re ready for the main event.

First, grab ComSkip from the github repository:

$ cd ~/
$ git clone git://github.com/erikkaashoek/Comskip
$ cd Comskip
$ ./autogen.sh
$ ./configure
$ make

This will create a comskip executable in the Comskip directory. For other applications to use it we’ll need to move it into a directory which is typically in everyone’s $PATH. I copied mine to /usr/local/bin/comskip. Remember to check and make sure it’s executable (chmod +x comskip)

Second, we’ll grab the Comchap library from github as well:

$ cd ~/
$ git clone git://github.com/BrettSheleski/comchap

Third, we’ll need to get a script to tie this all together.

$ nano convertTStoMKV.sh
#!/bin/bash
PATH=$PATH:/usr/local/bin
searchDir=$1
fileExt="ts"

if [ -d "$searchDir" ]
then
 find "$searchDir" -name "*.$fileExt" -type f -exec sh -c '
 file="$0"
 fileDir=$(dirname "$file")
 fileName=$(basename "$file")
 fileNameNoExt="${fileName%.*}"
 tmpFileDir="/your/path/to/the/working/directory"
 newFileExt="mkv"
 newFileName="$fileNameNoExt.$newFileExt"
 workingFilePath="$tmpFileDir/$fileName"
 tmpFilePath="$tmpFileDir/$newFileName"
 finalDestination="/your/path/to/where/the/file/is/dropped"
 echo "moving file to work dir: $file"
 mv "$file" "$workingFilePath"
 if [ $? -eq 0 ]
 then
 echo "Running ComCut on file: $workingFilePath"
 /your/path/to/comchap/comcut "$workingFilePath"
 echo "processing: $workingFilePath"
 HandBrakeCLI -e x264 --encoder-preset "faster" -q 24 -2 -T -E copy -B 192 -5 -i "$workingFilePath" -o "$tmpFilePath"
 if [ $? -eq 0 ]
 then
 echo "Moving file to final destination: $finalDestination/$newFileName"
 mv "$tmpFilePath" "$finalDestination/$newFileName"
 if [ $? -eq 0 ]
 then
 echo "Removing old file: $workingFilePath"
 rm "$workingFilePath"
 fi
 fi
 fi
 ' {} ';'
else
 echo "dir doesn't exist: $searchDir"
fi

Remember to update all the relevant paths. I’ve made some of them generic to explain what they are. Once that’s done, then set up the script to run at some point every night (I used cron) and all the new .TS files will have their commercials cut, be compressed and converted to .MKV files.

Pre Paid Progress

It’s been about two months since i dropped Sprint and went to T-Mobile. My experience has been pretty good so far, but there are a few ‘but’s in there. For the transfer I got an unlocked Nexus 4. The plan is that here in a while i’ll also get an AT&T prepaid plan and compare the services.

Price

I was able to get in on the $30/month prepaid plan for T-Mobile. Which is even cheaper that what I was going to get through Straight Talk. This plan is just rediculous! You get unlimited data and texting (up to 5GB at 3/4G speeds) and 100 minutes of talk. I really don’t talk on the phone much so that’s just fine for me, and I don’t think I’ve come close to hitting the 5GB limit on data (…yet ;))

Speeds

Where i live and with my phone, the fastest I’ll get is HSPA+42 (T-Mobile’s non-LTE 4G). In town, and once i’m in other towns I’ve gotten good speeds of between Β 1200 and 6000 kbps down, which is a huge increase from the 30 – 500 kbps i was getting with Sprint.

Coverage

This is where i think T-Mobile fails a bit. While the only place i’ve never had service was the same place most other people didn’t have service, there are areas where i wished me speeds were better. While in town i have great service and good speeds, but if i’m on the interstate or travelling between towns, often times my connection drops to E or even G — at which point doing any kind of music streaming is just impossible. Overall I would give the coverage a grade of satisfactory, but with much room for improvement.

With that said, I’m definitely more content with T-Mobile than I was with Sprint. I am curious though on how AT&T will stack up. I have friends on AT&T and while they have more and better coverage, I don’t think they get the same speeds that i do. I’d like to do an Apples-to-Apples comparison in the next few months.

Trying to move from Sprint to Straight Talk

This whole process has been quite frustrating.

But first, let me give you some background information on what i’m trying to do. I’ve been with Sprint for years, I’d say since 2000 or 2001 when i was still on with my parents. Then a few years ago, 2008 i think, I got a new phone and wanted to go off on my own. So i got a new number and my own account with Sprint. For the longest time I was quite happy. The speeds were good, the call quality was great, and the phones were pretty on par with everyone else. But then the smartphone revolution happened. And slowly i started to notice that Sprint had fewer and fewer phones that i was actually interested in. I also started noticing that my speeds weren’t keeping up with what other carriers were offering. So finally, after my contract expired in august i’ve been on the lookout for what new phone i’d want to get, and what carrier i’d go to.

Then a few months ago I discovered the Nexus 4. I knew about it for a while, but i didn’t quite looked into it. What really caught my eye is that it’s 1) a newer phone and 2) you can get it unlocked cheaper than you can get it from a carrier! The unlocked portion is extra nice especially since it’s now illegal for you to unlock your own phone!

Now that i knew what phone i wanted to get it was time to start looking at providers. A friend of mine has been using multiple resellers (or MNVOs) over the last two years or so and has had some good things to say. He was on Straight Talk at the time using AT&T. I figured I could get a couple of SIMs and then test out both networks, since Straight Talk used both AT&T and T-Mobile networks. I’d also looked at a few others and while the prices were comparable, I noticed that only Straight Talk explicitly referred to offering 4G speeds (which for the Nexus 4 meant HSPA+).

I order my phone from Google, and my SIM and Service Plan from Straight Talk. When the phone comes in i’m totally stoked! It’s pretty and clean and fast and everything i’d hoped it would be! I wait a few days and get my SIM (on 4/11). First thing i noticed was that my SIM was a full sized one, and not a micro SIM which the Nexus 4 needs. After hunting around and even stooping to go to Walmart to try and get a different SIM (which they don’t have for ST), i found a ‘conversion’ kit i could print out online. I chop up my SIM to make it fit into the SIM Slot, turn on the phone and everything looks good. It detected the SIM and started looking for signal. I then went to the Straight Talk website to Activate my SIM and service. Everything goes pretty smoothly from what i can tell. I say that i’m activating a new SIM and that i want to transfer an existing number from another company. I put in all the information they requested for my Sprint account, and then completed the process. I noted that for company to company transfers it could take up to two business days (this is weird because I later read online that there’s an FCC regulation saying that these transfers are supposed to be done within 24 hours). Β I wait until the next Monday (4/15) and then make a post on the Straight Talk facebook page, which I’d read was the best way to get any kind of customer service. I ask if i can get someΒ assistanceΒ since my port had taken longer than the two days they communicated in their policy. The conversation starts with comments on my post asking me to put in a helpdesk ticket, which i try, but the page kept giving me an error saying that my email address belonged to a deleted account. In the end we resort to Facebook Messaging, which I’ve exported and will display here fully intact except for any sensitive information. I find the whole situation quite frustrating.

On April 15, 2013 8:43:35 AM PDT, Dan Colomb wrote:
Hi Phil,
 The MEID of my old Sprint Phone is XXXXXXX, the IMEI of my new phone is XXXXXXX.
my ST user account email isΒ xxxx@xxxx.com
Let me know if you need anything else.
On April 15, 2013 8:44:23 AM PDT, Phil ST wrote:
Thank you for that information, Dan.
Let me check your account now. I'll get back to you in few minutes.
On April 15, 2013 8:45:09 AM PDT, Phil ST wrote:
Can you provide me the phone number that you're trying to transfer to Straight Talk?
On April 15, 2013 8:46:44 AM PDT, Dan Colomb wrote:
555-555-5555
On April 15, 2013 8:53:13 AM PDT, Phil ST wrote:
Were you given a reference or ticket number for your port request? If so, please provide me with the numbers so that I can pull out your account. Thanks!
On April 15, 2013 8:57:16 AM PDT, Dan Colomb wrote:
The only thing i see on my ST account is the SIM (XXXXX) and that it states there is a port in progress. I don't recall receiving an email with a reference or ticket number.
The only number i have in my email is for my SIM order (XXXXX).
On April 15, 2013 9:10:55 AM PDT, Phil ST wrote:
Dan,
We regret to inform you that we failed to port your number to the SIM card that you purchased. If you want we can activate your SIM with a new phone number or you may purchase a brandnew Straight Talk phone and we'll attempt to port again the phone number. Thanks!
On April 15, 2013 9:17:26 AM PDT, Dan Colomb wrote:
Wow, that is not the response i was expecting. Is there a reason why the port failed?
I noticed that on your website you no longer offers Micro SIMs, that is what my phone requires. How would i go about getting a Micro SIM for ST?
On April 15, 2013 9:20:05 AM PDT, Phil ST wrote:
Because porting any numbers to a T-Mobile compatible SIM is not possible as of now.
For now, Straight Talk Wireless is not selling SIM cards that are compatible with AT&T devices. We will bring them back as soon as we can. For updates on this issue, please visit our website atΒ www.Straighttalk.com.
On April 15, 2013 9:22:41 AM PDT, Dan Colomb wrote:
Is there a way to get a refund for the 30 days of service i purchased? I guess i'll be going to another provider.
On April 15, 2013 9:23:45 AM PDT, Phil ST wrote:
We're sorry to hear that, Dan.
Where did you purchase your service plan?
On April 15, 2013 9:24:08 AM PDT, Dan Colomb wrote:
I purchased it through the website when i bought the SIM.
On April 15, 2013 9:25:10 AM PDT, Phil ST wrote:
Dan,
If you want, you may purchase a brandnew Straight Talk phone and we'll just convert the amount you paid for the SIM and will add also your service plan.
On April 15, 2013 9:27:55 AM PDT, Phil ST wrote:
In addition, we will also re-process the porting of number if ever you will purchase a Straight Talk phone.
On April 15, 2013 9:28:44 AM PDT, Dan Colomb wrote:
i don't want to buy a new phone, i want so use the new Unlocked GSM phone which i just purchased.
So if, as of right now, there is no way for me to get my number transferred and have my service activated, i would like to have my 45 dollars refunded. I can handle eating the SIM price, since i know that's non-refundable.
On April 15, 2013 9:37:09 AM PDT, Phil ST wrote:
Dan,
I'll need first to update my floor supervisor regarding your request. I'll get back to you in few minutes. Thanks.
On April 15, 2013 10:48:33 AM PDT, Phil ST wrote:
Dan,Β 
We regret to inform that we do not issue refunds for airtime purchases.

This did not go anywhere near where i thought this would go. So i’m out about 70 dollars, and have nothing to show for it. Like a told a friend, i went from irritated, to insulted, to angry. I’m totally disappointed in the customer support, and will never use Straight Talk again. And i urge you all to stay away from them.

On the plus side, i ended up going to the T-Mobile store during lunch and found out that there’s a chance i can still get on their old $30 dollar a month unlimited pre-paid plan, which i may be able to go to Walmart (yes, another trip to WM… *shudder*) for and get today. Otherwise i can just order a new SIM online, which will properly fit my phone, and get a plan that’s even cheaper than Straight Talk’s. If i can’t get in on the $30 a month plan, then i’ll go to the new play they offer which is $50 a month, only 5 dollars more than ST.

I’ll let you all know how things go πŸ™‚

Sushi Shift is out of Beta!

I know it’s been a long time since i’ve posted here, and to be honest, i sort of forgot i had this blog.

We’ve recently gotten our game out of beta and we’ve been trying to get the word out. We’ve submitted the app to blogs and review sites, but nothing seems to be helping right now.

So maybe I can use this blog and its limited traffic to maybe give our game some extra needed exposure.

Our game is a puzzle game with unique twist — gravity. Β The link to the game is below πŸ™‚

http://goo.gl/nAdaf — Sushi Shift on Google Play.

Stop Internet Censorship!

I’ve censored the following, in protest of a bill that gives any corporation and the US government the power to censor the internet–a bill that could pass THIS WEEK. To see the uncensored text, and to stop internet censorship, visit:
http://americancensorship.org/posts/739/uncensor

β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ of any β–ˆβ–ˆβ–ˆβ–ˆ is β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ and β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ the β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ of β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ!

β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ is our β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ, β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ is our β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ. Don’t let β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ it β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ us!

We need to fix it, we need to do something!

At the time of this posting, i’m only about half-way done watching this video, but i feel that I need to post this now and share it with everyone i know. What he says sums up what is wrong with our government and makes me want to go to Capitol Hill and kick every politician out of Congress and force change to happen.

Now if you’re more to the Left or more to the Right doesn’t really matter here. No matter what your beliefs in how government works are, they clearly don’t line up with what reality is. Even if you’re not very political and have no interest in politics, what happens in our government DOES affect you.

I’d really like to see some real change happen. Some of the ideas like elections funded from public small amounts only or the ways to reform our government.

Give yourself an hour and a half and watch this.

Deploying Windows Services from TFS

As part of our initiative to automate code deployments, we needed to move windows services from TFS to our test servers. The way we did this before was to have a build stage all the files and then either stop the services on the destination machine manually, copy files, and restart the services, or use a homebrewed application to deploy the service; which is fine and dandy, except that the original developer isn’t with the company anymore and the application is limited in certain ways.

So to solve this, I went ahead and created a new build template that would deploy our windows services from a TFS build.

Some prerequisites:

  • PsExec must be on the build machine
  • Your build service must be an admin on the machine you’re deploying to (to be able to stop and start services)

First, we’ll set up a new Code Activity, it’s very similar to the DeployFiles class i wrote about before

using System;
using System.Activities;
using System.IO;
using System.Text.RegularExpressions;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Build.Workflow.Activities;
using Microsoft.TeamFoundation.Build.Workflow.Tracking;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
namespace BuildProcess.Activities
{
    [BuildActivity(HostEnvironmentOption.Agent)]
    public sealed class DeployWindowsService : CodeActivity
    {
        //Source dir being deployed from
        [RequiredArgument]
        public InArgument<string> SourceDir { get; set; }
        //Destination dir being copied from
        [RequiredArgument]
        public InArgument<string[]> DestinationDir { get; set; }
        //Files to include
        [RequiredArgument]
        public InArgument<string> FileInclusions { get; set; }
        //Folders to include
        [RequiredArgument]
        public InArgument<string> FolderInclusions { get; set; }
        [RequiredArgument]
        public InArgument<string> CollectionName { get; set; }
        public InArgument<string> ConfigLocations { get; set; }
        //globals
        public string fileInclusionPattern = "";
        public string folderInclusionPattern = "";
        protected override void Execute(CodeActivityContext context)
        {
            // Obtain the runtime value of the Text input argument
            string fileInclusions = context.GetValue(this.FileInclusions);
            string folderInclusions = context.GetValue(this.FolderInclusions);
            string configLocations = context.GetValue(this.ConfigLocations);
            string[] destinations = context.GetValue(this.DestinationDir);
            string collectionName = context.GetValue(this.CollectionName);
            DirectoryInfo sourceDir = new DirectoryInfo(context.GetValue(this.SourceDir));
            //parse exclusions, add them to regex patterns
            if (!String.IsNullOrWhiteSpace(fileInclusions))
            {
                string[] fileinarr = fileInclusions.Split(',');
                fileInclusionPattern = "(";
                foreach (string s in fileinarr)
                {
                    fileInclusionPattern += s.ToUpper().Trim().Replace(".", @"\.").Replace("*", @"[a-zA-Z0-9]*") + "$|";
                }
                if (fileInclusionPattern.EndsWith("|"))
                    fileInclusionPattern = fileInclusionPattern.Substring(0, fileInclusionPattern.Length - 1);
                fileInclusionPattern += ")";
            }
            if (!String.IsNullOrWhiteSpace(folderInclusions))
            {
                string[] folderinarr = folderInclusions.Split(',');
                folderInclusionPattern = "(";
                foreach (string s in folderinarr)
                {
                    folderInclusionPattern += s.ToUpper().Trim().Replace(".", @"\.").Replace("*", @"[a-zA-Z0-9]*") + "$|";
                }
                if (folderInclusionPattern.EndsWith("|"))
                    folderInclusionPattern = folderInclusionPattern.Substring(0, folderInclusionPattern.Length - 1);
                folderInclusionPattern += ")";
            }
            foreach (string dir in destinations)
            {
                DirectoryInfo destDir = new DirectoryInfo(dir);
                //Used for debugging, you don't need this, unless you want to display something custom here.
                context.Track(new BuildInformationRecord<BuildMessage>()
                {
                    Value = new BuildMessage()
                    {
                        Importance = BuildMessageImportance.High,
                        Message = "Source: " + sourceDir.FullName +
                            "\r\nDestination: " + destDir.FullName +
                            "\r\nFolder Inclusion Pattern: " + folderInclusionPattern +
                            "\r\nFile Inclusion Pattern: " + fileInclusionPattern +
                            "\r\nFolder Inclusions String: " + folderInclusions +
                            "\r\nFile Inclusions String: " + fileInclusions,
                    },
                });
                CopyDir(sourceDir, destDir);
            }
            //copy config files
            if (!String.IsNullOrWhiteSpace(configLocations))
            {
                string strTFSName = collectionName;
                //set up TFS connectivity
                Uri tfsName = new Uri(strTFSName);
                TfsTeamProjectCollection tfs = new TfsTeamProjectCollection(tfsName);
                VersionControlServer vcs = (VersionControlServer)tfs.GetService(typeof(VersionControlServer));
                //copy config files to proper location
                string timestamp = DateTime.Now.Ticks.ToString();
                string workspacePath = @"C:\temp\TFSConfigDeployment_" + timestamp;
                Workspace ws = vcs.CreateWorkspace("TFSConfigDeployment_" + timestamp, vcs.AuthorizedUser);
                //get the workspace locally
                ws.Map(configLocations, workspacePath);
                ws.Get();
                foreach (string configDir in destinations)
                {
                    CopyDir(new DirectoryInfo(workspacePath), new DirectoryInfo(configDir));
                }
                RemoveWorkSpaceDirectory(workspacePath);
            }
        }
        private void RemoveWorkSpaceDirectory(string workspacePath)
        {
            DirectoryInfo dir = new DirectoryInfo(workspacePath);
            var files = dir.EnumerateFiles();
            foreach (FileSystemInfo info in files)
            {
                string filePath = info.FullName;
                if ((File.GetAttributes(filePath) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                {
                    File.SetAttributes(filePath, FileAttributes.Normal);
                }
            }
            var subDirs = dir.EnumerateDirectories();
            foreach (DirectoryInfo subDir in subDirs)
            {
                RemoveWorkSpaceDirectory(subDir.FullName);
            }
            dir.Delete(true);
        }
        private void CopyDir(DirectoryInfo sourceDir, DirectoryInfo destDir)
        {
            //create destination dir if it doesn't exist
            if (!destDir.Exists)
            {
                destDir.Create();
            }
            // get all files from current dir
            FileInfo[] files = sourceDir.GetFiles();
            //copy ze files!!
            foreach (FileInfo file in files)
            {
                string destFilePath = Path.Combine(destDir.FullName, file.Name);
                if (!String.IsNullOrWhiteSpace(fileInclusionPattern))
                {
                    if (Regex.IsMatch(file.Name.ToUpper(), fileInclusionPattern))
                    {
                        if (File.Exists(destFilePath))
                        {
                            if ((File.GetAttributes(destFilePath) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                            {
                                File.SetAttributes(destFilePath, FileAttributes.Normal);
                            }
                            File.Delete(destFilePath);
                        }
                        file.CopyTo(destFilePath);
                        if ((File.GetAttributes(destFilePath) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                        {
                            File.SetAttributes(destFilePath, FileAttributes.Normal);
                        }
                    }
                }
            }
            // get subdirectories.
            DirectoryInfo[] dirs = sourceDir.GetDirectories();
            foreach (DirectoryInfo dir in dirs)
            {
                // Get destination directory.
                string destinationDir = Path.Combine(destDir.FullName, dir.Name);
                if (!String.IsNullOrWhiteSpace(folderInclusionPattern))
                {
                    if (Regex.IsMatch(dir.Name.ToUpper(), folderInclusionPattern))
                    {
                        // Call CopyDirectory() recursively.
                        CopyDir(dir, new DirectoryInfo(destinationDir));
                    }
                }
            }
        }
    }
}

For the next step, you’ll also want to look at the previous post about deploying files from TFS. After you’ve opened up your ProcessTemplate, you’ll want to have the following arguements:

  • DeploymentDir – In – String[]
  • SourceRootDir – In – String
  • CollectionName – In – String
  • PsExecPath – In – String
  • ServiceName – In – String
  • ServerName – In – String
  • FileInclusions – In – String
  • FolderInclustions – In – String
  • RestartService – In – Boolean – True

Each of these you’ll probably want to add to the Metadata Argument so you can keep your build definitions organized.

And you’ll want to add the following Variable:

  • PsExecResult – Int32 – Revert Workspace and Copy Files…

Under Process > Sequence > Run On Agent > Try Compile, Test, and Associate Changesets and Work Items > Revert Workspace and Copy Files to Drop Location > If Deployment Location is Set you’ll want to place a new Sequence and call it Stop Service, Copy Files, Start Service.

Inside that Sequence you’ll want to place an Invoke Process activity, the new DeployWindowsServices code activity, and an If statement with another Invoke Process activity in the Then clause.

For the first Process Invocation:

Arguements: Β ServerName + ” -s -d net stop ” + ServiceName
DisplayName: Stop Service
FileName: PsExecPath
Result: PsExecResult

For the Deployment Activity:

CollectionName: CollectionName
DestinationDir: DeploymentDir
DisplayName: Deploy Windows Service
FileInclustions: FileInclusions
FolderInclustions: FolderInclusions
SourceDir: Β BinariesDirectory + “\” + SourceRootDir

For the If statement, just check to see if RestartService is set to True, and then enter the values for the second Process Invocation:

Arguements: Β ServerName + ” -s -d net start ” + ServiceName
DisplayName: Start Service
FileName: PsExecPath

*NOTE, THE FOLLOWING SECTION DOES NOT WORK PROPERLY YET*

After the If statement, you’ll want to add in another If, this will check to see if PsExec has failed or not.

Since this isn’t working properly yet, i just check to see if PsExecResult is ‘1’, which it hasn’t been as of this writing. In the Then block, add a Throw activity and have it throw an exception of:

New Exception("PsExecResult: " + PsExecResult.ToString())

Optionally, you can also add WriteBuildMessage and WriteBuildWarning activities to your Invoke Process Activities, these are nice because you can see what the process you are invoking outputs.

New Camera and weekend exploits!

Ever since the trip to North Carolina I’ve been wanting to get a new camera, a DSLR to be precise. I’ve been looking at different cameras for the last week or so, trying to decide between a Canon T2i, a Nikon D90, and a Nikon D7000. Well, earlier this week i finally settled and got the D7000. And thanks to my friend Angela, who hooked me up with a Amazon Prime trial I was able to get 1-day shipping for 4 bucks! Order the camera, get it within the next two days, that was the plan anyway. The first day I get home from work and see a note on my door. The package required a signature on delivery, so they couldn’t just leave the camera on my door step. I guess that’s smart of Amazon to do, require the signature on expensive items. I’d never had that happen before, even on things i’d bought from Amazon. I decided that the second day i’d take a half-day from work so i could catch the delivery truck and get my precious new toy. No such luck. I get there 15 minutes too late and get another note stuck on my door. So, what i did was change the package to be held at the UPS Customer Center, so i could pick it up that day. I didn’t want to wait another day. I NEEDED MY PRECIOUS!

Saturday, after staying out a little late the night before after picking up my camera and going to judo, a few friends and I decided to go out for drinks and eat sushi for dinner, aka an awesome chance to try out my new camera πŸ˜€

Osaka Sushi Restaurant
Osaka is delicous, it’s actually one of my favorite places to get sushi at. But before we get to that we take a little detour. On the way up to Osaka, we get a phone call from Daphne, saying she has to work late. FOR AN ENTIRE HOUR!

 

DSC_0098
Sarah and I take this opportunity to get some delicious iced beverages at the Zen Tea House while we waited.
Abandoned house
After we ate at Osaka, we decided to take a little walk to help our food digest and to use up some time before heading out to Sergio’s World Beers. On the way, we saw this old house in very sad shape.
DSC_0110
After our walk we headed down to the bar where we partook in some delicious beverages. it was hot so a Radler was totally in order πŸ˜€
DSC_0123
Sarah found this adorable beer hidden in one of the fridges. It was quite good actually.
DSC_0118
Mary decided to take a shot and try one of the Fruit Ale’s on draft, it was a Strawberry Ale. Oh man, that was good! Very sweet!Β We stayed for a while chit chatting about this and that and eventually went home, I took a nap on the drive back :3

Sunday. Mary and I decided to meet up at Berheim Forest to practice with our cameras (Mary has a D90). We walked around taking pictures of all sorts of things.
DSC_0152
These geese were protecting their goslings from other geese trying to steal the food people were throwing at them. Geese can be VICIOUS!

 

DSC_0142
Typical, insect doing something with a plant picture. Also, <insert camera talk about blurriness and focus point here>.
DSC_0254
Mary. I don’t care what she says, I like this picture πŸ™‚ After Bernheim we went and ate at Saigon Cafe, which was delicious! I’m really glad i got introduced to Vietnamese food, it’s so good! Then it was off to Heine Bros for some coffee before the trip home.

Once i got to my parents that evening I played with my camera some more, mainly taking pictures of the dogs.
DSC_0277
Nero begging for food. Can’t you tell? He hasn’t eaten in minutes!

DSC_0276
Papa just wanting attention. Who can resist those eyes?

One thing i’ve noticed is that Nero and Papa are very photo conscious. They’re quite good at looking at the camera and being adorable.
DSC_0329
Homer on the other hand, couldn’t give two licks about cameras being pointed at him. He’s too busy making sure there aren’t things that need to be sniffed or chased in the yard.