Jump to content

Recommended Posts

Posted
Hi All,

 

Does anyone know if it is possible to link the Acitve Directory Thumbnail for users in to the ME Hap tile?

 

 

Thanks in advance

 

Just out interest, why would you want to do this?

Posted

Ah ok, we set the thumbnailPhoto attribute in AD. We use this so that it shows the users picture in Outlook. Is there any way to read from that attribute? If not ill just attach the pics to the jpegPhoto.

 

Cheers

 

Mat

Posted

Hmm, odd, I've used jpegPhoto, which ms recommend, thumbnailPhoto I thought was for something else.

 

If you know how to edit the hap source code, it's HAP.Web.LiveTiles, it's the me.cs file

Posted
Can anyone point to an article to tells you how to set the jpegPhoto to a students photo? I had a look on google but it seems massively complicated to me!
Posted

Do you know how to program?

 

The best way I've found is to write a program to do it

 

       public void Start()
       {
           ProcessStartInfo startinfo;
           Process process = null;
           StreamReader stdoutreader;
           XmlDocument doc = new XmlDocument();
           try
           {
               // Create a new Process Info object
               startinfo = new ProcessStartInfo();

               // Set the Parameters for the report

               startinfo.FileName = @"c:\program files\sims\sims .net\CommandReporter.exe";
               if (!File.Exists(startinfo.FileName)) startinfo.FileName = @"c:\Program Files (x86)\sims\sims .net\CommandReporter.exe";
               string param = "EffectiveDateDate" + DateTime.Now.ToString("dd/MM/yyyy") + " 00:00:00";
               startinfo.Arguments = String.Format("/USER:{0} /PASSWORD:{1} /REPORT:\"{2}\" /PARAMS:\"{3}\" /QUIET", "user", "password", "User Details Update", param);
               startinfo.UseShellExecute = false;
               startinfo.RedirectStandardOutput = true;
               startinfo.CreateNoWindow = true;
               // Start the Process
               process = Process.Start(startinfo);

               // Capture the Standard Output
               stdoutreader = process.StandardOutput;

               // Create a new XML document to hold the resilts
               doc = new XmlDocument();
               // Load the results
               doc.Load(stdoutreader);

               process.WaitForExit();
               // At this point you would do something with the results
               // in this case we are going to save them to a file
               //doc.Save(@"C:\SIMS TP Reporting SDK\Examples\ReDirectC#\obj\Debug\output.xml");
               // Close down the Standard Output stream
               stdoutreader.Close();
               stdoutreader = null;
           }
           catch { }
           finally
           {
               if (process != null)
               {
                   process.Close();
               }
               process = null;
               startinfo = null;
           }
           this.Progress = 0;
           DirectoryEntry usersDE = new DirectoryEntry("LDAP://DC=crick,DC=internal", "user", "password");
           DirectorySearcher ds = new DirectorySearcher(usersDE);

           //doc.Save("c:\\temp.xml");

           XmlNodeList nodes = doc.SelectNodes("/SuperStarReport/Record");
           if (Initialized != null) Initialized(nodes.Count);

           string logpath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "error.log");
           if (File.Exists(logpath)) File.Delete(logpath);
           foreach (XmlNode node in nodes)
           {
               if (node.SelectSingleNode("UPN") != null)
               {
                   ds.Filter = "(employeeID=" + node.SelectSingleNode("UPN").InnerText + ")";
                   ds.PropertiesToLoad.Add("cn");
                   ds.PropertiesToLoad.Add("employeeID");
                   SearchResultCollection r = ds.FindAll();
                   string reg = (node.SelectSingleNode("Reg") == null ? "" : " in " + node.SelectSingleNode("Reg").InnerText);
                   if (r.Count == 0)
                   {
                       ds.Filter = "(description=" + node.SelectSingleNode("Name").InnerText.Replace(" ", "\\20") + reg + ")";
                       r = ds.FindAll();
                       if (r.Count == 0)
                       {
                           string reg2 = reg;
                           if (reg != "") reg2 = reg.Remove(reg.Length - 1);
                           ds.Filter = "(description=" + node.SelectSingleNode("Name").InnerText.Replace(" ", "\\20") + reg2 + ")";
                           r = ds.FindAll();
                           if (r.Count == 0)
                           {
                               ds.Filter = "(description=" + node.SelectSingleNode("Name").InnerText.Replace(" ", "\\20") + ")";
                               r = ds.FindAll();
                               if (r.Count == 0)
                               {
                                   StreamWriter sw = File.Exists(logpath) ? File.AppendText(logpath) : File.CreateText(logpath);
                                   sw.WriteLine("Error with " + node.SelectSingleNode("Name").InnerText + reg + " - Can't find in, either with UPN or with Description");
                                   sw.Flush();
                                   sw.Close();
                                   continue;
                               }
                           }
                       }
                   }
                   DirectoryEntry theUserDE = new DirectoryEntry(r[0].Path, "user", "password");
                   try
                   {
                       UpdateUser(theUserDE, node);
                   }
                   catch
                   {
                       StreamWriter sw = File.Exists(logpath) ? File.AppendText(logpath) : File.CreateText(logpath);
                       sw.WriteLine("Error Saving " + node.SelectSingleNode("Name").InnerText + reg);
                       sw.Flush();
                       sw.Close();
                       continue;
                   }
                   this.Progress++;
                   if (Updated != null) Updated();
               }
           }
           if (Done != null) Done();
       }


       private void UpdateUser(DirectoryEntry theUserDE, XmlNode node)
       {
           //if (theUserDE.Properties["msExchQueryBaseDN"].Count == 0) theUserDE.Properties["msExchQueryBaseDN"].Add("CN=All Students,CN=All Address Lists,CN=Address Lists Container,CN=Crickhowell High School,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=crickhowell,DC=internal");
           //else theUserDE.Properties["msExchQueryBaseDN"][0] = "CN=All Students,CN=All Address Lists,CN=Address Lists Container,CN=Crickhowell High School,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=crickhowell,DC=internal";
           string reg = node.SelectSingleNode("Reg") == null ? "" : node.SelectSingleNode("Reg").InnerText;
           string[] name = node.SelectSingleNode("Name").InnerText.Split(new char[] { ' ' });
           if (theUserDE.Properties["mail"].Count == 0) theUserDE.Properties["mail"].Add(string.Format("{0}@students.crickhowell-hs.powys.sch.uk", theUserDE.Properties["cn"][0].ToString().ToLower()));
           else theUserDE.Properties["mail"][0] = string.Format("{0}@students.crickhowell-hs.powys.sch.uk", theUserDE.Properties["cn"][0].ToString().ToLower());
           if (theUserDE.Properties["employeeID"].Count == 0) theUserDE.Properties["employeeID"].Add(node.SelectSingleNode("UPN").InnerText);
           else theUserDE.Properties["employeeID"][0] = node.SelectSingleNode("UPN").InnerText;
           if (theUserDE.Properties["Department"].Count == 0) theUserDE.Properties["Department"].Add(reg);
           else theUserDE.Properties["Department"][0] = reg;
           if (theUserDE.Properties["company"].Count == 0) theUserDE.Properties["company"].Add("Crickhowell High School");
           else theUserDE.Properties["company"][0] = "Crickhowell High School";
           if (theUserDE.Properties["givenname"].Count == 0) theUserDE.Properties["givenname"].Add(name[0]);
           else theUserDE.Properties["givenname"][0] = name[0];
           if (theUserDE.Properties["sn"].Count == 0) theUserDE.Properties["sn"].Add(name[name.Length - 1]);
           else theUserDE.Properties["sn"][0] = name[name.Length - 1];
           if (theUserDE.Properties["DisplayName"].Count == 0) theUserDE.Properties["DisplayName"].Add(node.SelectSingleNode("Name").InnerText);
           else theUserDE.Properties["DisplayName"][0] = node.SelectSingleNode("Name").InnerText;
           if (theUserDE.Properties["description"].Count == 0) theUserDE.Properties["description"].Add(node.SelectSingleNode("Name").InnerText + " in " + reg);
           else theUserDE.Properties["description"][0] = node.SelectSingleNode("Name").InnerText + " in " + reg;
           if (theUserDE.Properties["employeeNumber"].Count == 0) theUserDE.Properties["employeeNumber"].Add(node.SelectSingleNode("Adno").InnerText);
           else theUserDE.Properties["employeeNumber"][0] = node.SelectSingleNode("Adno").InnerText;
           if (node.SelectSingleNode("Photo") != null)
           {
               if (theUserDE.Properties["photo"].Count == 0) theUserDE.Properties["photo"].Add(ConvertToJPEG(node.SelectSingleNode("Photo").InnerText));
               else theUserDE.Properties["photo"][0] = ConvertToJPEG(node.SelectSingleNode("Photo").InnerText);
               theUserDE.Properties["jpegPhoto"].Clear();
               theUserDE.Properties["jpegPhoto"].Add(ConvertToJPEG(node.SelectSingleNode("Photo").InnerText));
               theUserDE.Properties["thumbnailPhoto"].Clear();
               theUserDE.Properties["thumbnailPhoto"].Add(ConvertToJPEG(node.SelectSingleNode("Photo").InnerText));
           }
           if (theUserDE.Properties["departmentNumber"].Count == 0) theUserDE.Properties["departmentNumber"].Add(node.SelectSingleNode("Year_x0020_taught_x0020_in_x0020_Code").InnerText);
           else theUserDE.Properties["departmentNumber"][0] = node.SelectSingleNode("Year_x0020_taught_x0020_in_x0020_Code").InnerText;
           theUserDE.CommitChanges();
       }

       public byte[] ConvertToJPEG(string photo)
       {
           MemoryStream ms = new MemoryStream(Base64Encoder.FromBase64(photo));
           Image i = Bitmap.FromStream(ms);
           EncoderParameters encoderParameters = new EncoderParameters(1);
           encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
           MemoryStream ms1 = new MemoryStream();
           i.Save(ms1, GetEncoder(ImageFormat.Jpeg), encoderParameters);
           return ms1.ToArray();
       }

       public static ImageCodecInfo GetEncoder(ImageFormat format)
       {
           foreach (ImageCodecInfo codec in ImageCodecInfo.GetImageDecoders()) if (codec.FormatID == format.Guid) return codec;
           return null;
       }

 

