Twitter Search feed on SharePoint 2010 using RSS Feed Viewer Webpart

Our company uses a SharePoint blog site to make it easy for our attendees to TechEd to share their session notes and other information. This year we wanted to add a twitter search feed for auteched to the front page to make it easier to view what’s going on.

As Twitter provides with their search api, an rss feed of search queries, an easy way to do this was using the RSS Viewer web part built into SharePoint 2010.

Here’s how we set it up:

RSS Feed Url

http://search.twitter.com/search.rss?q=auteched

Xslt

I prefer to keep my xslt sheets separate from the webpart as it makes it easier to edit them and reuse the styles.

Here’s the xslt we ended up using:

<?xml version="1.0" encoding="utf-8" ?>
    <xsl:stylesheet
     version="2.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:google="http://base.google.com/ns/1.0"
    >
    <xsl:output method="html" />
    <xsl:template match="rss/channel">
    <link rel="stylesheet" type="text/css" href="/SiteAssets/XSLT/templates/twittersearch.css" />
    <xsl:apply-templates select="item" />
    </xsl:template>
    <xsl:template match="item">
        <xsl:variable name="twittername">
            <xsl:value-of select="substring-before(author,'@twitter.com')" />
        </xsl:variable>
        <xsl:variable name="fullname">
            <xsl:value-of select="substring-after(author,'@twitter.com ')" />
        </xsl:variable>
        <xsl:variable name="authorurl">
            http://twitter.com/<xsl:value-of select="$twittername" />
        </xsl:variable>
        <xsl:variable name="imagelink">
            <xsl:value-of select="google:image_link" />
        </xsl:variable>
        <xsl:variable name="utcpubdate">
            <xsl:value-of select="pubDate" />
        </xsl:variable>
        <xsl:variable name="localpubdate">
            <span class="utcdate"><xsl:value-of select="$utcpubdate"/></span>
        </xsl:variable>
        <div class="twit_holder">
            <div class="twit_img"><img src="{$imagelink}" class="twit_img" /></div>
            <div class="twit_content">
                <a class="twit_author" target="_blank" href="{$authorurl}" title="{$fullname}">
                    @<xsl:value-of select="$twittername" />
                </a>
                <span class="authorname">
                    <xsl:value-of select="$fullname" />
                </span>
                <div class="twit_tweet">
                    <xsl:value-of select="description" disable-output-escaping="yes"/>
                </div>
                <div><a target="_blank" href="{link}"><xsl:value-of select="$localpubdate" /></a></div>
            </div>
        </div>
    </xsl:template>
</xsl:stylesheet>

Css

Then it was just a matter of styling it with some css. I don’t claim to be the most amazing css guru, but I’m happy with how it turned out. Here’s the css used:

.twit_tweet a {
    font-size: 13px;
    color: #111111;
    width: 400px;
}
.twit_date {
    font-size: 10px;
    color: #333333;
    font-style: italic;
}
.twit_author {
    font-size:16px;
    font-weight:bold;
}
.twit_open {
    font-size: 8px;
    color: #333333;
}
.twit_holder {
    padding-bottom: 15px;
    width: 260px;
}

.twit_img{
    width: 48px;
    height: 48px;
    float: left;
}
.authorname{
    font-style:oblique;
    font-size: 10px;
    color: silver;
}
.twit_content{
    min-height:48px;
    margin-left: 58px;
    position:relative;
}

End result

image

Improvements

The timestamp from the twitter api is in GMT. It would be great to be able to convert this to the local time of the user via some javascript. That was outside the scope of this task however.

Why can’t the world be more like this error message?

Supermarkets vs. Takeaway. (File Systems vs. Search)

One of the things I think people have the hardest time getting their head around when switching from a file system based document storage solution to a search oriented solution is why. “I’ve already learnt where everything is. I don’t need to search for what I need. I can just go to where it is. Why should I change?”

Another problem is that search is called search.

search –verb
to go or look through (a place, area, etc.) carefully in order to find something missing or lost

That does not sound easy to me. Search should really be called ask or request.

An analogy that I think works to answer this question is the difference in efficiency between going to a super market and getting takeaway food.

