How can I get the alternates of SAPI speech recognization result - sapi

On windows7 platform I can use System.Speech.Recognition.SpeechRecognitionEngine to convert voice to text.By SpeechRecognitionEngine when the SpeechRecognized event triggered I can get some alternate words,and I can show these word to users for choise.
void engine_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
if (this.SpeechRecognized != null)
{
this.SpeechRecognized(this, new RecognizedResultEventArgs
{
Text = e.Result.Text,
Alternates = new ReadOnlyCollection<string>(e.Result.Alternates.Select(p => p.Text).ToList())
});
}
}
By the way,when I initialise SpeechRecognitionEngine instance,I want to load some specifical word instead of use "DictationGrammar".
My program need to runing on xp platform sometimes.So I want to implament a specific vertion to run on xp operating system by use sapi5.1.
I have readed a portion of sapi 5.1 document,then I get that:in sapi5.1,I can use "command and control" way to do that. but the "Result.Alternates()" method can not be used when I use "command and control".So,how can I achieve the same effect of SpeechRecognitionEngine ?
I tried the following code and there is an com Eception:
public void RecoContext_Recognition(int StreamNumber, object StreamPosition, SpeechRecognitionType RecognitionType, ISpeechRecoResult Result)
{
ISpeechPhraseProperty oItem;
oItem = Result.PhraseInfo.Properties.Item(0);
if ((System.Decimal)Result.PhraseInfo.GrammarId == grammarId)
{
if (this.SpeechRecognized != null)
{
RecognizedResultEventArgs e = new RecognizedResultEventArgs();
e.Text = oItem.Name;
// The following code throws an exception
ISpeechPhraseAlternates alternates = Result.Alternates(10);
List<string> s = new List<string>();
foreach (ISpeechPhraseAlternate item in alternates)
{
s.Add(item.RecoResult.PhraseInfo.Properties.Item(0).Name);
}
e.Alternates = new ReadOnlyCollection<string>(s);
this.SpeechRecognized(this, e);
}
}
}
Is there any way to get the alternates by use sapi by way of COM?Thank you.

In SAPI (any version), command and control grammars don't have alternates. Only dictation grammars have alternates.

Related

Parse Push Notfications in MonoDroid

So I'm using the Parse component from the Xamarin store in my MonoDroid app. So I was able to use the following code to store an object
ParseClient.Initialize ("appid", "windowskey");
var obj = new ParseObject("Note");
obj ["text"] = "Hello, world! This is a Xamarin app using Parse!";
obj ["tags"] = new List<string> {"welcome", "xamarin", "parse"};
obj.SaveAsync ();
My real goal is to be able to do push notifications. Even though the above object stored, Parse did not register the device in the installations to be able to send push notifications. What else am I missing. Note: I'm doing this in the emulator but if i'm not mistaken it still should work.
#basit-zia, yes I did! I had to create a binding for the push library from the Java Parse SDK. I believe I was able to strip away all the libraries except for the necessary elements. I can't remember exactly what I did though.
Then in the Main Activity class, I put the following into the OnStart() method:
// check for a notification
if (Intent != null)
try {
string jsonString = Intent.Extras.GetString("com.parse.Data");
PushObject jsonObj = JsonConvert.DeserializeObject<PushObject>(jsonString);
if (jsonObj.alert != null) {
Toast.MakeText (BaseContext, jsonObj.alert, ToastLength.Long).Show ();
}
} catch (Exception e) {
Console.WriteLine ("JSONException: " + e.Message);
}
And put the following into the OnCreate() method:
Com.Parse.Parse.Initialize(this, "app id here"}, "client key here");
PushService.SetDefaultPushCallback (this, this.Class);
PushService.StartServiceIfRequired (this);
ParseInstallation.CurrentInstallation.SaveInBackground ();

pushpin.Location error on Bing maps for Windows store app

