"It’s Nice to Be Important, But It’s More Important to Be Nice"
05
Feb

Twitter And SharePoint Custom Timer Job with some Linq to XmL

Inspiration, SharePoint 2007, WSS 3.0 | 1 Comment »

I’ve been fooling around with the Twitter API and how wanted to test how I could connect it to SharePoint. After som inspiration from Andrew Connell blog post about Custom Timer Jobs for SharePoint i’ve decided to give it a try. This function will update a list with tweets every 5 minutes so it wont go over the Rate Limit set for the Twitter API.

I’m using VS 2008 with VSeWSS 1.3 / WSS3.0

First I created a List called Twitter in the rootweb of my Wss3.0 installation and created the following columns:

Title  Single line of text  
Link  Single line of text 
Published  Single line of text 
Uri  Single line of text 
TweetAuthor  Single line of text 
TweetId  Single line of text 
TweetImage  Single line of text

After this I started an VSeWSS SharePoint Empty Project named TaskLoggerJob and created a Class with the same name TaskLoggerJob: and a small class named Tweets to handle the Tweet properties:

Tweets.cs

using System;
using System.Collections.Generic;
using System.Text;

namespace TaskLoggerJob
{
    class Tweets
    {
        public string Id { get; set; }
        public DateTime Published { get; set; }
        public string Link { get; set; }
        public string Image { get; set; }
        public string Title { get; set; }
        public string Author { get; set; }
        public string Uri { get; set; }
    }
}

———————–

TaskLoggerJob.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint;
using System.Xml.Linq;

namespace TaskLoggerJob
{
    class TaskLoggerJob : SPJobDefinition
    {
        List<Tweets> m_tweets;
        /// <summary>
        /// Initializes a new instance of the TaskLoggerJob class.
        /// </summary>
        public TaskLoggerJob()
            : base()
        {
        }

        /// <summary>
        /// Initializes a new instance of the TaskLoggerJob class.
        /// </summary>
        /// <param name=”jobName”>Name of the job.</param>
        /// <param name=”service”>The service.</param>
        /// <param name=”server”>The server.</param>
        /// <param name=”targetType”>Type of the target.</param>
        public TaskLoggerJob(string jobName, SPService service, SPServer server, SPJobLockType targetType)
            : base(jobName, service, server, targetType)
        {
        }

        /// <summary>
        /// Initializes a new instance of the TaskLoggerJob class.
        /// </summary>
        /// <param name=”jobName”>Name of the job.</param>
        /// <param name=”webApplication”>The web application.</param>
        public TaskLoggerJob(string jobName, SPWebApplication webApplication)
            : base(jobName, webApplication, null, SPJobLockType.ContentDatabase)
        {
            this.Title = “Task Logger”;
        }

        /// <summary>
        /// Executes the specified content db id.
        /// </summary>
        /// <param name=”contentDbId”>The content db id.</param>
        public override void Execute(Guid contentDbId)
        {
            getTweets();
            // get a reference to the current site collection’s content database
            SPWebApplication webApplication = this.Parent as SPWebApplication;
            SPContentDatabase contentDb = webApplication.ContentDatabases[contentDbId];

            // get a reference to the “Tasks” list in the RootWeb of the first site collection in the content database
            SPList taskList = contentDb.Sites[0].RootWeb.Lists["Twitter"];
            SPListItemCollection items = taskList.Items;
            // Clear Twitter List from objects
            List<int> listaIds = new List<int>(items.Count);

            for (int i = 0; i < items.Count; i++)
            {

                listaIds.Add(items[i].ID);

            }

            for (int i = 0; i < listaIds.Count; i++)
            {

                taskList.GetItemById(listaIds[i]).Delete();

            }

            taskList.Update();

            foreach (Tweets item in m_tweets)
            {
                // create a new tweet, and update the item
                SPListItem newTask = taskList.Items.Add();
                newTask["Title"] = item.Title;
                newTask.Update();
                // Add data to new item..
                SPListItem existingTask = taskList.GetItemById(newTask.ID);
                existingTask["TweetAuthor"] = item.Author;
                existingTask["Link"] = item.Uri;
                existingTask["Published"] = item.Published.ToString();
                existingTask["TweetId"] = item.Id;
                existingTask["TweetImage"] = item.Image;
                existingTask.Update();
            }

            taskList.Update();
             
        }

