How to use AspectHistogramContainer in ebay Finding API? - java

I am a newbie trying to write a program to get a database of dress images from eBay using the finding API. I am programming in Java and using Windows 7 OS. After taking the keyword to be searched for from the user, I used the FindItemsAdvanced call for getting the list of products under that category. I want to get the attributes of each of those items like colour, sleeve length, etc. For this, I used AspectHistogramContainer to get the aspects and the values. The code snippet is below:
AspectHistogramContainer aspectContainer=new AspectHistogramContainer();
aspectContainer=advanceResponse.getAspectHistogramContainer();
aspectContainer.setDomainDisplayName(keywords);
aspectContainer.setDomainName(keywords);
List<Aspect> aspectList=aspectContainer.getAspect();
for(Aspect aspect:aspectList)
{
System.out.println(aspect.getName());
List<AspectValueHistogram> aspectValueList= aspect.getValueHistogram();
for(AspectValueHistogram aspectValue:aspectValueList)
{
System.out.println(aspectValue.getValueName());
}
}
advanceResponse is the FindItemsAdvancedResponse Object.
But the AspectHistogramContainer is always only null, i.e the items have no aspects. I gave only leaf categories as input as required by AspectHistogramContainer. I have tried all avenues but cant find the reason.Could somebody please tell me what is wrong?

Figured it out! I had to set the category Id for the GetHistogramRequest object and then use that object to get the AspectHistogramContainer. The code snippet is below:
GetHistogramsRequest abcd = new GetHistogramsRequest();
abcd.setCategoryId(CatID.toString());
GetHistogramsResponse bb = port.getHistograms(abcd);
advanceResponse.setAspectHistogramContainer(bb.getAspectHistogramContainer());
AspectHistogramContainer aspectContainer=new AspectHistogramContainer();
aspectContainer=advanceResponse.getAspectHistogramContainer();
aspectContainer.setDomainDisplayName(keywords);
aspectContainer.setDomainName(keywords);
List<Aspect> aspectList=aspectContainer.getAspect();
for(Aspect aspect:aspectList)
{
System.out.println(aspect.getName());
List<AspectValueHistogram> aspectValueList= aspect.getValueHistogram();
for(AspectValueHistogram aspectValue:aspectValueList)
{
System.out.println(aspectValue.getValueName());
}
}
CatId is the categoryId and advanceResponse is the FindItemsByAdvanceRequestObject.But this still only gives the aspects under each category. To get the specific aspect of each item under that category, aspect filter should be used. I am not sure of how to initalise the aspect values for each aspect in the aspect filter and how to associate it with a response object. Any ideas?

Related

CommandExecuteIn Background throws a "Not an (encodable) value" error

