How to Container.Update , Container.Refresh? - xbmc

In my Kodi plugin I build a container with list items:
elif methode == 'get_item_serienplaner':
sp_items = refreshWidget(__LS__(30116))
url = '-'
for sitem in sp_items:
li = xbmcgui.ListItem(label2=sitem['TVShow'], label=sitem['Title'], thumbnailImage=sitem['Thumb'])
li.setProperty("channel", sitem['Channel'])
li.setArt({'poster': sitem['Poster']})
li.setProperty("plot", sitem['Description'])
li.setProperty("staffel", sitem['Staffel'])
li.setProperty("episode", sitem['Episode'])
li.setProperty("starttime", sitem['Starttime'])
li.setProperty("rating", sitem['Rating'])
li.setProperty("senderlogo", sitem['Logo'])
li.setProperty("genre", sitem['Genre'])
li.setProperty("date", sitem['Datum'])
li.setProperty("runtime", sitem['RunningTime'])
li.setProperty("studio", sitem['Studio'])
li.setProperty("year", sitem['Jahr'])
li.setProperty("altersfreigabe", sitem['Altersfreigabe'])
li.setProperty("status", sitem['Status'])
li.setProperty("label", sitem['Title'])
li.setProperty("label2", sitem['TVShow'])
xbmcplugin.addDirectoryItem(handle=addon_handle, url=url, listitem=li)
xbmcplugin.endOfDirectory(addon_handle)
So the container is called from the skin as follows:
<content>plugin://plugin.program.serienplaner/?methode=get_item_serienplaner</content>
Now I have the problem that refreshWidget(__LS__(30116)) will be updated every 5min but how can I update the container with the ListItems for Kodi so that this will be updated to?
I tried with Container.Update() and Container.Refresh but it did not work.

Related

Authorize.net Sandbox Accept page testing- always declined?

I’m attempting to test Accept Hosted payment page(redirect-method) with my sandbox. For this, I’m using the GetAnAcceptPaymentPage from the Java sample code application to generate a token string for a payment, specified the autoLoginId and transactionKey for my sandbox, and setting $1.00 as the amount. I’m then posting the returned token string to https://test.authorize.net/payment/payment with a “token” form element containing that string. This much appears to be working, and I do get a payment page showing the $1.00 amount. However, no matter what values I enter onto that payment page, pressing the “Pay” button just shows “The transaction has been declined.” in red text at the bottom of the form. I’ve confirmed that my sandbox is set to “Live” mode, and have looked at the following link to use what I believe should be valid values for testing: https://developer.authorize.net/hello_world/testing_guide/. I'm hoping someone can tell me why I can't get any result other than "The transaction has been declined".
public String getTokenValue() {
ApiOperationBase.setEnvironment(Environment.SANDBOX);
MerchantAuthenticationType merchantAuthenticationType = new MerchantAuthenticationType();
merchantAuthenticationType.setName("xxxxx");
merchantAuthenticationType.setTransactionKey("xxxxxx");
ApiOperationBase.setMerchantAuthentication(merchantAuthenticationType);
// Create the payment transaction request
TransactionRequestType txnRequest = new TransactionRequestType();
txnRequest.setTransactionType(TransactionTypeEnum.AUTH_CAPTURE_TRANSACTION.value());
txnRequest.setAmount(new BigDecimal(1.00).setScale(2, RoundingMode.CEILING));
OrderExType order = new OrderExType();
order.setInvoiceNumber("2");
txnRequest.setOrder(order);
CustomerProfilePaymentType cpp = new CustomerProfilePaymentType();
cpp.setCustomerProfileId("xxxx");
cpp.setCreateProfile(true);
txnRequest.setProfile(cpp);
SettingType setting1 = new SettingType();
setting1.setSettingName("hostedPaymentButtonOptions");
setting1.setSettingValue("{\"text\": \"Proceed\"}");
SettingType setting2 = new SettingType();
setting2.setSettingName("hostedPaymentOrderOptions");
setting2.setSettingValue("{\"show\": false}");
SettingType setting3 = new SettingType();
setting3.setSettingName("hostedPaymentPaymentOptions");
setting3.setSettingValue("{\"cardCodeRequired\": true}");
SettingType setting4 = new SettingType();
setting4.setSettingName("hostedPaymentIFrameCommunicatorUrl");
setting4.setSettingValue("{\"url\": \"http://example.com/abc\"}");
ArrayOfSetting alist = new ArrayOfSetting();
alist.getSetting().add(setting1);
alist.getSetting().add(setting2);
alist.getSetting().add(setting3);
alist.getSetting().add(setting4);
GetHostedPaymentPageRequest apiRequest = new GetHostedPaymentPageRequest();
apiRequest.setTransactionRequest(txnRequest);
apiRequest.setHostedPaymentSettings(alist);
GetHostedPaymentPageController controller = new GetHostedPaymentPageController(apiRequest);
controller.execute();
GetHostedPaymentPageResponse response = new GetHostedPaymentPageResponse();
response = controller.getApiResponse();
if (response != null) {
if (response.getMessages().getResultCode() == MessageTypeEnum.OK) {
System.out.println(response.getToken());
} else {
System.out.println("Failed to get hosted payment page: " + response.getMessages().getResultCode());
}
}
return response.getToken();
}
>>> order.setInvoiceNumber("2");
Set the invoice number to a different value than 2, this value is used in Sandbox to trigger decline for testing purposes.