Attached is the SIMS report this program runs

  • Thanks 1
Posted

Forgot a bit of code

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

namespace CHS.UpdateUserDetails
{
   public class Base64Encoder
   {
       static public string ToBase64(byte[] data)
       {
           int length = data == null ? 0 : data.Length;
           if (length == 0)
               return String.Empty;

           int padding = length % 3;
           if (padding > 0)
               padding = 3 - padding;
           int blocks = (length - 1) / 3 + 1;

           char[] s = new char[blocks * 4];

           for (int i = 0; i < blocks; i++)
           {
               bool finalBlock = i == blocks - 1;
               bool pad2 = false;
               bool pad1 = false;
               if (finalBlock)
               {
                   pad2 = padding == 2;
                   pad1 = padding > 0;
               }

               int index = i * 3;
               byte b1 = data[index];
               byte b2 = pad2 ? (byte)0 : data[index + 1];
               byte b3 = pad1 ? (byte)0 : data[index + 2];

               byte temp1 = (byte)((b1 & 0xFC) >> 2);

               byte temp = (byte)((b1 & 0x03) << 4);
               byte temp2 = (byte)((b2 & 0xF0) >> 4);
               temp2 += temp;

               temp = (byte)((b2 & 0x0F) << 2);
               byte temp3 = (byte)((b3 & 0xC0) >> 6);
               temp3 += temp;

               byte temp4 = (byte)(b3 & 0x3F);

               index = i * 4;
               s[index] = SixBitToChar(temp1);
               s[index + 1] = SixBitToChar(temp2);
               s[index + 2] = pad2 ? '=' : SixBitToChar(temp3);
               s[index + 3] = pad1 ? '=' : SixBitToChar(temp4);
           }

           return new string(s);
       }
       static private char SixBitToChar(byte b)
       {
           char c;
           if (b < 26)
           {
               c = (char)((int)b + (int)'A');
           }
           else if (b < 52)
           {
               c = (char)((int)b - 26 + (int)'a');
           }
           else if (b < 62)
           {
               c = (char)((int)b - 52 + (int)'0');
           }
           else if (b == 62)
           {
               c = s_CharPlusSign;
           }
           else
           {
               c = s_CharSlash;
           }
           return c;
       }

