| |
Disclaimer: Screenscraping results like this probably contravening Google’s Terms of Use (or something) and I do not advocate that you do it – this is purely hypothetical, if I did want to do it, this is how I would go about it  Further Disclaimer: The results page formats could change at any time and may well break this script, if that happens you are on your own (FireBug and some modified regex should help you out). So, if you wanted to get the Google ranking of a bunch of domains when searching for a particular term you could use one of the many SEO page ranking test sites that are available, but these are a pain in as much it they require you to enter the search term and the domain name you are looking for and they give you the ranking (what position in the results the domain name comes). that is fine for individual searches (like what position is kapie.com if I search on ‘Ken Hughes’), but not very good for doing a comparison of multiple domains against the search term. I looked at using Googles Search API to get this info, but unfortunately it only returns 4 or 8 results (it is mainly designed to present some brief results in a box on your website), what I needed was to look at a lot more results (like up to 500)…. Back to my trusty friend – PowerShell… I create a web client, have it download the first X (500) results to the search term, load the link Url and the position into a hashtable and then lookup the hashtable to find the rank position of each of the domain names I am looking for. It was actually pretty easy, the only difficult part was getting the regex(s) correct – Regex is evil, as evil as Perl…. Here is the script code : $domainNames = "google.com", "live.com", "bing.com", "yahoo.com"
$maxResult = 100
$searchTerm = "search"
$urlPattern = "<\s*a\s*[^>]*?href\s*=\s*[`"']*([^`"'>]+)[^>]*?>"
$hitPattern = "<\s*(h3)\sclass=r>(.*?)</\1>"
$wc = new-object "System.Net.WebClient"
$urlRegex = New-Object System.Text.RegularExpressions.Regex $urlPattern
$hitRegex = New-Object System.Text.RegularExpressions.Regex $hitPattern
$urls = @{}
$resultsIndex = 0
$count = 1
while($resultsIndex -lt $maxResults)
{
$inputText = $wc.DownloadString("http://www.google.com/search?q=$searchTerm&start=$resultsIndex")
"Parsing : " + $resultsIndex
$index = 0
while($index -lt $inputText.Length)
{
$match = $hitRegex.Match($inputText, $index)
if($match.Success -and $match.Length -gt 0)
{
$urlMatch = $urlRegex.Match($match.Value.ToString())
if(($urlMatch.Success) -and ($urlMatch.Length -gt 0))
{
$newKey = $urlMatch.Groups[1].Value.ToString()
if(!$urls.ContainsKey($newKey))
{
$urls.Add($newkey, $count)
}
$count++
}
$index = $match.Index + $match.Length
}
else
{
$index = $inputText.Length
}
}
$resultsIndex += 10
}
foreach($domain in $domainNames)
{
$maxPos = -1
foreach($key in $urls.Keys)
{
if($key.Contains($domain))
{
$pos = [int] $urls[$key]
if(($pos -lt $maxPos) -or ($maxPos = -1))
{
$maxPos = $pos
}
}
}
if($maxPos -eq -1)
{
$domain + " : Not Found"
}
else
{
$domain + " : Found at result #" + $maxPos
}
}
Drop me a line in the comments if you find it useful…
GEO 51.4043197631836: -1.28760504722595
Yesterday on Leon's Blog, secretGeek, I noticed they had released v3.4 of TimeSnapper. One of the features that caught my eye was the ability to develop/add plugins to it.
I love plugins, I've written plugins for Windows Live Writer, Outlook, dasBlog, and more. Everything should have an SDK or plugin'able architecture. I championed it at work and we were one of the first Archiving Vendors with a 'real' SDK (I've built demo Vista Gadgets, integration scripts, federated search providers and PowerShell commandlets for it).
Anyway, the TimeSnapper plugin model looked really clean and easy to use. Read the one page description and your ready to go (didn't even download the sample code - it was so clear how things worked there was no need).
I wanted a little play around with it, so I though upload a snapshot to TwitPic would be a good idea. Opening a new project in Visual Studio, adding a reference to the ITimeSnapperPlugin.dll, create a new inherited class from ITimeSnapperPlugin and implement the interface :
#region ITimeSnapperPlugin Members
bool ITimeSnapperPlugin.Configurable
{
get { return true; }
}
void ITimeSnapperPlugin.Configure()
{
System.Windows.Forms.Form frm = new TwitPicPluginConfig();
frm.ShowDialog();
}
string ITimeSnapperPlugin.Description
{
get { return "Uploads snapshots to TwitPic"; }
}
string ITimeSnapperPlugin.FriendlyName
{
get { return "TwitPic Plugin"; }
}
object ITimeSnapperPlugin.HandleEvent(TimeSnapperEvent TimeSnapperEvent, EventArgs args)
{
switch (TimeSnapperEvent)
{
case TimeSnapperEvent.SnapshotSaved :
// upload it it to TwitPic
if (IsTimeToUpload())
{
string fileName = ((TimeSnapperPluginAPI.SnapshotSavedEventArgs)(args)).Activity.Filename;
Debug.WriteLine("Uploading " + fileName + " to TwitPic");
XmlDocument xmlDoc = UploadToTwitPic(fileName);
}
break;
default :
Debug.Assert(false, "Should never occur");
break;
}
return null;
}
TimeSnapperMenuItem[] ITimeSnapperPlugin.MenuItems()
{
return null;
}
Guid ITimeSnapperPlugin.PluginID
{
get { return new Guid("50744334-C5A0-44f1-BE64-5BBF32FDA79D"); }
}
TimeSnapperEvent[] ITimeSnapperPlugin.SubscribesTo()
{
return new TimeSnapperEvent[] { TimeSnapperEvent.SnapshotSaved };
}
All that was required was to give it a new Guid and name/description and then subscribe to the 'SnapShotSaved' event and handle the event when it was triggered. To get the image uploaded to TwitPic I used some code from the excellent Yedda Twitter C# Library (just the stuff for posting image data to a url). That all worked a breeze, but it was sending images (and posting to my twitter account) every 10 seconds (and of course it was hard coded to my username/password) - what was needed was a bit of configuration...
Luckily the plugin model provides an excellent and easy way to do this (set the Configurable property to true, and handle the Configure event). A bit more jiggery pokery, one modal dialog and an XML config file later, it was all working (configurable username, password, twitter message and frequency of updates) - although I really should do something better than store the username/password in clear text in an XML file...
If you want the plugin, just drop this dll into your %install%\plugins folder and restart TimeSnapper.
GEO: 51.4043006896973 : -1.28754603862762
After upgrading to Windows 7 on my laptop I found that I could no longer sync with my Sony Ericsson X1 (Windows Mobile 6.1) Phone. It didn’t even seem to be charging (over USB). Looking in the system Device Manager I found a missing driver for the ‘Generic RNDIS’ device. A bit of goggling uncovered that this was something required for syncing mobile devices. Although there are comments around that Windows Mobile devices are not supported on Windows 7 beta, and a number of people seem to be having the same problem, the good news is it does actually work. I simply downloaded the Windows Mobile Device Center 6.1 for Vista (from Microsoft), installed it and everything was rosy. It installed the driver for the ‘Generic RNDIS’, I connected the phone, it was recognised a Microsoft USB Sync device was installed and it all started working as expected. GEO 51.4043694884482: -1.28756761550903
I am loving the Sticky Notes app in Windows 7. The only issue I have with it is the dreadful font it uses – well my issue is not the font, it is the fact that you cannot change it to something more ‘normal’. I mean, I can easily change the font for Outlook Notes. I know, I know, you want it to look like handwritten notes that you would stick on your fridge at home, but hey – this isn’t my fridge at home, it’s my PC at work (and unfortunately there is no cold beer inside it !!). Eileen Brown confirmed for me that there is no way to change it right now (in the beta – build 7000), but there may be a ‘Non UI’ way of changing it in the official release… GEO 51.4043243116043: -1.28760516643523
Apparently I am rapidly becoming 'Geo Guy'. I seem to be adding Geo / Gps support and plug-ins to everything I use...
I just finished adding 'Insert GPS Link' support to PockeTwit (a great little Windows Mobile twitter client - really, go and get a copy now...) Previously I added GeoRSS support to dasBlog for individual blog posts as well as the RSS feed, and I also added geo microformat support to Windows Live Writer with my 'InsertGeoMicroformat' plugin.
So, what's next - have you got an app that needs Geo / GPS support added ?
GEO 51.4043243116043: -1.28760516643523
Twitter is one of those applications / services that I've had trouble getting to grips with. For me it seems it's like shouting about what you are doing right now to a huge audience that is not listening. Who really cares that @kjhughes is heading to the shops to get some Mint sauce ?? Maybe I'm just not that kind of social animal, maybe I don't have enough friends using it, maybe I should 'but in' to other peoples conversations more, maybe I'm just plain boring... I do see a use for it though (for me). It's a pretty neat way to do some remote control stuff - like set up a Media Center recording, reboot my PC, and also it's a neat way of getting updates, like new blog comment received, TV recording completed and the like.... So, right now I need to get my Outlook addin project completed, but right afterwards I'm planning an app that interfaces to twitter and accepts direct tweets as remote control instructions, and also can update me on specific events. I am also thinking about adding twitter alerts to dasBlog (on comments, posts, errors, daily reports etc) I can see myself getting immersed in this twitter thing... GEO 51.4043197631836: -1.28760504722595
I've been toying around with creating an Outlook addin recently that adds a new panel to the main Outlook inspector window. Actually it is going to be a 'folding' or 'collapsing' windows similar to the docked ToolWindows in Visual Studio. Anyway, the stuff around getting the correct window handle for the Outlook inspector window and resizing it to allow some space to insert my new panel was fairly simple, but I also had to hook into the message look of the window so that I could capture any move or resize messages and so resize things again to accommodate my panel. I had started developing it as an Outlook add-in but to speed things up (and prevent me having to register / unregister the addin between tests etc I decided to develop it as a separate app- I could still hook into Outlook and move things around. The problem came when I was trying to hook the inspector window message loop - it didn't seem to work. I fired up Spy++ and check that the inspector window was getting the messages - which it was - but they were never getting delivered to my hook code. I was using System.Windows.Form.NativeWindow and overriding the WndProc function (see my NativeWindowListener class below). To get the hook in place I was creating a new NativeWindowListener class with the inspector window handle as the parameter. Checking the handles and the delegates etc it all seemed to be correct, I just couldn't fathom why it wasn't getting any of the messages. Then the penny dropped. Outlook is in a separate process... (NativeWindow only works across the current process and window handles that are contained in it). What would be needed in this case is a system wide hook, that requires use of the Win32API and interop. I reckon this is overkill just to save a bit of development pain, so will probably move to something where the Outlook addin dynamically loads the panel in and make something available to have the add-in reload the panel - this should allow me to develop the panel code (the majority of the app) without worrying to much about the Outlook addin side of things. using System;
using System.Windows.Forms;
using System.Text;
namespace Outlook_Subclasser
{
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
internal class NativeWindowListener : NativeWindow
{
// Constant value was found in the "windows.h" header file.
private const int WM_SIZE = 0x0005;
public NativeWindowListener(IntPtr handle)
{
AssignHandle(handle);
}
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
protected override void WndProc(ref Message msg)
{
switch (msg.Msg)
{
case WM_SIZE:
// do your processing in here
break;
default:
break;
}
base.WndProc(ref msg);
}
}
}
and then to use the class you would find the handle of the window you want to subclass and create a new NativeWindowsListener passing in that handle to the constructor. Note - this does not cover a number of aspects around releasing handles etc - you will want to make sure these are covered off... MyForm myForm = new MyForm(); NativeWindowListener nwl = new NativeWindowListener(myForm.Handle);
GEO 51.4043197631836:-1.28760504722595
I bought one of these about 4 years ago - initially loved it, but it chewed through batteries at an incredible rate, so after a few months of use and another instance of needing fresh batteries (and none being available) it sat in a drawer for some (considerable) time. Now that I am a (proud ??) owner of an Xbox 360, I wanted to rationalize all our disparate remotes - my suggestion of buying a Harmony One (currently £88 on amazon) was met with "What! we already have one of those - that blue thing that lights up" from Sarah... She's right (of course) so I dug it out and brought it back into play - reprogrammed the devices for the new HD TV and DVD player, it still had the Pace Twin PVR programmed and bingo it worked again. I wanted to be 100% sure it would do everything I needed (I guess I was looking for an excuse to buy a Harmony), so I looked at all the functions available and programmed - I found that the PVR button (which should bring up the recording library) didn't work correctly, but a bit of googling sorted that (Key Reprogramming - code 00536) and then I started considering the Xbox. There is a little info around about getting a Kameleon working with your Xbox. I tried this advice for the 8060 (6 in 1), but it didn't work (apparently the 4 in 1 does not have the modem programing capability), so eventually I emailed One For All support. A pretty quick response indicated that yes it could support the Xbox, but would need sending back for reprogramming (at a cost of £10, as I was outside the first year of purchase / warranty). This seemed like a fair price so I have just sent it off. I'll post on the 'richness' of the Xbox support (and the best code) when I get it back. Codes that might be useful : - Vistron 32" HD TV - Model VIS032HDID : 0587
- Yamada DVDSlim 5520 : 0665
- Xbox 360 : ????
- Pace Twin Freeview Recorder : 1423(with PVR key reprogrammed to function code 00536)
GEO 51.4043197631836: -1.28760504722595
So before Christmas I bought an Xbox 360 (60GB HDD version). Reasoning was "it will be good for the kids hand eye coordination" which in reality was a thinly veiled "I want one and the kids might like it too" (as it turns out they don't)... Anyway, one of the first tasks was networking it -linking it to the home PC and DSL router. I read a bunch of stuff online about the Xbox wireless adapter being over the top and the same could be done with any old wireless router that you had lying around around - so, having an old WRT54G lying around that was my first step. It was pretty successful in that I already had reflashed it with DD-WRT firmware and it was pretty simple getting the wireless side acting as a client to my Linksys WAG160N and the unit bridging connections from the LAN side. Now this configuration requires that you set the LAN side side up on a different subnet to the existing (wireless) network - otherwise the routing gets screwed up. i.e. The LAN side might be on 192.168.2.X while the existing router is on 192.168.1.x (this is what routing is all about - Xbox gets an address of 192.168.2.x and a default GW of 192.168.2.1, the router bridges any data sent to 192.168.2.1 over to the wireless side which has an address of 192.168.1.xxx and a default GW of of 192.168.1.1 that then bridges it over to the WAN side of the DSL connection that then routes it to the Internet... This worked fine initially, I could connect to Xbox Live and the like, but where it fell down was on the connection to the Media Centre PC - for some reason any Media Centre PC must be on the same segment as the Xbox (which is not the case here as Xbox = 192,168.2.x and MCPC = 192.168.1.x). It does this to make 'discovery' of the MCPC easy fro an Xbox, but I am surprised (read disappointed) that there is not an advanced / manual setting that allows the user to specify the IP address. I reckon this is around needing a good quality network connection between the devices (which is generally the case if they are on the same subnet, but not always when on different subnet's), but a simple disclaimer could have sufficed.... It forces users into either running an Ethernet cable, buying a wireless adapter or living without media centre capability. Anyway I caved and bought an Xbox wireless adapter, but the speeds are still not up to streaming HD TV, so now I'm considering powerline adapters (Homeplug) - be glad to hear of any experiences you have with this... GEO 51.4043197631836: -1.28760504722595
I've had a lot of interest in my SMS Gateway app since this post. SMS gateway consist of two components :
SMS Gateway Addin This is an Outlook addin that adds a new toolbar to your Outlook instance. The toolbar allow the user to choose a mobile / cellphone number (from their contacts) and enter a message. When they hit the enter key after the message (or click 'Send') a new Task is created when has a subject of 'SECRETCODE' and the mobile / cellphone number and the details being the text of the message.
At some stage this Outlook Task is synchronized (over ActiveSync / Direct Push) to a Windows mobile device...
SMSGateway This is a small app running on a Windows Mobile device that every 15 seconds checks through the tasks. If it finds any tasks that have a subject beginning with SECRETCODE then it parses out the mobile / cellphone number and sends the message text (from the Task details) to that mobile / cellphone number via SMS. Note: the SECRETCODE word is configurable.
Why develop this ? The purpose of this app was really to allow me to send SMS messages easily from Outlook without having to sign up for (and pay for) a web to SMS service (I already get 100's of free SMS messages with my mobile / cellphone package).
The application is free for anyone to use (drop me a line - in the comments - if you do use it...)
Windows Mobile CAB file (copy the file to your Windows Mobile device and click on it) : SMSGatewayMobile.CAB Setup file for the Outlook 2003 Add-in (Outlook 2007 coming soon) : SMSGatewayAddin2003.msi Source for both the applications : SMSGateway.zip (includes test Outlook 2007 addin code)
I'd be really interested to hear from anyone using this.... post in the comments...
GEO 51.4043197631836: -1.28760504722595
In an effort to get my blogging back on track, and show some activity on my website, this is a quick post to wish everyone a prosperous 2009 !! I have a number of posts planned, including more details on the Outlook to Windows Mobile Gateway SMSing project, more details on my Homebrew Home Server (after a lot of traffic from Alex Kuretz over at www.mediasmartserver.net) and some bits on PowerShell, WCF and more... Happy New Year... GEO 51.4043197631836: -1.28760504722595
I've had two problems recently and I was looking to buy (hopefully) one piece of software to solve them both... Problem 1 : The mp4 files output by my Sanyo HD camcorder have the video and audio out of sync with one another when I play them in WMP (which I have to do as QuickTime crashes on every 64 bit machine I've tried it on). I wanted something to convert it to .wmv format that could be played by any windows machine with a default install of WMP. Problem 2 : I needed to get some of my DVD films into a format (and size) that could be played by my Windows Mobile 6 phone. I thought/think I need something to convert .vob files to .wmv format. I tried a couple of apps that claimed to do 'any to any' conversion and transcoding - no joy. I then came across Prism Video Convertor which also claimed to do the 'any to any' conversion and transcoding. I downloaded an evaluation copy and set to trying it out with the two cases / problems I needed solved. Problem 1 - not problem, worked just fine !! Problem 2 - no joy, blank screen when playing the output file :-( Searched through the support forums and FAQs, again no joy. By this stage I'm thinking it's probably just me being stupid or choosing the wrong settings/codec/encoder or the like (I don't profess to know much about this technology). I'm excited about the application, it's solved my first problem, just show me the second one working and I'm sold (and I'll rave about it to everyone I know..) Time for the last resort - open their support page and fill in the form for a support case - enter the details, hit submit, bam "No support contract found, please buy a support contract". The product is around $18, a 'Silver' support contract will cost me another $8, not much, but... I don't want to throw away $8 for them not to fix the problem (it's supposed to be a free trial - right), so I shimmy over to their 'Reasonable Service Terms' (their words not mine).. Incredulous - the wording, the attitude, the sheer abrasiveness of it all. It made me think that they :- - Are setting my expectation that I'm unlikely to get a resolution
- Are going to refuse point blank if there is even a chance of it not being their software
- Want me to prove (beyond reasonable doubt) that it's their software at fault before they would even consider helping me.
- Don't want to spend more than 10 minutes on a support case
- Don't really want me as a customer
I am all for setting expectations and outlining boundaries/limits but, in my opinion, this is completely the wrong way to do it. Certainly as someone who is putting in the effort to trial their software, I do not want to have to pay for the privilege especially when I know it may not even do what I want meaning I may not even buy the application. You can also bet that when they say... - It also does not guarantee that they will be able to solve all problems. It means only that they will do their best.
...their definition of 'do their best' will be completely different from mine. GEO 51.4043197631836: -1.28760504722595
|
|
|
|
|
|