IBM Omnifind Yahoo! Edition and C#

April 24, 2008 15:09 by Onslaught
I've played around with IBM's Omnifind Yahoo! Edition and came up with these little procedures. For those reading this article, you'll know there isn't much on the web regarding this topic. Hopefully this will help in your quest to integrate the search engine into a web/from application before a flash of peripeteia forces you otherwise.
(I would like to apologize to Q for not properly acknowledging his code. This code is all you, man.)

Searching:
First, place an XML and textbox control onto your aspx page.

 <asp:TextBox runat="server" ID="txtSearch" /><br><br>
 <asp:Xml runat="server" TransformSource="~/search.xsl" EnableViewState="false" ID="xmlSearch" />


Now, you need to build your query string that will power the search in the code behind. All this can be placed into an OnClick event of a button, link, or custom control.

 string strSearch = txtSearch.Text;
 string strRequest = "http://[omnifindserver:port#]/api/search?query=" + strSearch + "&collection=Default";


I've specified the collection so it won't attempt to look through all collections. Note: In the Yahoo! Edition, you're allowed only 5 collections. For a list of all available parameters, see here.

Finally, query the collection and read in the resulting XML to your control.

 string strResults = "";
 strResults = new System.Net.WebClient().DownloadString(strRequest);
 xmlSearch.DocumentContent = strResults;


That's it for a quick way to search your index. You can add more parameters, create a XSLT sheet to format the results, or specify how to return the results.

Adding Documents to the Index manually:
(This is my code)
Create the location to which your OmniFind Server resides and the necessary credentials to access it. The username and password are exactly what you use to log into the Administration Console of the OmniFind Server.

For this, you'll need the following namespaces: System.Net, System.Text

Now, create connection and credentials necessary to interact with Omnifind:

 string strLocation = "http://[omnifindserver:port#]/api/document";
 CredentialCache myCache = new CredentialCache();
 myCache.Add(new Uri(strLocation), "Basic", new NetworkCredential("username", "password"));


You'll need to encode the document. Keep in mind, you'll need to read your documents and store the raw data into an encoded format. In our example, we are pushing an aspx page.

 ASCIIEncoding encoding = new ASCIIEncoding();
 byte[] htmlBytes = encoding.GetBytes(htmlText); //I read the generated data of the aspx page into this variable earlier (not shown in this blog)


Build the HTTPWebRequest:

 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(strLocation);
 request.Method = "POST";
 request.UserAgent = "exrobinson"; //If you specified a useragent the set it here
 request.Credentials = myCache;
 request.Headers.Add("action", "addDocument");
 request.Headers.Add("collection", "Default");
 request.Headers.Add("docId", "full path of document");
 request.Headers.Add("docType", "text/xhtml"); //change type to what you need, it is important you match the correct type
 request.Headers.Add("Authorization", myCache.ToString());
 request.ContentLength = htmlBytes.Length;


Now we try to "push" the document into the index.

 try
 {
   using (Stream streamWrite = request.GetRequestStream())
   {
     if (streamWrite.CanWrite)
     {
       streamWrite.Write(htmlBytes, 0, htmlBytes.Length);
     }

     HttpWebResponse response = (HttpWebResponse)request.GetResponse();
     Stream streamResponse = response.GetResponseStream();
     StreamReader strRead = new StreamReader(streamResponse);
     
     lblMessage.Text = strRead.ReadToEnd();

     response.Close();
     strRead.Close();
     streamResponse.Close();
   }
 }
 catch (WebException webError)
 {
   lblMessage.Text = webError.Message.ToString();
 }


Note, if document succesfully is added to the index, the strRead will be empty. You can now easily place this into a loop to put in multiple documents.

The end. Let us know if you have questions.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:
Categories: ASP.NET | C#
Actions: E-mail | Permalink | Comments (2) | Comment RSSRSS comment feed

Dynamically Loading Images in SilverLight 1.0 using C#

April 18, 2008 09:40 by Onslaught

Here is an easy way to dynamically load images from a directory into your SilverLight 1.0 application using C#. I'm going to assume you already know how to set up your application to use an aspx (with codebehind) page instead of a static HTML page. If not, this article may be useful.