Supermarkets

The super market is the filing system. Each file is a product, and they’ve been sorted into aisles and sections that group all the like products together, based on some established guidelines (hopefully) on where things should go.

I’m going shopping. This is my regular supermarket, so I know where most things I usually need are. I can walk in, walk to the aisle I need and pretty quickly get the product (file) I’m looking for. If I’m not sure exactly which brand I’m after, I can still pretty quickly find it by going to the right place.

Sometimes I need to find something I don’t usually buy. If I know my supermarket well, I can usually figure out where it should be and start looking, but then sometimes they’ve put it in that organic section instead of where I’d expect it, so I better check there as well. But then maybe it’s under gluten free…

and of course, the level of organisation varies…

And then what about when I have to go to the supermarket across town? I’ve got no idea how this place is organised. I might need to check a map (if I can find that), or else maybe I could ask someone and have them help me find something. I’m not sure they’re going to want to help me with all my shopping though. If I want to keep coming here, I’m going to have to make a concerted effort to figure out where everything I need lives.

And then I just have to pray the supermarket doesn’t decide to reorganise…

That starts to sounds a lot more like searching to me; manually.

Takeaway Food

After all that shopping, I’ve decided I don’t have any energy left to make dinner, so I’m going to get takeaway.

So I walk up to the counter, and I ask for what I want, and it is presented to me.

lunch!

This is what search gives you! You place your order, and you receive your item. Naturally different implementations of search are better or worse at giving you what you asked for, sometimes they mix up your order.

But overall, provided the menu is clear, and your order is coherent, they usually get it right. And you can always ask again if they don’t.

If I’m in another city and looking for food, I can go to any takeaway store and ask for what I want. I don’t need to know where they keep their food, or how they organise it. The experience for me, is the same where ever I go.

Renaming folders in a Document Library with PowerShell

After a bit of stuffing round with Rename-Item (don’t try) I discovered this is actually pretty easy.

You just need to use the .MoveTo() method:

PowerShell
  1. #get the folder
  2. $folder = $web.GetFolder("http://sharepoint/DocLib/FolderName")
  3. #set the path
  4. $path = "http://sharepoint/DocLib/NewFolderName"
  5. #move the folder to the new path
  6. $folder.MoveTo($path)

More info

Mobile Devices not able to Sync after upgrading to Exchange 2010

After moving a mailbox to our Exchange 2010 server, we discovered that an iPhone was unable to sync mail to it.

A quick test at: https://www.testexchangeconnectivity.com/ indicated this error:

Exchange Activesync returned an HTTP 500 response. 

The error points to a permissions issue, which was misleading.

Google pointed me at this: http://msexchangeteam.com/archive/2009/12/08/453472.aspx which suggests it maybe a proxying issue.

This didn’t seem to be our issue, so eventually I found this article: http://blog.sallarp.com/exchange-2010-iphone-activesync-issue/ by Björn, you can always depend on a Björn.

Björn pointed me to this http://www.ffoutpost.net/2009/11/10/resolve-issues-with-activesync-not-working-in-exchange-2010 which resolved the issue.

  1. Goto Active Directory Users and Computers > View > (enable) Advanced Features
  2. Open the Properties of the user in question.
  3. Goto the Security tab and select Advanced.
  4. In the default Permissions tab enable the "Include inheritable permissions from this object’s parent"
  5. Wait for the AD to replicate and try to sync the iPhone again. If all goes well, it should have fixed the syncing permission issue.

Office 2010 and SharePoint 2007 – Opening files

When opening documents stored on a SharePoint 2007 site with Office 2010 beta 2 you will get an error stating that office was unable to open the document.

To get around this issue you need to set up a "fake proxy" in internet explorer:

  • In Internet Explorer from the Tools menu select Internet Options.

 

  • On the Connections tab open LAN settings tick the Use a proxy server for your LAN and enter 127.0.0.1 as the Address.
  • Open the Advanced settings and enter * in the exceptions box.

 

Unfortunately this opens a pretty large security hole in IE by detecting every site as local intranet.