        public void getTweets()
        {
            XDocument feed = XDocument.Load(“http://search.twitter.com/search.atom?q=from:chrperss“);

            XNamespace atomNS = “http://www.w3.org/2005/Atom“;

            m_tweets = (from tweet in feed.Descendants(atomNS + “entry”)
                        select new Tweets
                        {
                            Title = (string)tweet.Element(atomNS + “title”),
                            Published = DateTime.Parse((string)tweet.Element(atomNS + “published”)),
                            Id = (string)tweet.Element(atomNS + “id”),
                            Link = tweet.Elements(atomNS + “link”)
                            .Where(link => (string)link.Attribute(“rel”) == “alternate”)
                            .Select(link => (string)link.Attribute(“href”))
                            .First(),
                            Image = tweet.Elements(atomNS + “link”)
                            .Where(link => (string)link.Attribute(“rel”) == “image”)
                            .Select(link => (string)link.Attribute(“href”))
                            .First(),
                            Author = (string)tweet.Element(atomNS + “author”).Element(atomNS + “name”),
                            Uri = (string)tweet.Element(atomNS + “author”).Element(atomNS + “uri”),
                        }).ToList<Tweets>();
        }
    }
}

————————————-

After this I created a FeatureReceiverClass to get it all going: Named it TaskLoggerJobInstaller

TaskLoggerJobInstaller.cs

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;

namespace TaskLoggerJob
{
class TaskLoggerJobInstaller : SPFeatureReceiver
{
const string TASK_LOGGER_JOB_NAME = “TaskLogger”;

///
/// Occurs after a Feature is installed.
///
///
An object that represents the properties of the event. public override void FeatureInstalled(SPFeatureReceiverProperties properties)
{
}

///
/// Occurs when a Feature is uninstalled.
///
///
An object that represents the properties of the event. public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
{
}

///
/// Occurs after a Feature is activated.
///
///
An object that represents the properties of the event. public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
// register the the current web
SPSite site = properties.Feature.Parent as SPSite;

// make sure the job isn’t already registered
foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)
{
if (job.Name == TASK_LOGGER_JOB_NAME)
job.Delete();
}

// install the job
TaskLoggerJob taskLoggerJob = new TaskLoggerJob(TASK_LOGGER_JOB_NAME, site.WebApplication);

SPMinuteSchedule schedule = new SPMinuteSchedule();
schedule.BeginSecond = 0;
schedule.EndSecond = 59;
schedule.Interval = 5;
taskLoggerJob.Schedule = schedule;

taskLoggerJob.Update();
}

///
/// Occurs when a Feature is deactivated.
///
///
An object that represents the properties of the event. public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
SPSite site = properties.Feature.Parent as SPSite;

// delete the job
foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)
{
if (job.Name == TASK_LOGGER_JOB_NAME)
job.Delete();
}
}
}
}

————————-

Then I’ve had to modify the Feature.xml file that is created when we add a new feature to the project through the “WSP View”, so it points to the ReceiverClass we just created and ReceiverAssembly

<?xml version=”1.0″ encoding=”utf-8″?>
<Feature Id=”3901dc1f-5b79-4e70-96af-f4ed32d3da0e” Title=”TaskLoggerJob” Scope=”Site” Version=”1.0.0.0″ Hidden=”FALSE” DefaultResourceFile=”core” xmlns=”http://schemas.microsoft.com/sharepoint/” ReceiverAssembly=”TaskLoggerJob, Version=1.0.0.0, Culture=neutral, PublicKeyToken=53b5e25b60ede585″ ReceiverClass=”TaskLoggerJob.TaskLoggerJobInstaller”>
  <ElementManifests />
</Feature>

The Custom Timer Job is complete and should be able to deploy, now after 5 minutes the Twitter List should be filled with 15 blogposts.

note: Remember that you might have to restart the SharePoint Timer Service when you make changes since it keeps a chached version of you assemblis. Also remember to change the guids and Publickeytoken if you copy this.

And if it doesnt work? don’t blame me cause Im a noob :D


10
Nov

WSS 3.0: View and edit Search Scopes in Search Administration

SharePoint 2007, WSS 3.0 | No Comments »

Just installed Search Server 2008  Express for your WSS 3.0 app?? And now you want to add a new scope to the search dropdown for you FARM? But you can’t seem to find the scopes on the Search Administration site? Well Daniel Berg gave me a good tip and told me that the link to the “View Scopes” page in Search Administrator seems to be hidden.. and to access the page you need to know the exact URL which he provided:

http://ExampleSite:PortToSearchAdministration/ssp/admin/_layouts/ViewScopesSSP.aspx?Mode=ssp