I'm using C# to create a windows store app using bing maps. I am trying to store and retrieve the location of a randomly placed pushpin on a map but when I use pushpin.Location for trying to print the location for example, I get the following error:
'Bing.Maps.Pushpin' does not contain a definition for 'Location' and
no extension method 'Location' accepting a first argument of type
'Bing.Maps.Pushpin' could be found (are you missing a using directive
or an assembly reference?)
The simple code example below show what I mean a bit more clearly:
private async void pushpinTapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
{
MessageDialog dialog = new MessageDialog("You are here" + pushPin.Location());
await dialog.ShowAsync();
}
It states clearly that location is a property of the the pushpin class in the API here
There's also examples of it being used for windows phone 7, like in this question.
Any ideas what I'm missing? or is this functionality not available for Windows 8?
It works like:
async void pin_Tapped(object sender, TappedRoutedEventArgs e)
{
Pushpin pin = sender as Pushpin;
Location pinLocation = MapLayer.GetPosition(pin);
MessageDialog dialog = new MessageDialog("You are here: " + pinLocation.Latitude +", " + pinLocation.Longitude);
await dialog.ShowAsync();
}
Ah nice one thank you.
I found another way to do it too. Essentially the same thing but using var x instead of Location.
private async void pushpinTapped(object sender,Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
{
Pushpin tappedpin = sender as Pushpin;
if (null == tappedpin) return;
var x = MapLayer.GetPosition(tappedpin);
MessageDialog dialog = new MessageDialog("You are here " + x.Latitude + ", " + x.Longitude);
await dialog.ShowAsync();
}

How do I use Sitecore.Data.Serialization.Manager.LoadItem(path,LoadOptions) to restore a item to Sitecore?

I am trying to use the sitecore API to serialize and restore sitecore items. I have created a WCF app to retrieve an Item name given a ID or sitecore path (/sitecore/content/home), retrieve a list of the names of the items children give an id or path. I can also Serialize the content tree.
public void BackupItemTree(string id)
{
Database db = Sitecore.Configuration.Factory.GetDatabase("master");
Item itm = db.GetItem(id);
Sitecore.Data.Serialization.Manager.DumpTree(itm);
}
The above code works great. After running it can see that the content tree has been serialized.
However when I try to restore the serialized items useing the following:
public void RestoreItemTree(string path)
{
try
{
using (new Sitecore.SecurityModel.SecurityDisabler())
{
Database db = Sitecore.Configuration.Factory.GetDatabase("master");
Data.Serialization.LoadOptions opt = new Data.Serialization.LoadOptions(db);
opt.ForceUpdate = true;
Sitecore.Data.Serialization.Manager.LoadItem(path, opt);
//Sitecore.Data.Serialization.Manager.LoadTree(path, opt);
}
}
catch (Exception ex)
{
throw ex;
}
}
With this code I get no errors. It runs, but if I check SiteCore it didn't do anything. I have tested using the Office Core example. The path I sent in, which might be the issue is:
C:\inetpub\wwwroot\sitecoretest\Data\serialization\master\sitecore\content\Home\Standard-Items\Teasers\Our-Clients.item
and
C:\inetpub\wwwroot\sitecorebfahnestockinet\Data\serialization\master\sitecore\content\Home\Standard-Items\Teasers\Our-Clients
Neither seems to do anything. I changed the teaser title of the item and am trying to restore to before the but every time the change is still present.
Any help would be appreciated as the SiteCore documentation is very limited.
You can always check how the Sitecore code works using Reflector, the following method is called when you click "Revert Item" in back-end:
protected virtual Item LoadItem(Item item, LoadOptions options)
{
Assert.ArgumentNotNull(item, "item");
return Manager.LoadItem(PathUtils.GetFilePath(new ItemReference(item).ToString()), options);
}
In LoadOptions you can specify whether you want to overwrite ("Revert Item") or just update ("Update Item") it.
See Sitecore.Shell.Framework.Commands.Serialization.LoadItemCommand for more info.
You have the correct LoadOptions for forcing an overwrite (aka Revert).
I suspect that the path you are using for the .item file wrong. I would suggest modifying your method to take a path to a Sitecore item. Using that path, you should leverage other serialization APIs to determine where the file should be.
public void RestoreItemTree(string itemPath)
{
Sitecore.Data.Database db = Sitecore.Configuration.Factory.GetDatabase("master");
Sitecore.Data.Serialization.ItemReference itemReference = new Sitecore.Data.Serialization.ItemReference(db.Name, itemPath);
string path = Sitecore.Data.Serialization.PathUtils.GetFilePath(itemReference.ToString());
Sitecore.Data.Serialization.LoadOptions opt = new Sitecore.Data.Serialization.LoadOptions(db);
opt.ForceUpdate = true;
using (new Sitecore.SecurityModel.SecurityDisabler())
{
Sitecore.Data.Serialization.Manager.LoadItem(path, opt);
}
}
Took me a while to work out, but you have to remove .item when restoring the tree
try this
public void RestoreItemTree(string itemPath)
{
var db = Factory.GetDatabase("master");
var itemReference = new ItemReference(db.Name, itemPath);
var path = PathUtils.GetFilePath(itemReference.ToString());
if (!System.IO.File.Exists(path))
{
throw new Exception("File not found " + path);
}
var opt = new LoadOptions(db);
opt.ForceUpdate = true;
using (new SecurityDisabler())
{
Manager.LoadItem(path, opt);
Manager.LoadTree(path.Replace(".item", ""), opt);
}
}

SharePoint 2010 Rename Document on Upload Fails in Explorer View

I'm trying to implement a customization in SharePoint 2010 so that when a document is uploaded to a library, the file name is changed to include the Document ID in the name. (I know that people shouldn't worry about file names as much any more, but we have a lot of legacy files already named and users who like to have local copies).
I was able to implement a custom Event Receiver on the ItemAdded event that renames the file by adding the Document ID before the file name. This works correctly from the web Upload.
The problem is with the Explorer View. When I try to add the file using WebDAV in the Explorer View, I get two copies of the file. It seems that when a file is uploaded via the Web the events that fire are
ItemAdding
ItemAdded
But when I copy/paste a file into Explorer View I see the following events:
ItemAdding
ItemAdded
ItemAdding
ItemAdded
ItemUpdating
ItemUpdated
The result is I have two files with different names (since the Document IDs are different).
I've found a lot of people talking about this issue online (this is the best article I found). Anyone have any other ideas? Would it make more sense to do this in a workflow instead of an event receiver? I could use a scheduled job instead, but that might be confusing to the user if the document name changed a few minutes later.
This is my code that works great when using the Web upload but not when using Explorer View:
public override void ItemAdded(SPItemEventProperties properties)
{
try
{
SPListItem currentItem = properties.ListItem;
if (currentItem["_dlc_DocId"] != null)
{
string docId = currentItem["_dlc_DocId"].ToString();
if (!currentItem["BaseName"].ToString().StartsWith(docId))
{
EventFiringEnabled = false;
currentItem["BaseName"] = docId + currentItem["BaseName"];
currentItem.SystemUpdate();
EventFiringEnabled = true;
}
}
}
catch (Exception ex)
{
//Probably should log an error here
}
base.ItemAdded(properties);
}
I have found that using a Visual Studio workflow allows me the most flexibility to do this. A SharePoint Designer Workflow would be simpler, but would be harder to deploy to different sites and libraries.
After reading some good articles including this and this I have come up with this code which seems to work. It starts a workflow and waits until the document is not in a LockState and then processes the filename.
The workflow looks like this:
And here is the code behind:
namespace ControlledDocuments.RenameWorkflow
{
public sealed partial class RenameWorkflow : SequentialWorkflowActivity
{
public RenameWorkflow()
{
InitializeComponent();
}
public Guid workflowId = default(System.Guid);
public SPWorkflowActivationProperties workflowProperties = new SPWorkflowActivationProperties();
Boolean continueWaiting = true;
private void onWorkflowActivated1_Invoked(object sender, ExternalDataEventArgs e)
{
CheckFileStatus();
}
private void whileActivity(object sender, ConditionalEventArgs e)
{
e.Result = continueWaiting;
}
private void onWorkflowItemChanged(object sender, ExternalDataEventArgs e)
{
CheckFileStatus();
}
private void CheckFileStatus()
{
if (workflowProperties.Item.File.LockType == SPFile.SPLockType.None)
{
continueWaiting = false;
}
}
private void renameFile(object sender, EventArgs e)
{
try
{
SPListItem currentItem = workflowProperties.Item;
if (currentItem["_dlc_DocId"] != null)
{
string docId = currentItem["_dlc_DocId"].ToString();
if (!currentItem["BaseName"].ToString().StartsWith(docId))
{
currentItem["BaseName"] = docId + currentItem["BaseName"];
currentItem.SystemUpdate();
}
}
}
catch (Exception ex)
{
//Should do something useful here
}
}
}
}
Hope this helps someone else if they have the same problem.
Well i'd go for the workflow workaround... there are 2 options imo:
1) Create a boolean fied in your document library, then create a SPD workflow that fires when the item is added and set that field to "Changed" or something. In the EventReceiver you then check whether that field has been set..
2) Do everything with the SPD workflow - changing the title like in this example should be no problem.

Google Search API - Number of Results

Whenever you perform a Google search, it spits out this little snippet of info
"About 8,110,000 results (0.10 seconds)"
I'm using the number of results certain terms return to rank them against each other, so if I could get this integer - 8,110,000 - via the API it would be very helpful. Some Google API's have recently been deprecated, so if you could point me to the right one that isn't deprecated, it would be very helpful.
Any other workarounds would also be much appreciated. I've seen one or two old posts on similar topics, but none seemed to be resolved successfully.
Completed using Bing instead of Google and with the following code:
string baseURL = "http://api.search.live.net/xml.aspx?Appid=<MyAppID>&query=%22" + name + "%22&sources=web";
WebClient c = new WebClient();
c.DownloadStringAsync(new Uri(baseURL));
c.DownloadStringCompleted += new DownloadStringCompletedEventHandler(findTotalResults);
and this calls findTotalResults:
void findTotalResults(object sender, DownloadStringCompletedEventArgs e)
{
lock (this)
{
string s = e.Result;
XmlReader reader = XmlReader.Create(new MemoryStream(System.Text.UTF8Encoding.UTF8.GetBytes(s)));
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
if (reader.Name.Equals("web:Total"))
{
gResults = reader.ReadInnerXml();
}
}
}
}
}