The aspx page (I'll call it sampleXAML.aspx) contains your XAML declaration for the SilverLight 1.0 application. For this elucidation, we will only have one main canvas. In it, we will call your loadImages() method from the codebehind.

<Canvas>
  <%= loadImages() %>
</Canvas>

In your codebehind (sampleXAML.aspx.cs), we dynamically load images that will be displayed in the SilverLight app. First will create a string variable that will house our XAML declaration for an image.

string strImages = @"<Image x:Name=""image-{0}"" Source=""{1}"" Canvas.Left=""{2}"" Canvas.Right=""{3}"" />;

I've included Canvas.Left and Canvas.Right so images will be placed in a cascading fashion to ensure they were all loaded.

Keep in mind you will need the following namespaces:

System.IO; 
System.Text; 


Next step, read in your files from a directory using the loadImages() method...

protected string loadImages()
{
  StringBuilder strXML = new StringBuilder();

  int intCounter = 0;

  DirectoryInfo dirs = new DirectoryInfo(MapPath("~/images")); //Change path here for a specific folder you want to read in from

  foreach (FileInfo fi in dirs.GetFiles("*.jpg"))
  {
    strXml.AppendFormat(strImages, intCounter, "images/" + fi.Name, intCounter*100, intCounter*100);
    intCounter++;
  }
 
  return strXML.ToString();
}

The strXML is used to build your <Image> XAML tag and is populated in the foreach loop by four parameters. You can add or remove parameters as needed, but at mininum you'll need the Source.

Note that I've filtered for JPGs. First, SilverLight 1.0 can only read JPGs and PNGs. Secondly, Windows loves to create the thumbs.db to display the cool little folder with tiny images of the pictures. While you may not get an error, it will attempt to create another <Image> XAML tag that is empty for that thumbs.db file.

When you run your application, the XAML generated should read to something similar:

<Image x:Name="image-0" Source="images/img01.jpg" Canvas.Left="0" Canvas.Right="0" />
<Image x:Name="image-1" Source="images/img02.jpg" Canvas.Left="100" Canvas.Right="100" />
<Image x:Name="image-2" Source="images/img03.jpg" Canvas.Left="200" Canvas.Right="200" />
<Image x:Name="image-3" Source="images/img04.jpg" Canvas.Left="300" Canvas.Right="300" />

The end. Post any questions you may have.


Currently rated 4.3 by 4 people

  • Currently 4.25/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Website Monitoring - Simple Website Monitor

April 16, 2008 16:44 by Onslaught

Recently, we needed a way to monitor if our Company's website was up and running. We didn't care if the server was up; we wanted to know if users could hit our site. We brainstormed for about 2 minutes and came up with this solution.

First we created an HttpWebRequest:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("website URL goes here");

Next, we try to get a response from it...
try
{
  HttpWebResponse response = (HttpWebResponse)request.GetResponse();
  label1.text = "Status is: " + response.StatusCode.ToString();
  response.Close(); //necessary, otherwise response will hang after 2nd attempt
}
catch (WebException webError)
{
  label1.Text = "Error! Message: " + webError.Message.ToString();
}


If there is an error, the catch will fire and let us know the problem.
Now, what if you want the code to check this every so often? What's the point of checking it once if the site goes down immediately afterward, right? You can easily solve this issue by using a timer.

Create your timer...
System.Timers.Timer tmrCheck = new System.Timers.Timer();
tmrCheck.Elapsed += new ElapsedEventHandler(checkResponse);
tmrCheck.Interval = 5000; //will check every 5 seconds
trmCheck.Enabled = true;


Every time you fire the event, you are essentially creating a thread and your labels will no longer be available for updating. You'll need to create some delegates to handle this.
public delegate void updLabel(string strResponse);
public delegate void updLabelError(string strError);


You'll now need to create two methods, checkReponse() and updLabel().  Upon completion of 5 seconds, your timer will fire the checkResponse(). Depending on the result of the response, updLabel() will write out the status of the target site.
private void checkResponse()
{
 HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://www.truwest.org");
 string strMessage = "";

 try
 {
   HttpWebResponse response = (HttpWebResponse)request.GetResponse();
   strMessage = "Status is: " + response.StatusCode.ToString();
   lblReponse.Invoke(new updLabel(this.showMessage), strMessage);
   response.Close(); //necessary, otherwise response will hang after 2nd attempt
 }
 catch (WebException webError)
 {
   strMessage = "Error! Message: " + webError.Message.ToString();
   lblReponse.Invoke(new updLabel(this.showMessage), strMessage);
 }
}

private void showMessage(string strResponse)
{
  label1.Text = strResponse;
}


Note the response.Close() event. I only bring it up because during testing, the progam would hang after the second attempt to check the site. Using this event cleared up the problem.

Hope this helps and let us know if you encounter any problems with the exemplary code. The end.


Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Monitor Processes and CPU Usage

April 16, 2008 15:48 by John M

This is a simple way in .NET 2.0 to monitor processes on your machine or a remote machine.  This example also monitors how much cpu usage the process is using at the time of monitoring.  Keep in mind this example also kills the process if it goes over 10% CPU Usage.

private static void killProcess()
        {
            Console.WriteLine("Watching to Kill Process!");
            int intInterval = 1000; // 1 second
            string procName = "YourProcessName";

            while (true)
            {

                Process[] runningNow = Process.GetProcesses();


                foreach (Process process in runningNow)
                {
                    using (PerformanceCounter pcProcess = new PerformanceCounter("Process", "% Processor Time", process.ProcessName))
                     {
                         if (process.ProcessName == procName)
                         {
                             pcProcess.NextValue();
                             System.Threading.Thread.Sleep(1000);
                             Console.WriteLine("Process:{0} CPU% {1}", process.ProcessName, pcProcess.NextValue());
                             if(pcProcess.NextValue() > float.Parse("10"))
                             {
                                 Console.WriteLine(string.Format("Killing {0} at {1}", procName, DateTime.Now.ToString()));
                                 process.Kill();
                             }
                         }
                    }
                }

                // Sleep till the next loop
                Thread.Sleep(intInterval);

            }


        }

Make sure you reference the following:

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.Collections;

Anyway this is cool if you are needing to send alerts if a program takes up too much CPU usage or whatever the case may be.  Also .GetProcesses() and PerformanceCounter() have overloads that except the remote computer name.


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:
Categories: C#
Actions: E-mail | Permalink | Comments (4) | Comment RSSRSS comment feed