Sitecore.Analytics.Tracker.Current is null when invoked through a pipeline - sitecore

I need to redirect based on the country location the user is trying to access. For example when user trying to access http://www.example.com/ from china my site should as http://www.example.com/zh. I am checking using the sitecore tracker in pipeline process to get the country code using the below method.
public void Process(HttpRequestArgs args)
{
Assert.ArgumentNotNull(args, "args");
if (HttpContext.Current == null
|| Context.Site == null
////TODO: || Sitecore.Context.PageMode...
|| Context.Database == null || Context.Site.Name == "shell" || !this._sites.Contains(Context.Site.Name))
{
return;
}
// contains path including language and query string
// (not anchor name), but not hostname.
// We can use this to add the language back into the path.
string rawPath = Sitecore.Context.RawUrl;
if (!rawPath.StartsWith("/sitecore") && !rawPath.StartsWith("/" + Sitecore.Context.Language.Name + "/") && !rawPath.StartsWith("/" + Sitecore.Context.Language.Name) && !rawPath.StartsWith("/default.aspx"))
{
string langCode = "";
if(!string.IsNullOrEmpty(GeoIPUtils.GetUserGeoIP()))
{
try
{
string country = GeoIPUtils.GetUserGeoIP();;
if (country.Trim().ToUpper() == "China".ToUpper())
langCode = "zh";
else if (country.Trim().ToUpper() == "Japan".ToUpper())
langCode = "jp";
else if (country.Trim().ToUpper() == "Thailand".ToUpper())
langCode = "th";
else
langCode = "en";
}
catch(Exception)
{
langCode = "en";
}
}
else
{
langCode = HttpContext.Current.Request.Cookies["avc#lang"].Value.ToString();
}
if (!string.IsNullOrEmpty(langCode))
{
Language language = null;
if (Language.TryParse(langCode, out language))
{
//then try to get the language item id from the language or two letter iso code
ID langID = LanguageManager.GetLanguageItemId(language, Sitecore.Context.Database);
if (!ID.IsNullOrEmpty(langID))
{
//sometimes the language found is slightly different than official language item used in SC
language = LanguageManager.GetLanguage(language.CultureInfo.TwoLetterISOLanguageName);
if (Context.Item != null)
{
List<string> availableLangs = LanguagesWithContent(Context.Item);
if (availableLangs != null && availableLangs.Count > 0 && !availableLangs.Contains(language.CultureInfo.TwoLetterISOLanguageName.ToString()))
{
langCode = availableLangs.FirstOrDefault().ToString();
}
}
else
{
langCode = "en";
}
}
else
{
langCode = "en";
}
}
}
HttpContext.Current.Response.RedirectPermanent("/" + (String.IsNullOrEmpty(langCode) ? Sitecore.Context.Language.Name : langCode) + rawPath);
}
}
Below is the GetUserGeoIP function
public static string GetUserGeoIP()
{
string countryCode = "";
try
{
countryCode = Sitecore.Analytics.Tracker.Current.Interaction.GeoData.Country;
}
catch(Exception ex)
{
Log.Error("GetUserGeoIP Error: " + ex.Message + " Source: " + ex.Source + " Stack Trace :" + ex.StackTrace + " Inner Ex : " + ex.InnerException, ex);
countryCode = "GB";
}
if (!string.IsNullOrEmpty(countryCode))
{
var countryItem = ISO3166.FromAlpha2(countryCode);
if (countryItem != null)
return countryItem.Name;
}
return "Other";
}
But I am getting an below exception
7904 10:43:25 ERROR Cannot create tracker.
Exception: System.InvalidOperationException
Message: session is not initialized
Source: Sitecore.Analytics
at Sitecore.Analytics.Data.HttpSessionContextManager.GetSession()
at Sitecore.Analytics.Pipelines.EnsureSessionContext.EnsureContext.Process(InitializeTrackerArgs args)
at (Object , Object[] )
at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
at Sitecore.Analytics.DefaultTracker.EnsureSessionContext()
at Sitecore.Analytics.Pipelines.CreateTracker.GetTracker.Process(CreateTrackerArgs args)
at (Object , Object[] )
at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
at Sitecore.Analytics.Tracker.Initialize()
Note: The same GetUserGeoIP method is used in API which gets the correct countryName. I am using Sitecore.NET 8.0 (rev. 151127) version
Any help on this highly appreciated