Acumatica GI - Inventory Transaction History Screen

I want to create a GI for Inventory Transaction History Screen (IN405000).
Since the table InventoryTranHistEnqResult isn't present in the database...few of the columns of this screen are taken from INTran Table.
I am not able to find following columns: BegQty, QtyIn, QtyOut, EndQty...
I also tried the following query on database to find these columns
SELECT c.name AS ColName, t.name AS TableName
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
WHERE c.name LIKE '%EndQty%'
The DAC for these fields is:
enter image description here
Looking at the information behind the page in the page Graph will give you the answers to your question. Inventory Transaction History Screen (IN405000) uses graph InventoryTranHistEnq. The grid in this page uses DAC InventoryTranHistEnqResult in the following view:
PXSelectJoin<InventoryTranHistEnqResult,
CrossJoin<INTran>,
Where<True, Equal<True>>,
OrderBy<Asc<InventoryTranHistEnqResult.gridLineNbr>>> ResultRecords
The ResultsRecords are built dynamically in the inquiry using the following:
protected virtual IEnumerable resultRecords()
{
int startRow = PXView.StartRow;
int totalRows = 0;
decimal? beginQty = null;
List<object> list = InternalResultRecords.View.Select(PXView.Currents, PXView.Parameters, new object[PXView.SortColumns.Length], PXView.SortColumns, PXView.Descendings, PXView.Filters, ref startRow, PXView.MaximumRows, ref totalRows);
PXView.StartRow = 0;
foreach (PXResult<InventoryTranHistEnqResult> item in list)
{
InventoryTranHistEnqResult it = (InventoryTranHistEnqResult)item;
it.BegQty = beginQty = (beginQty ?? it.BegQty);
decimal? QtyIn = it.QtyIn;
decimal? QtyOut = it.QtyOut;
beginQty += (QtyIn ?? 0m) - (QtyOut ?? 0m);
it.EndQty = beginQty;
}
return list;
}
So i guess the short answer is you cannot use the results of this page for a GI as it is built in the page only. You might want to look into adding what you need to this history page via a customization or make your own version of this page/graph/dac if the information you need is that important.

Numbered lists continues when Apps Script appends template-content into document