       static public byte[] FromBase64(string s)
       {
           int length = s == null ? 0 : s.Length;
           if (length == 0)
               return new byte[0];

           int padding = 0;
           if (length > 2 && s[length - 2] == '=')
               padding = 2;
           else if (length > 1 && s[length - 1] == '=')
               padding = 1;

           int blocks = (length - 1) / 4 + 1;
           int bytes = blocks * 3;

           byte[] data = new byte[bytes - padding];

           for (int i = 0; i < blocks; i++)
           {
               bool finalBlock = i == blocks - 1;
               bool pad2 = false;
               bool pad1 = false;
               if (finalBlock)
               {
                   pad2 = padding == 2;
                   pad1 = padding > 0;
               }

               int index = i * 4;
               byte temp1 = CharToSixBit(s[index]);
               byte temp2 = CharToSixBit(s[index + 1]);
               byte temp3 = CharToSixBit(s[index + 2]);
               byte temp4 = CharToSixBit(s[index + 3]);

               byte b = (byte)(temp1 << 2);
               byte b1 = (byte)((temp2 & 0x30) >> 4);
               b1 += b;

               b = (byte)((temp2 & 0x0F) << 4);
               byte b2 = (byte)((temp3 & 0x3C) >> 2);
               b2 += b;

               b = (byte)((temp3 & 0x03) << 6);
               byte b3 = temp4;
               b3 += b;

               index = i * 3;
               data[index] = b1;
               if (!pad2)
                   data[index + 1] = b2;
               if (!pad1)
                   data[index + 2] = b3;
           }

           return data;
       }
       static private byte CharToSixBit(char c)
       {
           byte b;
           if (c >= 'A' && c <= 'Z')
           {
               b = (byte)((int)c - (int)'A');
           }
           else if (c >= 'a' && c <= 'z')
           {
               b = (byte)((int)c - (int)'a' + 26);
           }
           else if (c >= '0' && c <= '9')
           {
               b = (byte)((int)c - (int)'0' + 52);
           }
           else if (c == s_CharPlusSign)
           {
               b = (byte)62;
           }
           else
           {
               b = (byte)63;
           }
           return b;
       }