Your processor is probably too soon in the pipeline(s). You can find an overview of the request pipelines here: http://sitecoreskills.blogspot.be/2015/02/a-sitecore-8-request-from-beginning-to.html
You should put your processor after the tracker has been initialized and the geo data has been fetched. I did something similar a while ago and placed my processor in the startAnalytics pipeline.
Fetching the geo data is async so that might (will) give issues when doing this in the first request pipeline. Read this article to tackle that issue by calling UpdateGeoIpData with a timespan.

Related

Bukkit Player check achievements

I don't know what I should put into player.getAdvancementProgress(Here).
if (player.getAdvancementProgress().isDone()) {
}
Maybe someone knows something?
You should use an Advancement object, specially the advancement that you are looking for informations.
You can get it with Bukkit.getAdvancement(NamespacedKey.fromString("advancement/name")) where advancement/name can be nether/all_potions for example. You can get all here (column: "Resource location). If you are getting it from command, I suggest you to add tab complete.
Example of TAB that show only not-done success :
#Override
public List<String> onTabComplete(CommandSender sender, Command cmd, String label, String[] arg) {
List<String> list = new ArrayList<>();
if(!(sender instanceof Player))
return list;
Player p = (Player) sender;
String prefix = arg[arg.length - 1].toLowerCase(Locale.ROOT); // the begin of the searched advancement
Bukkit.advancementIterator().forEachRemaining((a) -> {
AdvancementProgress ap = p.getAdvancementProgress(a);
if((prefix.isEmpty() || a.getKey().getKey().toLowerCase().startsWith(prefix)) && !ap.isDone() && !a.getKey().getKey().startsWith("recipes"))
list.add(a.getKey().getKey());
});
return list;
}
Then, in the command you can do like that:
#Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] arg) {
if(!(sender instanceof Player)) // not allowed for no-player
return false;
Player p = (Player) sender;
// firstly: try to get advancement
Advancement a = Bukkit.getAdvancement(NamespacedKey.fromString(arg[0]));
if(a == null)
a = Bukkit.getAdvancement(NamespacedKey.minecraft(arg[0]));
if(a == null) // can't find it
p.sendMessage(ChatColor.RED + "Failed to find success " + arg[0]);
else { // founded :
AdvancementProgress ap = p.getAdvancementProgress(a);
p.sendMessage(ChatColor.GREEN + "Achivement " + a.getKey().getKey() + " stay: " + ChatColor.YELLOW + String.join(", ", ap.getRemainingCriteria().stream().map(this::getCleaned).collect(Collectors.toList())));
}
return false;
}
private String getCleaned(String s) { // this method is only to make content easier to read
String[] args = s.split("/");
return args[args.length - 1].replace(".png", "").replace(".jpg", "").replace("minecraft:", "").replace("_", " ");
}
Else, if you want to get all advancements, you should use Bukkit.advancementIterator().

Merging two identical word document displaying wrong page number using aspose word