I have an Apps Script that copies the content of an template-file to the end of a document. It works with one minor annoyance: the numbered list continues from one copy to the next.
I have many different templates that users can append to the end of the document. Each template is stored in its own Document.
function addSub(template_id){
var mainBody = DocumentApp.getActiveDocument().getBody();
var tempBody = DocumentApp.openById(template_id).getBody();
for(var i = 0;i<tempBody .getNumChildren();i++){
var element = tempBody .getChild(i);
if(element.getType() == DocumentApp.ElementType.TABLE)
mainBody.appendTable(element.copy());
else if(element.getType() == DocumentApp.ElementType.PARAGRAPH)
mainBody.appendParagraph(element.copy());
else if(element.getType() == DocumentApp.ElementType.LIST_ITEM)
mainBody.appendListItem(element.copy());
else if(element.getType() == DocumentApp.ElementType.PAGE_BREAK)
mainBody.appendPageBreak(element.copy());
}
}
It could look like this: ( I want the list to reset for each new copy of the template)
table with name of this template
some raw text
List item1
List item2
table with name of this template
some raw text
List item1
List item2
Do you now that ListItems have an ID, which is a STRING and you can access it via myListItem.getListId().
It seems that all your ListItems have the same ID.
If this is the case, the numbering has to be as you described.
Why do they have the same ListID?
I don't know.
Seems that the body.appendListem method always chooses the same listId.
I didn't test it yet, but you could try to set the listID of the newly append ListItem to that of the original document, if they are different.
Yes, i know, the .copy() method should enclose this information, but the body.appendListItem method may not care.
So, you could try to first save the detached copy of the listItem.
Then append it to the new body.
And then set the id of the newly appended listItem to that of the detached copy.
It's stupid, i know, but it may help.
Didn't try it yet.
And i have little experience with listItems, bit what i saw up to now is that there seems to be only one ListId in the body of a document, if you append or insert listItems.
This could be the cause of the problem.
Hope this helps.
After Richard Gantz solved it, It was corrected by this code:
var listItemDictionary = {};//top
...
else if(element.getType() == DocumentApp.ElementType.LIST_ITEM){
var listCopy = element.copy().asListItem()
var lcID = listCopy.getListId();
if (listItemDictionary[lcID] == null){
var tempLI = mainBody.appendListItem("temp")
listItemDictionary[lcID] = tempLI;
}
Logger.log(lcID)
mainBody.insertListItem(childIndex+j, listCopy.setListId(listItemDictionary[lcID]));
}
...
if(listItemDictionary){//bottom
mainBody.appendParagraph("");
for(var key in listItemDictionary){
listItemDictionary[key].clear().removeFromParent()
}
}
Based on the answer from Niklas Ternvall/Richard Gantz, I found a simpler solution for the case of each template having no more than one list.
function addSub(template_id) {
var mainBody = DocumentApp.getActiveDocument().getBody();
var tempBody = DocumentApp.openById(template_id).getBody();
var listID = null;
for(var i = 0;i<tempBody.getNumChildren();i++){
var element = tempBody.getChild(i).copy();
var type = element.getType();
if(type == DocumentApp.ElementType.TABLE)
mainBody.appendTable(element);
else if(type == DocumentApp.ElementType.PARAGRAPH)
mainBody.appendParagraph(element);
else if(type == DocumentApp.ElementType.LIST_ITEM){
if(listID==null) // First list item
listID = mainBody.appendListItem('temp'); // Define new listID
mainBody.appendListItem(element).setListId(listID); // Apply to copy
}
else if(type == DocumentApp.ElementType.PAGE_BREAK)
mainBody.appendPageBreak(element);
}
mainBody.removeChild(listID); // Delete temporary list item
}
Each time you call the function, listID=null is the indicator for whether or not there have been any list items in the template. When you get to the first list item, appending the text 'temp' forces a new list and hence a new listID that you can apply to the list items from the template. After you finish going through the template, mainBody.removeChild(listID) removes 'temp' from the top of your list.
This solution worked for me when using one template 100 times in one document, essentially as a mail merge. I'm fairly new to Apps Script, so I would appreciate any feedback if there is a reason this wouldn't work for a single-list template.

Dynamodb pagination of 10 results

