If you would like to discuss anything, please contact me via email: HowardBayliss@redweb.com

Wednesday, February 27, 2013

SharePoint "Managed Navigation" visitors

Is your Managed Navigation not showing / hidden? If so read on...

SharePoint 2013 includes Managed Navigation. I used this to setup some basic navigation but found that, when logged-in as a visitor, the navigation disappears.

I came across this page - "Managed navigation not visible to Readers" - which said "navigation nodes which do not have a page will not be shown to Readers".

To implement this fix, for each term (in your Managed Navigation Term set) you can :

  1. On the "NAVIGATION" tab, change the "Navigation Node Type" to "Simple Link" and specify a page url, or
  2. On the same tab, change the "Navigation Node Type" to "Term-Driven Page with Friendy URL" and then, on the "TERM-DRIVEN PAGES" tab, change the target page for the term to a page url.

Tuesday, July 3, 2012

SharePoint ItemAdded OpenBinary Zero

I created an ItemAdded event receiver for a document library. This sets metadata values for an uploaded file. Everything worked well for documents added using SharePoint's single, or multiple file upload forms.

However, when using Windows Explorer to upload a file to the library, I found that a call to the OpenBinary method for the file returned a zero length byte array.

In fact the wider issue was that the length of the file object was zero. Here's some skeleton code:

public override void ItemAdded(SPItemEventProperties properties)
{
  long length = properties.ListItem.File.Length; // zero
}

Other people that have found the same issue suggest using Thread.Sleep() in the event receiver to add an artifical delay.

However, I chose to work around this issue another way:

  1. In the ItemAdded receiver, do a check for a zero length file. Don't do any processing if it is zero. Obviously this won't work for a file uploaded using Windows Explorer. So I also needed to...
  2. Add an ItemUpdated event receiver (which just so happens to called when a user uploads a file using Windows Explorer.
  3. Both receivers call some shared code which updates the file's metadata. However, to avoid this being done multiple times, the shared code runs a check to verify that the metadata is blank before it is set.

Wednesday, June 27, 2012

SharePoint Index Music

I'm storing music tracks in a SharePoint Foundation 2010 library. I want users to be able to search for tracks using music file metadata e.g. Track Name. Artist, Album, Lyrics, etc.

This metadata is stored within popular music file types (e.g. mp3, wma, ogg, etc); though the format of the metadata varies. So how can SharePoint index these files and extract the metadata? You have a number of options:

  1. Install FAST Search Server 2010 and the "Advanced Filter Pack", which can index certain music file types.
  2. Install a 3rd party IFilter, which knows how to index your music files. You'll probably need one IFilter for each specific media file type.
  3. Develop your own music file IFilter. This should be written in C++ and it's not an easy exercise - believe me; I've tried.
  4. Expose the music file metadata through the standard SharePoint user interface.

I went for option (4), but it does require some development knowledge, and the use of a 3rd party .Net library called "taglib-sharp". In essence you create a SharePoint Event Receiver that fires whenever a music file is added to a library. The Receiver then uses "taglib-sharp" to extract metadata from the file and copy it to custom SharePoint metadata.

The picture below shows the custom SharePoint metadata, extracted from an .mp3 file:

The SharePoint indexer can now index the custom metadata, which you can then use in custom searches.

Two great things about taglib-sharp:

  1. It can be called from .Net and is easy to use - you just point it directly at a file in the SharePoint library.
  2. It supports the following music file formats: wma, aiff, asf, mp3, m4a, mpeg, ogg, riff, aac, ape, flac, Musepack and WavPack.

Thursday, June 21, 2012

TagLib Stream Buffer

Do you want to load TagLib mp3 properties from a buffer or stream?

As I write this, the latest version in the TagLib Master branch on GitHub supports this.

Here's some C++ code that I've hacked together to do it - thanks to Lukáš Lalinský for his help.

Note that I'm not a C++ Developer ;)

I need to use C++ in this instance as I'm working on a project that cannot use the .Net framework - more in a later post.


// Load a sample track into a stream. std::ifstream is("Track1.mp3");

if (!is.bad())
{
// Calculate the size of the stream.
long l = is.tellg();
is.seekg (0, ios::end);
long m = is.tellg();
is.seekg (0, ios::beg);

long diff = (m - l);

// Save the stream to a buffer.
char* buffer = new char[diff];
is.read(buffer, diff);

ByteVector v(buffer, diff);
TagLib::IOStream* stream = new TagLib::ByteVectorStream(v);

TagLib::ID3v2::FrameFactory *frameFactory = TagLib::ID3v2::FrameFactory::instance();
TagLib::MPEG::File* mpegFile =new TagLib::MPEG::File (stream,frameFactory,true,TagLib::AudioProperties::Accurate);

TagLib::FileRef* f = new TagLib::FileRef(mpegFile);

cout << f->tag()->title() << endl;
cout << mpegFile->ID3v1Tag()->artist() << endl;

is.close();
}

Monday, June 18, 2012

SharePoint check user in group

I created some code to check if the current user belonged to a specific SharePoint group, similar to this:

SPUser user = SPContext.Current.Web.CurrentUser;

foreach (SPGroup group in user.Groups)
{
  if (group.Name == [INSERT YOUR GROUP NAME HERE)
  {
  }
}

This worked when users were directly added to the SharePoint group. However, it did not work if they were part of an AD group, which was then added to the SharePoint group.

To fix the issue, I used code similar to this:

SPGroupCollection groups = SPContext.Current.Site.RootWeb.Groups;
bool inGroup = groups[INSERT YOUR GROUP NAME HERE].ContainsCurrentUser;

Thursday, June 14, 2012

SharePoint "Crawled Properties" Filename

I have a document library that contains audio files (mp3, wma, etc). When I search the site, the results contain links to the library's DispForm.aspx. This is expected as I haven't installed an iFilter for the audio file types. However, I wanted to be able to get at the Name property (highlighted in the image below), which is the filename of the media file:



To do this, I had to:
  1. Include values from the crawled property "ows_FileLeafRef" in the index.
  2. Create a mapping to a managed property
These are shown below:



The platform was a single-server farm, using SharePoint Foundation 2010 and Search Server Express 2010.

Friday, June 8, 2012

WMPLib Artist Blank

I'm using SharePoint to host music tracks, which I play with Windows Media Player (WMP).

The player is controlled via WMPLib - Microsoft's WMP API.

I found that I can add SharePoint music files to a WMP playlist via the API, and that the tracks are played. However, when I wanted to display information about the current track (track name, artist, duration, etc), I found that the artist property was empty.

I discovered the fix for this was to URL encode the URL of the track (as it exists in SharePoint) before adding it to the playlist. This was because the track URLs contained spaces (and potentially other odd characters).