You can get around this by disabling automatic intranet detection:

  • On the Security tab select Local Intranet and open the Sites window.
  • Untick the Automatically detect intranet network box.

Nine Thousand Nine Hundred and Ninety Nine more bottles of beer on the wall…

I think this may possibly be the greatest SQL I’ve written all year, if not ever.

First off a function to convert numbers to words:

CREATE FUNCTION [dbo].[num_to_text] (@n int) returns varchar(max)
begin
declare @result varchar(max)

SELECT @result = case
    when @n = 1 then ‘One’
    when @n = 2 then ‘Two’
    when @n = 3 then ‘Three’
    when @n = 4 then ‘Four’
    when @n = 5 then ‘Five’
    when @n = 6 then ‘Six’
    when @n = 7 then ‘Seven’
    when @n = 8 then ‘Eight’
    when @n = 9 then ‘Nine’
    when @n = 10 then ‘Ten’
    when @n = 11 then ‘Eleven’
    when @n = 12 then ‘Twelve’
    when @n = 13 then ‘Thirteen’
    when @n = 14 then ‘Fourteen’
    when @n = 15 then ‘Fifteen’
    when @n = 16 then ‘Sixteen’
    when @n = 17 then ‘Seventeen’
    when @n = 18 then ‘Eighteen’
    when @n = 19 then ‘Nineteen’
    when @n > 19 then
        case
                when @n BETWEEN 20 AND 29 then ‘Twenty’ +
                    case
                        when cast(RIGHT(cast(@n AS varchar),1) AS int) = 0 then
                        else ‘ ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar),1) AS int))
                    end
                when @n BETWEEN 30 AND 39 then ‘Thirty’ +
                    case
                        when cast(RIGHT(cast(@n AS varchar),1) AS int) = 0 then
                        else ‘ ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar),1) AS int))
                    end
                when @n BETWEEN 40 AND 49 then ‘Fourty’ +
                    case
                        when cast(RIGHT(cast(@n AS varchar),1) AS int) = 0 then
                        else ‘ ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar),1) AS int))
                    end
                when @n BETWEEN 50 AND 59 then ‘Fifty’ +
                    case
                        when cast(RIGHT(cast(@n AS varchar),1) AS int) = 0 then
                        else ‘ ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar),1) AS int))
                    end
                when @n BETWEEN 60 AND 69 then ‘Sixty’ +
                    case
                        when cast(RIGHT(cast(@n AS varchar),1) AS int) = 0 then
                        else ‘ ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar),1) AS int))
                    end
                when @n BETWEEN 70 AND 79 then ‘Seventy’ +
                    case
                        when cast(RIGHT(cast(@n AS varchar),1) AS int) = 0 then
                        else ‘ ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar),1) AS int))
                    end
                when @n BETWEEN 80 AND 89 then ‘Eighty’ +
                    case
                        when cast(RIGHT(cast(@n AS varchar),1) AS int) = 0 then
                        else ‘ ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar),1) AS int))
                    end
                when @n BETWEEN 90 AND 99 then ‘Ninety’ +
                    case
                        when cast(RIGHT(cast(@n AS varchar),1) AS int) = 0 then
                        else ‘ ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar),1) AS int))
                    end
            when @n BETWEEN 100 AND 999 then
                dbo.num_to_text(cast(LEFT(cast(@n AS varchar), 1) AS int)) + ‘ Hundred’ +
                case RIGHT(cast(@n AS varchar), 2)
                    when ’00′ then
                    else ‘ and ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar), 2) AS int))
                end
            when @n BETWEEN 1000 AND 9999 then
                dbo.num_to_text(cast(LEFT(cast(@n AS varchar), 1) AS int)) + ‘ Thousand’ +
                case RIGHT(cast(@n AS varchar), 3)
                    when ’000′ then
                    else ‘ ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar), 3) AS int))
                end
            when @n BETWEEN 10000 AND 99999 then
                dbo.num_to_text(cast(LEFT(cast(@n AS varchar), 2) AS int)) + ‘ Thousand’ +
                case RIGHT(cast(@n AS varchar), 3)
                    when ’0000′ then
                    else ‘ ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar), 3) AS int))
                end
            when @n BETWEEN 100000 AND 999999 then
                dbo.num_to_text(cast(LEFT(cast(@n AS varchar), 3) AS int)) + ‘ Thousand’ +
                case RIGHT(cast(@n AS varchar), 3)
                    when ’00000′ then
                    else ‘ ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar), 3) AS int))
                end
            when @n BETWEEN 1000000 AND 9999999 then
                dbo.num_to_text(cast(LEFT(cast(@n AS varchar), 1) AS int)) + ‘ Million’ +
                case RIGHT(cast(@n AS varchar), 5)
                    when ’00000′ then
                    else ‘ ‘ + dbo.num_to_text(cast(RIGHT(cast(@n AS varchar), 6) AS int))
                end
         else ‘really big number’
        end
    else