I am currently trying to implement file exports in background so that the user can do some actions while the file is downloading.
I used the apache isis CommandExexuteIn:Background action attribute. However, I got an error
"Not an (encodable) value", this is an error thrown by the ScalarValueRenderer class.
This is how my method looks like:
#Action(semantics = SemanticsOf.SAFE,
command = CommandReification.ENABLED)
commandExecuteIn = CommandExecuteIn.BACKGROUND)
public Blob exportViewAsPdf() {
final Contact contact = this;
final String filename = this.businessName + " Contact Details";
final Map<String, Object> parameters = new HashMap<>();
parameters.put("contact", contact);
final String template = templateLoader.buildFromTemplate(Contact.class, "ContactViewTemplate", parameters);
return pdfExporter.exportAsPdf(filename, template);
}
I think the error has something to do with the command not actually invoking the action but returns the persisted background command.
This implementation actually worked on the method where there is no return type. Did I miss something? Or is there a way to implement background command and get the expected results?
interesting use case, but it's not one I anticipated when that part of the framework was implemented, so I'm not surprised it doesn't work. Obviously the error message you are getting here is pretty obscure, so I've raised a
JIRA ticket to see if we could at least improve that.
I'm interested to know in what user experience you think the framework should provide here?
In the Estatio application that we work on (that has driven out many of the features added to the framework over the last few years) we have a somewhat similar requirement to obtain PDFs from a reporting server (which takes 5 to 10 seconds) and then download them. This is for all the tenants in a shopping centre, so there could be 5 to 50 of these to generate in a single go. The design we went with was to move the rendering into a background command (similar to the templateLoader.buildFromTemplate(...) and pdfExporter.exportAsPdf(...) method calls in your code fragment, and to capture the output as a Document, via the document module. We then use the pdfbox addon to stitch all the document PDFs together as a single downloadable PDF for printing.
Hopefully that gives you some ideas of a different way to support your use case
Thx
Dan

Enumerate Custom Slot Values from Speechlet

Is there any way to inspect or enumerate the Custom Slot Values that are set-up in your interaction model? For Instance, Say you have an intent schema with the following intent:
{
"intent": "MySuperCoolIntent",
"slots":
[
{
"name": "ShapesNSuch",
"type": "LIST_OF_SHAPES"
}
]
}
Furthermore, you've defined the LIST_OF_SHAPES Custom Slot to have the following Values:
SQUARE
TRIANGLE
CIRCLE
ICOSADECAHECKASPECKAHEDRON
ROUND
HUSKY
Question: is there a method I can call from my Speechlet or my RequestStreamHandler that will give me an enumeration of those Custom Slot Values??
I have looked through the Alexa Skills Kit's SDK Javadocs Located Here
And I'm not finding anything.
I know I can get the Slot's value that is sent in with the intent:
String slotValue = incomingIntentRequest.getIntent().getSlot("LIST_OF_SHAPES").getValue();
I can even enumerate ALL the incoming Slots (and with it their values):
Map<String, Slot> slotMap = IncomingIntentRequest.getIntent().getSlots();
for(Map.Entry<String, Slot> entry : slotMap.entrySet())
{
String key = entry.getKey();
Slot slot = (Slot)entry.getValue();
String slotName = slot.getName();
String slotValue = slot.getValue();
//do something nifty with the current slot info....
}
What I would really like is something like:
String myAppId = "amzn1.echo-sdk-ams.app.<TheRestOfMyID>";
List<String> posibleSlotValues = SomeMagicAlexaAPI.getAllSlotValues(myAppId, "LIST_OF_SHAPES");
With this information I wouldn't have to maintain two separate "Lists" or "Enumerations"; One within the interaction Model and another one within my Request Handler. Seems like this should be a thing right?
No, the API does not allow you to do this.
However, since your interaction model is intimately tied with your development, I would suggest you check in the model with your source code in your source control system. If you are going to do that, you might as well put it with your source. Depending on your language, that also means you can probably read it during run-time.
Using this technique, you can gain access to your interaction model at run-time. Instead of doing it automatically through an API, you do it by best practice.
You can see several examples of this in action for Java in TsaTsaTzu's examples.
No - there is nothing in the API that allows you to do that.
You can see the full extent of the Request Body structure Alexa gives you to work with. It is very simple and available here:
https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/alexa-skills-kit-interface-reference#Request%20Format
Please note, the Request Body is not to be confused with the request, which is a structure in the request body, with two siblings: version and session.

I am coding in Android Studio, and I need to fetch and display a specific line of data from a specific webpage

I am very new to coding in Java/Android Studio. I have everything setup that I have been able to figure out thus far. I have a button, and I need to put code inside of the button click event that will fetch information from a website, convert it to a string and display it. I figured I would have to use the html source code in order to do this, so I have installed Jsoup html parser. All of the help with Jsoup I have found only leads me up to getting the HTML into a "Document". And I am not sure if that is the best way to accomplish what I need. Can anyone tell me what code to use to fetch the html code from the website, and then do a search through the html looking for a specific match, and convert that match to a string. Or can anyone tell me if there is a better way to do this. I only need to grab one piece of information and display it.
Here is the piece of html code that contains the value I want:
writeBidRow('Wheat',-60,false,false,false,0.5,'01/15/2015','02/26/2015','All',' ',' ',60,'even','c=2246&l=3519&d=G15',quotes['KEH15'], 0-0);
I need to grab and display whatever value represents the quotes['KEH15'], in that html code.
Thank you in advance for your help.
Keith
Grabbing raw HTML is an extremely tedious way to access information from the web, bad practice, and difficult to maintain in the case that wherever you are fetching the info from changes their HTML.
I don't know your specific situation and what the data is that you are fetching, but if there is another way for you to fetch that data via an API, use that instead.
Since you say you are pretty new to Android and Java, let me explain something I wish had been explained to me very early on (although I am mostly self taught).
The way people access information across the Internet is traditionally through HTML and JavaScript (which is interpreted by your browser like Chrome or Firefox to look pretty), which are transferred over the internet using the protocol called HTTP. This is a great way for humans to communicate with computers that are far away, and the average person probably doesn't realize that there is more to the internet than this--your browser and the websites you can go to.
Although there are multiple methods, for the purpose of what I think you're looking for, applications communicate over the internet a slightly different way:
When an android application asks a server for some information, rather than returning HTML and JavaScript which is intended for human consumption, the server will (traditionally) return what's called JSON (or sometimes XML, which is very similar). JSON is a very simple way to get information about an object, and put it into a form that is readable easily by both humans (developers) and computers, and can be transmitted over the internet easily. For example, let's say you ask a server for some kind of "Video" object for an app that plays video, it may give you something like this:
{
"name": "Gangnam Style",
"metadata": {
"url": "https://www.youtube.com/watch?v=9bZkp7q19f0",
"views": 2000000000,
"ageRestricted": false,
"likes": 43434
"dislikes":124
},
"comments": [
{
"username": "John",
"comment": "10/10 would watch again"
},
{
"username": "Jane",
"number": "12/10 with rice"
}
]
}
That is very readable by us humans, but also by computers! We know the name is "Gangnam Style", the link of the video, etc.
A super helpful way to interact with JSON in Java and Android is Google's GSON library, which lets you cast a Java object as JSON or parse a JSON object to a Java object.
To get this information in the first place, you have to make a network call to an API, Application Programming Interface. Just a fancy term for communication between a server and a client. One very cool, free, and easy to understand API that I will use for this example is the OMDB API, which just spits back information about movies from IMDB. So how do you talk to the API? Well luckily they've got some nice documentation, which says that to get information on a movie we need to use some parameters in the url, like perhaps
http://www.omdbapi.com/?t=Interstellar
They want a title with the parameter "t". We could put a year, or return type, but this should be good to understand the basics. If you go to that URL in your browser, it spits back lots of information about Interstellar in JSON form. That stuff we were talking about! So how would you get this information from your Android application?
Well, you could use Android's built in HttpUrlConnection classes and research for a few hours on why your calls aren't working. But doesn't essentially every app now use networking? Why reinvent the wheel when virtually every valuable app out there has probably done this work before? Perhaps we can find some code online to do this work for us.
Or even better, a library! In particular, an open source library developed by Square, retrofit. There are multiple libraries like it (go ahead and research that out, it's best to find the best fit for your project), but the idea is they do all the hard work for you like low level network programming. Following their guides, you can reduce a lot of code work into just a few lines. So for our OMDB API example, we can set up our network calls like this:
//OMDB API
public ApiClient{
//an instance of this client object
private static OmdbApiInterface sOmdbApiInterface;
//if the omdbApiInterface object has been instantiated, return it, but if not, build it then return it.
public static OmdbApiInterface getOmdbApiClient() {
if (sOmdbApiInterface == null) {
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("http://www.omdbapi.com")
.build();
sOmdbApiInterface = restAdapter.create(OmdbApiInterface.class);
}
return sOmdbApiInterface;
}
public interface OmdbApiInterface {
#GET("/")
void getInfo(#Query("t") String title, Callback<JsonObject> callback);
}
}
After you have researched and understand what's going on up there using their documentation, we can now use this class that we have set up anywhere in your application to call the API:
//you could get a user input string and pass it in as movieName
ApiClient.getOmdbApiClient().getInfo(movieName, new Callback<List<MovieInfo>>() {
//the nice thing here is that RetroFit deals with the JSON for you, so you can just get information right here from the JSON object
#Override
public void success(JsonObject movies, Response response) {
Log.i("TAG","Movie name is " + movies.getString("Title");
}
#Override
public void failure(RetrofitError error) {
Log.e("TAG", error.getMessage());
}
});
Now you've made an API call to get info from across the web! Congratulations! Now do what you want with the data. In this case we used Omdb but you can use anything that has this method of communication. For your purposes, I don't know exactly what data you are trying to get, but if it's possible, try to find a public API or something where you can get it using a method similar to this.
Let me know if you've got any questions.
Cheers!
As #caleb-allen said, if an API is available to you, it's better to use that.
However, I'm assuming that the web page is all you have to work with.
There are many libraries that can be used on Android to get the content of a URL.
Choices range from using the bare-bones HTTPUrlConnection to slightly higher-level HTTPClient to using robust libraries like Retrofit. I personally recommend Retrofit. Whatever you do, make sure that your HTTP access is asynchronous, and not done on the UI thread. Retrofit will handle this for you by default.
For parsing the results, I've had good results in the past using the open-source HTMLCleaner library - see http://htmlcleaner.sourceforge.net
Similar to JSoup, it takes a possibly-badly-formed HTML document and creates a valid XML document from it.
Once you have a valid XML document, you can use HTMLCleaner's implementation of the XML DOM to parse the document to find what you need.
Here, for example, is a method that I use to parse the names of 'projects' from a <table> element on a web page where projects are links within the table:
private List<Project> parseProjects(String html) throws Exception {
List<Project> parsedProjects = new ArrayList<Project>();
HtmlCleaner pageParser = new HtmlCleaner();
TagNode node = pageParser.clean(html);
String xpath = "//table[#class='listtable']".toString();
Object[] tables = node.evaluateXPath(xpath);
TagNode tableNode;
if(tables.length > 1) {
tableNode = (TagNode) tables[0];
} else {
throw new Exception("projects table not found in html");
}
TagNode[] projectLinks = tableNode.getElementsByName("a", true);
for(int i = 0; i < projectLinks.length; i++) {
TagNode link = projectLinks[i];
String projectName = link.getText().toString();
String href = link.getAttributeByName("href");
String projectIdString = href.split("=")[1];
int projectId = Integer.parseInt(projectIdString);
Project project = new Project(projectId, projectName);
parsedProjects.add(project);
}
return parsedProjects;
}
If you have permission to edit the webpage to add hyper link to specified line of that page you can use this way
First add code for head of line that you want to go there in your page
head your text if wanna
Then in your apk app on control click code enter
This.mwebview.loadurl("https:#######.com.html#target")
in left side of # enter your address of webpage and then #target in this example that your id is target.
Excuse me if my english lang. isn't good

box-api search parameters not working?

I'm using the Java SDK to connect to Box. I find the root folder (this is a small dev instance so I don't mind searching from there.) I execute the search query and I get results. My problem is that the search parameters do not seem to work consistently or at all.
For example, this query
Iterator resultSet = rootFolder.search("query=NR_chewy_chic_swt_pot_app&file_extensions=jpg&content_type=name&type=file").iterator();
returns three entries.
NR_chewy_chic_swt_pot_app.jpg
NR Chewy Chicken AD02.xls
PreInvoice_M197301-3644756_NR Chewy Treats SURP.pdf
I remove the substring "&file_extensions=jpg" because it doesn't seem to do anything and save/recompile/run and I get the same three results.
I change "&type=file" to "&type=folder" and I get the same three results.
I change "query=NR_chewy_chic_swt_pot_app" to "query=NR" and I get NO results. Even though SO user Peter (who appears to work for Box) says that partial strings should match1.
I've tried rearranging the order of the search parameters to no avail. What am I missing?
Thanks,
Eric B.
Advanced search has yet to be implemented in the SDK (since it's still in beta), but it will be added in the coming weeks.
The reason why your call doesn't work is because the query method parameter is sent as the "query" URL parameter in the API call. Therefore, the ampersands in your query string are being escaped.
If you need an immediate workaround, you can use the BoxAPIRequest and BoxAPIResponse classes to make a custom search request. For example:
BoxAPIConnection api = new BoxAPIConnection("token");
URL url = new URL("https://api.box.com/2.0/search?query=NR_chewy_chic_swt_pot_app&file_extensions=jpg&content_type=name&type=file")
BoxAPIRequest request = new BoxAPIRequest(api, url, "GET");
BoxJSONResponse response = (BoxJSONResponse) request.send();
String json = response.getJSON();
Sorry that this wasn't clear. We'll update the documentation to make it more explicit that query represents the query field and not the URL query string.

How to set the content of a RichTextItem field in a Notes document?

This one seems like it should be simple enough. I'm writing a Notes Agent in Java; it calculates a fairly large amount of numeric data (a 6400-entry array of doubles) that I want to store in an existing document, updating a field. Because of Notes' field limitations, I figured I needed to use a RichText field to do that. (My initial attempt to write to a multi-value Number field resulted in it failing to save somewhere between an array of size 4000 and 5000.) It's not clear to me how one stores that value in a RichTextItem, though. All my attempts have failed. In one case, using doc.replaceItemValue(), it seemed to convert the item to a Text List. Getting the item, casting it to a RichTextItem, and calling setValues() or setValueString() doesn't seem to do anything. This shouldn't be this hard! Any pointers?
(Alternately: Any better suggestion for how to store my array in a document in the database?)
Thanks,
Reid
You'll need to create a RichTextItem and use the methods on that object to populate it:
import lotus.domino.*;
import java.util.Vector;
public class JavaAgent extends AgentBase {
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext =
session.getAgentContext();
// (Your code goes here)
Database db = agentContext.getCurrentDatabase();
Document doc = db.createDocument();
Item subject = doc.replaceItemValue("Subject",
"Project description");
RichTextItem body = doc.createRichTextItem("Body");
body.appendText("Cartoon book for children
ages 9-12");
// Print text of subject and body
System.out.println(subject.getText());
System.out.println(body.getText());
// Save the document
doc.save(true, true);
} catch(Exception e) {
e.printStackTrace();
}
}
}
UPDATE:
If you need to edit an existing document, instead of creating a new rich text item, you would get the existing one.
RichTextItem body = doc.GetFirstItem("Body"); // instead of createRichTextItem
You can bypass the Notes' field limitations. You can flag your item as «contains non-summary data» by using the NotesItem.IsSummary property. You need to set this property to false. But remember, you cannot use this item in views and folders.
Here is example:
Vector vector = new Vector();
for (int index = 0; index<6400;index++)
vector.addElement(new Double(Math.random()*100));
Item item = document.replaceItemValue("YourFieldName", vector);
item.setSummary(false);
document.save(true,true);
As for the question of "better" solution. I've recently written some code where I serialize/deserialize Java objects as JSON strings. This way they are well readable and easily restorable. I guess for the plain array it's a little problem. Especially if you do not want to restore it and have not interest to look at it (well, but probably it should be one or other :-)
And yes, you have to store it in the rich text anyway. Alternative you might write a text document and attach it in the RT field (again RT :-). Pretty usual scenario and easy to do.
Finally you could store data as database objects, but I guess from Java you do not really have access to do it. And it does not seem to be in any way better.

Categories

Resources