       static private char s_CharPlusSign = '+';
       /// 
       /// Gets or sets the plus sign character.
       /// Default is '+'.
       /// 
       static public char CharPlusSign
       {
           get
           {
               return s_CharPlusSign;
           }
           set
           {
               s_CharPlusSign = value;
           }
       }
       static private char s_CharSlash = '/';
       /// 
       /// Gets or sets the slash character.
       /// Default is '/'.
       /// 
       static public char CharSlash
       {
           get
           {
               return s_CharSlash;
           }
           set
           {
               s_CharSlash = value;
           }
       }
   }
}

  • Thanks 1
Posted
Ill have a go. I think that Outlook 2010 only picks up the pictures from the thumbnail attribute. Ill have a play and see what I can do.

 

Thanks!!

 

That's in line with what i have found too. Outlook (the only real reason for doing it) seems to use the wrong attribute - but there's little point in sticking to our principles when - Our network management software (BCX Management Tools) allows us to set it for Outlook purposes (and to make managing users a bit prettier) - but we stick that in the thumbnail attribute so it shows up in Outlook.

 

(mine is in both from when i was experimenting with it - but im hesitant to put it in both, it seems like a lot of extra data to go into the AD...

Posted
(mine is in both from when i was experimenting with it - but im hesitant to put it in both, it seems like a lot of extra data to go into the AD...

 

I find that if I put it in both attributes it oddly disappears from Outlook and you end up with the little silhouette. I did have a look at the HAP source code but I think its a bit beyond me :(

Posted (edited)

Ok, just released the update for this: v8.5.1211.1240 is out on the v8.5 release.

 

Ok, it should be on codeplex, it's attached if needed as it looks like codeplex is down atm

Edited by nickbro
Posted

Hi Nick,

 

I have checked and there is nothing in the studentPhotoHandler. However its still not picking up the pics? I dropped the dll files into the bin directory on the HAP server but still no joy.

 

Any ideas? Its prob something I’m doing wrong!

!

Posted

Nick,

 

Not to piggyback on another problem (and if you want to move it to another thread, that's fine) , I was curious about this feature as well and added a user's picture into Active Directory. I only added it in for one staff member to test it out. If I go into attribute editor under that user's properties, I can see that it is set. But when I log-in to HAP+ as that user, I get the generic user picture. I didn't know if there was something that I was missing. I did check out the videos on the hap.codeplex site, but the videos were for older versions of HAP+ and talked about SIMS. I setup a test site called HAPTEST with a fresh install, thinking maybe it was some configuration on the actual site that I had screwed up, and it still didn't show up on the fresh install.

 

I looked at the photo handler line in hapconfig.xml and it is set as follows: "photohandler="" />".

 

Looking at the source code of the page it says the following:

Test Teacher (testteacher)

                       
                           
                           Edit Profile
                           Logout

 

Is there something else that I have to configure for it to pull the Active Directory Photo?

Thanks!

Posted

Nick,

When I go to /hap/api/mypic I get the following:

 

HAP/api/tiles/icons/128/128/images/icons/metro/folders-os/UserNo-Frame.png. If I select the picture, I can see the generic user photo.

 

Thanks!

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now



×
×
  • Create New...