Using Aspose Implementation:Aspose.Words for Java
Aspose Implementation-Version: 13.5.0.0
Below are the documents:
Source.docx
A1.docx
A2.docx
A3.docx
Using below code to append the word documents:
public static void main(String[] args) {
try {
List<Document> documentsToBeMerged=new ArrayList<Document>();
Document source=new Document("D:/Source.docx");
Document identicalDoc1=new Document("D:/A1.docx");
Document identicalDoc2=new Document("D:/A2.docx");
Document identicalDoc3=new Document("D:/A3.docx");
documentsToBeMerged.add(identicalDoc1);
documentsToBeMerged.add(identicalDoc2);
documentsToBeMerged.add(identicalDoc3);
mergeDocumentsWithSourceDocumentHeaderFooter(source, documentsToBeMerged, "D:/output.docx");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void mergeDocumentsWithSourceDocumentHeaderFooter(
Document destinationDocument, List<Document> mergingdocument,
String outputFileName) throws Exception {
try {
for (Document document : mergingdocument) {
document.getFirstSection().getPageSetup()
.setSectionStart(SectionStart.NEW_PAGE);
document.getFirstSection().getHeadersFooters()
.linkToPrevious(true);
destinationDocument.appendDocument(document,
ImportFormatMode.KEEP_SOURCE_FORMATTING);
}
AsposeUtil.convertNumPageFieldsToPageRef(destinationDocument);
destinationDocument.updatePageLayout();
destinationDocument.save(outputFileName);
} catch (Exception e) {
throw e;
}
}
public static void convertNumPageFieldsToPageRef(Document doc) throws Exception
{
final String BOOKMARK_PREFIX = "_SubDocumentEnd";
final String NUM_PAGES_FIELD_NAME = "NUMPAGES";
final String PAGE_REF_FIELD_NAME = "PAGEREF";
DocumentBuilder builder = new DocumentBuilder(doc);
int subDocumentCount = 0;
for (Section section : doc.getSections())
{
if (section.getPageSetup().getRestartPageNumbering())
{
if (!section.equals(doc.getFirstSection()))
{
Section prevSection = (Section)section.getPreviousSibling();
Node lastNode = prevSection.getBody().getLastChild();
builder.moveTo(lastNode);
builder.startBookmark(BOOKMARK_PREFIX + subDocumentCount);
builder.endBookmark(BOOKMARK_PREFIX + subDocumentCount);
subDocumentCount++;
}
}
if (section.equals(doc.getLastSection()))
{
Node lastNode = doc.getLastSection().getBody().getLastChild();
builder.moveTo(lastNode);
builder.startBookmark(BOOKMARK_PREFIX + subDocumentCount);
builder.endBookmark(BOOKMARK_PREFIX + subDocumentCount);
}
for (Node node : section.getChildNodes(NodeType.FIELD_START, true).toArray())
{
FieldStart fieldStart = (FieldStart)node;
if (fieldStart.getFieldType() == FieldType.FIELD_NUM_PAGES)
{
String fieldCode = getFieldCode(fieldStart);
String fieldSwitches = fieldCode.replace(NUM_PAGES_FIELD_NAME, "").trim();
Node previousNode = fieldStart.getPreviousSibling();
if (previousNode == null)
previousNode = fieldStart;
builder.moveTo(previousNode);
Field newField = builder.insertField(MessageFormat.format(" {0} {1}{2} {3} ", PAGE_REF_FIELD_NAME, BOOKMARK_PREFIX, subDocumentCount, fieldSwitches));
previousNode.getParentNode().insertBefore(previousNode, newField.getStart());
removeField(fieldStart);
}
}
}
}
private static String getFieldCode(FieldStart fieldStart) throws Exception
{
StringBuilder builder = new StringBuilder();
for (Node node = fieldStart; node != null && node.getNodeType() != NodeType.FIELD_SEPARATOR &&
node.getNodeType() != NodeType.FIELD_END; node = node.nextPreOrder(node.getDocument()))
{
if (node.getNodeType() == NodeType.RUN)
builder.append(node.getText());
}
return builder.toString();
}
private static void removeField(FieldStart fieldStart) throws Exception
{
Node currentNode = fieldStart;
boolean isRemoving = true;
while (currentNode != null && isRemoving)
{
if (currentNode.getNodeType() == NodeType.FIELD_END)
isRemoving = false;
Node nextNode = currentNode.nextPreOrder(currentNode.getDocument());
currentNode.remove();
currentNode = nextNode;
}
}
Issue: Total page output.docx contains 12 and last page footer is showing page number as 12 of 11 which is wrong.
Note: Both the documents Identical1.docx and Identical2.docx are same and also contains same References.
Please suggest me any solution how to resolve the page number issue.
We have tested the scenario using latest version of Aspose.Words for Java 18.6 and have not found the shared issue. Please use Aspose.Words for Java 18.6. Please note that Aspose.Words mimics the behavior of MS Word. If you join these documents using MS Word, the final output document will have 9 pages.
Moreover, please share the code of AsposeUtil.convertNumPageFieldsToPageRef method for further testing.
I work with Aspose as Developer Evangelist.

Domain switcher button for different languages

I want to create a dropdown menu With English or German as the options in Javascript / jQuery that checks that:
check if on a domain - say happy.com/pizza
if german is selected on dropdown
redirect user to
happy.de/pizza
and I could have a list
if happy.com/pizza got to happy.de/pizza
happy.com/coke got to happy.de/coke
happy.com/juice got to happy.de/juice
etc etc.
I have written the code yet but how would one go about this?
Thanks!
I have written some code but I just need a little help please:
In this scenario I am on the www.something.com/beer page and want it to go to the German Beer Page!
<select>
<option value="1">English</option>
<option value="2">German</option>
</select>
if(value == 2) && is current domain www.something.com/beer{
window.top.location.href = 'www.something.de/beer';
}else if(value == 2) && is current domain www.something.com/cheese{
window.top.location.href = 'www.something.de/cheese';
}else{
do nothing
}
How do I get this to check the value of the dropdown and the domain is currently on?
Here is my Jsfiddle
http://jsfiddle.net/msasz2an/
Thanks again!
function current(arr) {
// discuss at: http://phpjs.org/functions/current/
// original by: Brett Zamir (http://brett-zamir.me)
// note: Uses global: php_js to store the array pointer
// example 1: transport = ['foot', 'bike', 'car', 'plane'];
// example 1: current(transport);
// returns 1: 'foot'
this.php_js = this.php_js || {};
this.php_js.pointers = this.php_js.pointers || [];
var indexOf = function (value) {
for (var i = 0, length = this.length; i < length; i++) {
if (this[i] === value) {
return i;
}
}
return -1;
};
// END REDUNDANT
var pointers = this.php_js.pointers;
if (!pointers.indexOf) {
pointers.indexOf = indexOf;
}
if (pointers.indexOf(arr) === -1) {
pointers.push(arr, 0);
}
var arrpos = pointers.indexOf(arr);
var cursor = pointers[arrpos + 1];
if (Object.prototype.toString.call(arr) === '[object Array]') {
return arr[cursor] || false;
}
var ct = 0;
for (var k in arr) {
if (ct === cursor) {
return arr[k];
}
ct++;
}
// Empty
return false;
}

Unable to divide the latest freebase dump

I've dividing the freebase dump into smaller compressed files using a ruby script, then with freebase-rdf-2014-10-26-00-00 it stopped working, ending prematurely. Today I wrote a java program that acts the same way as ruby. Are there changes to freebase dump regarding compression?
package splitfreebase;
import java.io.*;
import java.util.zip.GZIPInputStream;
/**
*
* #author ron
*/
public class SplitFreebase {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
try {
BufferedReader in = new BufferedReader(
new InputStreamReader(
new GZIPInputStream(
new FileInputStream(args[0]))));
BufferedWriter out = null;
long cnt = 0;
int file_cnt = 0;
while (in.ready()) {
if ((cnt % 10000000) == 0) {
String name = args[0].substring(0, args[0].length() - 3)
+ "_" + file_cnt + ".gz";
if (out != null) {
out.close();
}
out = new BufferedWriter(
new OutputStreamWriter(
new GZIPOutputStream(
new FileOutputStream(name))));
file_cnt++;
}
if (out != null) {
out.write(in.readLine());
out.newLine();
}
cnt++;
}
if (out != null) {
out.close();
}
in.close();
} catch (FileNotFoundException ex) {
Logger.getLogger(SplitFreebase.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(SplitFreebase.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
This works pretty well. Java failed and ruby did too in the exact same way. I divided the problem substituting gunzip STDIN and it works now.
Freebase file:
-rw-r--r-- 1 ron users 29498770878 Nov 2 18:13 freebase-rdf-2014-11-02-00-00.gz
$ gunzip -c freebase_s19.gz | ./free_sp_stdin.rb howdy_pardner
Here is the script. I'm not a ruby programmer, may not be elegant.
require 'zlib'
file_cnt = 0;
error = ""
wgz = nil
if ARGV[1] != nil
file_cnt = ARGV[1].to_i;
end
base_name = ARGV[0]
STDIN.each_with_index do |line, idx|
#puts idx.to_s+" "+line
if((idx % 100000000) == 0)
if(idx != 0)
wgz.close
end
wgz = Zlib::GzipWriter.open(base_name + file_cnt.to_s + ".gz")
puts base_name + file_cnt.to_s + ".gz"
file_cnt+=1
end
if((idx % 1000000) == 0)
print "."
end
error = line
wgz << line
end
wgz.close
puts error

Detect USB devices event

I made a console application which detects plugin and plugout events for all type of usb devices. but I wanted some filteration in it like I wanted to detect only webcams . This was done by using GUID class. The class for webcam is 'Image' class with GUID "{6bdd1fc5-810f-11d0-bec7-08002be2092f}" .The problem is that this 'Image' class is also used for scanners and I dont want to detect scanners.The code is given below:
static void Main(string[] args)
{
WqlEventQuery weqQuery = new WqlEventQuery();
weqQuery.EventClassName = "__InstanceOperationEvent";
weqQuery.WithinInterval = new TimeSpan(0, 0, 3);
weqQuery.Condition = #"TargetInstance ISA 'Win32_PnPEntity'";
ManagementEventWatcher m_mewWatcher = new ManagementEventWatcher(weqQuery);
m_mewWatcher.EventArrived += new EventArrivedEventHandler(m_mewWatcher_EventArrived);
m_mewWatcher.Start();
Console.ReadLine();
}
static void m_mewWatcher_EventArrived(object sender, EventArrivedEventArgs e)
{
bool bUSBEvent = false;
string deviceCaption = "";
string deviceType = "";
foreach (PropertyData pdData in e.NewEvent.Properties)
{
try
{
ManagementBaseObject mbo = (ManagementBaseObject)pdData.Value;
if (mbo != null)
{
foreach (PropertyData pdDataSub in mbo.Properties)
{
Console.WriteLine(pdDataSub.Name + " = " + pdDataSub.Value);
if (pdDataSub.Name == "Caption")
{
deviceCaption = pdDataSub.Value.ToString();
}
if (pdDataSub.Name == "ClassGuid" && pdDataSub.Value.ToString() == "{6bdd1fc5-810f-11d0-bec7-08002be2092f}")
{
bUSBEvent = true;
deviceType = "Image";
}
}
if (bUSBEvent)
{
if (e.NewEvent.ClassPath.ClassName == "__InstanceCreationEvent")
{
Console.WriteLine("A " + deviceType + " device " + deviceCaption + " was plugged in at " + DateTime.Now.ToString());
}
else if (e.NewEvent.ClassPath.ClassName == "__InstanceDeletionEvent")
{
Console.WriteLine("A " + deviceType + " device " + deviceCaption + " was plugged out at " + DateTime.Now.ToString());
}
}
}
}
catch (Exception ex)
{
}
}
}
for references check this link
I waited but no body answered this question so, after seeing all properties of ManagementBaseObject I found that there is a property named Service which is different for scanners. In scanners the value of Service property is usbscan while in cameras it is usbvideo.
eg.
you can do something like this
if (mbo.Properties["Service"].Value.ToString() == "usbscan")
{
//then it means it is a scanner
}
else
{
//then it means it is a camera
}
note: The main question was that how can we differentiate between a scanner and a webcam because they both use same GUID.