end

RETURN @result
end

 

Result:

Not brilliant, not perfect, but useful. Where it really becomes a work of art though is in the application:

CREATE procedure [dbo].[sing](
    @i integer = 100,
    @container_plural varchar(max) = ‘bottles’,
    @container_singular varchar(max) = ‘bottle’,
    @contents varchar(max) = ‘beer’
)
AS
declare @s varchar(max)
declare @container varchar(max)
SET @s = dbo.num_to_text(@i)
SET @container = @container_plural

IF @i = 1 SET @container = @container_singular

while @i > 0
begin
        print @s + ‘ ‘ + @container + ‘ of ‘ + @contents + ‘ on the wall,’
        print @s + ‘ ‘ + @container + ‘ of ‘ + @contents + ‘,’
        print ‘Take one down, pass it around,’
        SET @i = @i - 1
        IF @i = 1 SET @container = @container_singular
                SET @s = dbo.num_to_text(@i)
        IF @i = 0
        begin
            print ‘No more ‘ + @container_plural + ‘ of ‘ + @contents + ‘ on the wall!’
        end
        else
        begin
                print @s + ‘ more ‘ + @container + ‘ of ‘ + @contents + ‘ on the wall!’
        end
        print
end

 

Result:

Why Bing Sucks

Outlook 2010 has a neat little "Map It" button next to addresses in your contact form.

I thought I’d give it test and tried to Map my parents address in the charming seaside town of Mornington:

Unfortunately the mapping seems a little off… they did get a charming little sea side town…

But on consulting with Google maps, we find that this charming little sea side town, is quite possibly as far as you can get from Mornington and still be in Australia.

I guess we should give them points for hitting the right landmass.

Debugging Windows Server 2008 crash dumps

  1. Download debugging tools from Microsoft:
    x64 – http://www.microsoft.com/whdc/devtools/debugging/install64bit.mspx
    x83 – http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx
  2. Install the complete tools.
  3. Right click WinDbg and Run as administrator.
  4. Set the Symbol File Path from the File menu.
  5. Set the path as: SRV*c:\temp\symbols*http://msdl.microsoft.com/download/symbols

    You may have to wait a little while for the symbols to load before you can proceed with the next step.
  6. Open the minidump file
  7. The file is usually located in %windir%\Minidump
  8. Wait for the file to finish loading. You will see a Bugcheck Analysis screen once it is finished loading.
  9. To get detailed information of the crash, click !analyze -v.

 

This can give you further information about a crash or blue screen which may point you at a driver or application that is causing the crash.

Remove missing devices from Device Manager

Sometimes you can have issues caused by devices that have been physically removed from a system, but are still configured.

It is not possible to normally see these devices in the Device Manager unless you have set a system variable.

The variable you need to set is DEVMGR_SHOW_NONPRESENT_DEVICES and it needs to be set to 1 (true).

You can do this quickly and easily via the command prompt:

  1. Right click Command Prompt and select Run as administrator
  2. Type: set DEVMGR_SHOW_NONPRESENT_DEVICES=1 and press Enter.
  3. Type: start DEVMGMT.MSC and press Enter:
  4. In Device Manager click View and click Show hidden devices:
  5. Non present devices will have a faded icon. Right click and select Uninstall:
Follow

Get every new post delivered to your Inbox.