Just add this link to you “Links” Web Part on the Search Administration Start Page for future use. This will make it possible to Manage Search Scopes for your WSS farm.

If you want to edit your Search Scope the old fashion way then it’s Site Actions -> Site Settings -> Site Collection Administration -> Search Scopes


16
Oct

SharePoint End User FAQ!

SharePoint 2007 | 2 Comments »

Over at http://www.sharepoint-training-videos.com they have created a SharePoint End User FAQ which is very helpfull for the first timers of MOSS 07 and more experienced users.

Direct Link to FAQ: http://www.sharepoint-training-videos.com/SharePoint_EndUser_FAQ_Guide.html

Topics covered in the FAQ are:

  1. How can I upload multiple documents into a document library?
  2. How can I save a document directly into SharePoint Library?
  3. How can I check-in & check-out a document?
  4. How can I view an old version of a document?
  5. How do I change a view?
  6. How do I change the properties on a document or item in a list?
  7. How do I filter a list or a set of documents?
  8. How do I sort a list or a set of documents?
  9. How do I setup alerts on a document?
  10. How do I sent a documents to others?
  11. How do I attach a document in email directly from a document library?
  12. How do I move files between folders, document libraries or sites?
  13. How do I search on documents?
  14. How do I navigate around SharePoint?
  15. How do I hide a file in SharePoint?
  16. How do I search on the properties of a file?
  17. How do I create a shortcut to a SharePoint document library on my desktop?

The site also has educational videos that are very usefull for End Users and Administrators.

Videos direct link: http://www.sharepoint-training-videos.com/Sharepoint_Training_Videos_Course_Outline.html

Enjoy!


15
Sep

Remove Broken Web Part?

SharePoint 2007, SharePoint 2010 | 1 Comment »

There’s an easy trick to get to the web part maintentance page.

If your malfunctioning page is:

http://testsite.com/pages/default.aspx

simply add a querystring onto the end of the URL

http://testsite.com/pages/default.aspx?contents=1


25
Aug

Free SharePoint Web Parts!

SharePoint 2007, SharePoint 2010 | No Comments »

http://www.amrein.com/apps/page.asp?Q=572

Check it out!


17
Aug

No time to explain SharePoint to a user?

SharePoint 2007 | No Comments »

http://www.microsoft.com/video/en/us/details/76e8d3af-c2bd-42a6-bb12-befcbd041bf1

check out this video posted on the SharePoint Team Blog, SharePoint in plain english. and then find out more on commoncraft.com :D


10
Jul

SharePoint Dev Wiki

SharePoint 2007 | No Comments »

http://www.sharepointdevwiki.com/display/public/Welcome

Check it out :D


14
May

Error message when you try to attach a file in a custom form

SharePoint 2007 | No Comments »

Solution? :D

http://support.microsoft.com/default.aspx?scid=kb;EN-US;953271


06
May

Dropdown with URL in onchange

SharePoint 2007 | 1 Comment »

Found this on Lise’s blog:

 

If you want to create a dropdown list with onchange event to dynamically go to selected URL then do this:

Use Sharepoint Designer
Insert Data View
Select Show Data
Select which field that should be displayed in the drop-down list
Insert Data
ViewData..
Style
Change layout to “Drop-down view style”
Click OK
Change to Code view in Designer
Put a script type javascript code snippet before the before the /head> tag:

Then find the following in your code
select name=”ID” size=”1″12
Change that to
select name=”ID” size=”1″ onchange=”FP_jumpMenu(this,’window’,false)”>

Then find
option style=”display:{$GroupStyle}”
Change to
option style=”display:{$GroupStyle}” value=”{@FieldWithURL}”>
where FieldWithURL is the link that you want to go to
Save

 

// Link to blog post:  http://miss-sharepoint.blogspot.com/2008/04/dropdown-with-url-in-onchange.html


06
May

Data View Controls: Form Action Button and Dynamic Redirect

SharePoint 2007 | No Comments »

Example of code to add to the form sav button to redirect to another page when submitting a custom form

javascript: {ddwrt:GenFireServerEvent(concat(‘__commit;__redirect={DispForm3.aspx?ID’,$ID,’}'))}

 

http://autosponge.spaces.live.com/blog/cns!D7F85948C20F0293!233.entry

http://social.msdn.microsoft.com/forums/en-US/sharepointcustomization/thread/8f559dd6-fb7e-4d1f-be0c-15a6b798f7e1