I have a message table which I would like to get the last 10 messages for that user and if they click more it would retrieve another 10 until there were no more message left. I could not see how to do this, so far I am able to get message based on time, but this is not exactly what I want. Reading through the documentation I can see it a method called LastEvaluatedKey, but where and how do I use this I can't find a working example of this. This is my code for time:
long startDateMilli = (new Date()).getTime() - (15L*24L*60L*60L*1000L);
long endDateMilli = (new Date()).getTime() - (5L*24L*60L*60L*1000L);
java.text.SimpleDateFormat df = new java.text.SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
String startDate = df.format(startDateMilli);
String endDate = df.format(endDateMilli);
QuerySpec spec = new QuerySpec()
.withProjectionExpression("to,fr,sta,cr")
.withKeyConditionExpression("to = :v_to and cr between :v_start_dt and :v_end_dt")
.withValueMap(new ValueMap()
.withString(":v_id", username)
.withString(":v_start_dt", startDate)
.withString(":v_end_dt", endDate));
ItemCollection<QueryOutcome> items = table.query(spec);
System.out.println("\nfindRepliesPostedWithinTimePeriod results:");
Iterator<Item> iterator = items.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next().toJSONPretty());
}
How can I modify this to eliminate the time based pagination and use instead a last 10 messages type of pagination?

Tkinter forgetting to finish the function

I am again asking a question on this progressbar project; although this should just be a clarification question.
My code causes for a progressbar to be created to track the creation of a file. The user selects the type of file they want to create and then hits "go" which causes for the file to begin changing and for the progressbar to appear. Progressbar works great. File writing/manipulation works great.
Problem: When the user selects several files to manipulate, despite the progressbars being created correctly, they do NOT update correctly. At first I thought that clicking on a button multiple times causes for tkinter to forget the root.after() function it was doing previously but after playing with a (much simpler) sample code I realized that this is not the case.
Question: How do I make sure tkinter doesn't stop implementing the first function even when the same function is restarted with different parameters?
Below are parts of my code to describe what I am doing.
progbarlock = False # start with the prograssbar marked as not occupied
class guibuild:
def __init__(self):
self.root = root
guibuild.progbarlock = False
global theframe
theframe = Frame(root)
job_name = e.get()
label = Label(theframe,text = job_name).pack(side=LEFT,padx =2)
self.progbar = Meter(theframe) #makes the progressbar object
self.progbar.set(0.0) #sets the initial value to 0
self.progbar.pack(side=LEFT)
self.counter = 0
self.i = float(0) #i is the value set to the progressbar
def stop_progbar(self):
self.progbar.stop()
def begin(self):
self.interval()
self.Status_bar()
theframe.pack(anchor="s")
def interval(self):
if guibuild.progbarlock == False:
guibuild.progbarlock = True
def update(self):
the_file = open('running_file.json')
data = json.load(the_file)
curr = data["current_line"]
total = data["total_lines"]
if self.i == 1.0:
self.stop_progbar
rint "100% - process is done"
self.root.after_cancel(self.interval)
elif curr == self.counter:
self.root.after(5000, self.interval)
elif curr == self.counter+1:
self.i += 1.0/total
self.progbar.set(self.i) #apply the new value of i to the progressbar
self.counter += 1
self.stop_progbar
self.root.after(5000, self.interval)
elif curr > self.counter+1:
self.i += 1.0/total*(curr-self.counter)
self.progbar.set(self.i) #apply the new value of i to the progressbar
self.counter = curr
self.stop_progbar
self.root.after(5000, self.interval)
else:
print "something is wrong - running.json is not available"
self.root.after(5000, self.interval)
guibuild.progbarlock = False
def start_process():
makeRequest() #this is defined much earlier in the code and includes all the file creation and manipulation
guibuild().begin()
button4 = Button(root,text="GO", command = start_process).pack()
NOTE:makeRequest() depends entirely on user input and the user input changes each time "go" is pressed.