How to list all notes in an Evernote business notebook - ruby

Using https://github.com/evernote/evernote-oauth-ruby, how can I list all notes in a business notebook?
I'm able to get all business notebooks with
business_note_store.listNotebooks
but, listing all notes where business_notebook_id comes from in the above statement, using
business_note_store.findNotesMetadata(
#client.access_token.token,
filter(business_notebook_id), 0, 200, specs
).notes
results in an exception when I use:
def filter(notebook_id)
filter = Evernote::EDAM::NoteStore::NoteFilter.new
filter.order = Evernote::EDAM::Type::NoteSortOrder::UPDATED
filter.notebookGuid = notebook_id
filter
end
def spec
spec = Evernote::EDAM::NoteStore::NotesMetadataResultSpec.new
spec.includeTitle = true
spec.includeUpdated = true
spec
end

it works, when I removed the token
business_note_store.findNotesMetadata(
filter(business_notebook_id), 0, 200, specs
).notes
works fine. now i just wanna know why :)

Related

How can I retrieve the "Description" field of inspect.exe in my pywinauto based automation script?

I have the following SysTreeView32 element from which I would like to retrieve the "Description" field:
In my pywinauto script (based on win32 backend), I can retrieve pretty easily the TreeViewWrapper element by looking for the class type and eventually looking at the items text, but some information that I need is only available in the Description field of this element.
I was not able to find a way to retrieve this information.
I tried in UIA mode as well:
But in this case, it does not even appear in the information.
So I tried using the TreeItemWrapper element with the UIA backend in pywinauto, but I could not find the appropriate description not even in the UIAElementInfo. Although something looked pretty similar in the following line:
impl = uia_defs.get_elem_interface(elem, "LegacyIAccessible").
When I call the legacy_properties of the uia_controls.TreeItemWrapper, I get:
{'ChildId': 0,
'DefaultAction': '',
'Description': '',
'Help': '',
'KeyboardShortcut': '',
'Name': 'Execute multiple tasks(MultiTask_ImportSysD)',
'Role': 36,
'State': 3145730,
'Value': ''}
And in there, the Description is empty.
I'm guessing that property comes from IAccessible::get_accDescription.
MSDN says that property is deprecated but if you still want to use it, call AccessibleObjectFromWindow to get a IAccessible for a window.
Finally, I could not find this possibility through the pywinauto exposed API.
Although pywniauto does expose the Description property through the legacy_properties of the uia_controls.TreeItemWrapper instance, but it returns an empty string. This correlates with the note in teh Windows SDK documentation that states:
Note The Description property is often used incorrectly and is not supported by Microsoft UI Automation. Microsoft Active Accessibility server developers should not use this property. If more information is needed for accessibility and automation scenarios, use the properties supported by UI Automation elements and control patterns.
In the end, I finally developed a small piece of code to search for the element that I need the description of and I could retrieve the Description from there. Here is the code:
# for OleAcc access
import ctypes
import comtypes, comtypes.automation, comtypes.client
comtypes.client.GetModule('oleacc.dll')
def accDescription(iaccessible, cid):
objChildId = comtypes.automation.VARIANT()
objChildId.vt = comtypes.automation.VT_I4
objChildId.value = cid
objDescription = comtypes.automation.BSTR()
iaccessible._IAccessible__com__get_accDescription(objChildId, ctypes.byref(objDescription))
return objDescription.value
def accRole(iaccessible, cid):
objChildId = comtypes.automation.VARIANT()
objChildId.vt = comtypes.automation.VT_I4
objChildId.value = cid
objRole = comtypes.automation.VARIANT()
objRole.vt = comtypes.automation.VT_BSTR
iaccessible._IAccessible__com__get_accRole(objChildId, objRole)
return AccRoleNameMap[objRole.value]
def accState(iaccessible, cid):
'''Get Element State'''
objChildId = comtypes.automation.VARIANT()
objChildId.vt = comtypes.automation.VT_I4
objChildId.value = cid
objState = comtypes.automation.VARIANT()
iaccessible._IAccessible__com__get_accState(objChildId, ctypes.byref(objState))
return objState.value
def accName(iaccessible, cid):
'''Get Element Name'''
objChildId = comtypes.automation.VARIANT()
objChildId.vt = comtypes.automation.VT_I4
objChildId.value = cid
objName = comtypes.automation.BSTR()
iaccessible._IAccessible__com__get_accName(objChildId, ctypes.byref(objName))
return objName.value
def accDescendants(iaccessible):
"""Iterate all desencendants of an object iaccessible, including the current one.
Arguments:
iaccessible -- the IAccessible element to start from
Yields:
(IAcessible instance, Child id)
"""
yield (iaccessible, 0)
objAccChildArray = (comtypes.automation.VARIANT * iaccessible.accChildCount)()
objAccChildCount = ctypes.c_long()
ctypes.oledll.oleacc.AccessibleChildren(iaccessible, 0, iaccessible.accChildCount, objAccChildArray, ctypes.byref(objAccChildCount))
for i in range(objAccChildCount.value):
objAccChild = objAccChildArray[i]
if objAccChild.vt == comtypes.automation.VT_DISPATCH:
# query the sub element accessible interface
newiaccessible = objAccChild.value.QueryInterface(comtypes.gen.Accessibility.IAccessible)
# then loop over its descendants
for (__i, __c) in accDescendants(newiaccessible):
yield (__i, __c)
else: #if objAccChild.vt == comtypes.automation.VT_I4:
yield (iaccessible, objAccChild.value)
def findObjIAccessible(handle, text):
"""Find the IAccessible based on the name, starting from a specific window handle
Arguments:
handle -- the window handle from which to search for the element
text -- text that should be contained in the name of the IAccessible instance
Return:
(None, 0) if not found
(IAccessible instance, child id) of the first element whose name contains the text
"""
iacc = ctypes.POINTER(comtypes.gen.Accessibility.IAccessible)()
ctypes.oledll.oleacc.AccessibleObjectFromWindow(handle, 0, ctypes.byref(comtypes.gen.Accessibility.IAccessible._iid_), ctypes.byref(iacc))
for (ia, ch) in accDescendants(iacc):
n = accName(ia, ch)
if n != None and text in n:
return (ia, ch)
else:
return (None, 0)

Scroll automation appium

I'm doing an automation in Ruby and Appium on mobile, and I need to access a card that is out of range, and I'm using all possible methods and it just happens error ... Does anyone have a solution? I need to down the Recycler view all the way down
Edit:
code
class AuditoriaController
def initialize
#util = UtilMethods.new
#objects = PageAuditoria.new
main = MenuPrincipal.new
#menus = main.menus
#tela_principal = main.tela_principal
#objects_auditoria = #objects.tela_auditoria
end
def acessar_auditoria
data_sync = find_element(:xpath, #tela_principal[:msg_sincronizacao]).text
data_sync.slice!("Última atualização: ")
t = Time.now
while(t.strftime("%d/%m/%Y %H:%M:%S") != data_sync)
btn_sync = find_element(:xpath, #tela_principal[:view_sync])
btn_sync.click
break;
end
list = find_element(:xpath, #tela_principal[:lista])
list.scrollIntoView()
#menu_auditoria = find_element(:xpath, #menus[:menu_auditoria])
#if(menu_auditoria)
# #util.logger("ACHEI AUDITORIA")
#end
end
First get the element(that is card)
Then add the below code
browser.execute_script('arguments[0].scrollIntoView();', card);
Hope it will help you. If you need any more information just comment here
EDIT:
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.execute_script('arguments[0].scrollIntoView();', card)
Here driver is the driver you are using for automation that is appium driver. Here card is the element that you want to get and scroll upto it.
In ruby:
def scroll_to_element(element)
#driverAppium.execute_script('mobile: scroll', name: element.name)
end
This will scroll to the element which you are looking for even if it is offscreen. You should be able to modify for use with Java.
scroll_to_exact(elementname) should do the job for you! This will scroll to through the elements until the specified is visible. This is in Appium_lib for ruby

Save Google Cloud Speech API operation(job) object to retrieve results later

I'm struggling to use the Google Cloud Speech Api with the ruby client (v0.22.2).
I can execute long running jobs and can get results if I use
job.wait_until_done!
but this locks up a server for what can be a long period of time.
According to the API docs, all I really need is the operation name(id).
Is there any way of creating a job object from the operation name and retrieving it that way?
I can't seem to create a functional new job object such as to use the id from #grpc_op
What I want to do is something like:
speech = Google::Cloud::Speech.new(auth_credentials)
job = speech.recognize_job file, options
saved_job = job.to_json #Or some element of that object such that I can retrieve it.
Later, I want to do something like....
job_object = Google::Cloud::Speech::Job.new(saved_job)
job.reload!
job.done?
job.results
Really hoping that makes sense to somebody.
Struggling quite a bit with google's ruby clients on the basis that everything seems to be translated into objects which are much more complex than the ones required to use the API.
Is there some trick that I'm missing here?
You can monkey-patch this functionality to the version you are using, but I would advise upgrading to google-cloud-speech 0.24.0 or later. With those more current versions you can use Operation#id and Project#operation to accomplish this.
require "google/cloud/speech"
speech = Google::Cloud::Speech.new
audio = speech.audio "path/to/audio.raw",
encoding: :linear16,
language: "en-US",
sample_rate: 16000
op = audio.process
# get the operation's id
id = op.id #=> "1234567890"
# construct a new operation object from the id
op2 = speech.operation id
# verify the jobs are the same
op.id == op2.id #=> true
op2.done? #=> false
op2.wait_until_done!
op2.done? #=> true
results = op2.results
Update Since you can't upgrade, you can monkey-patch this functionality to an older-version using the workaround described in GoogleCloudPlatform/google-cloud-ruby#1214:
require "google/cloud/speech"
# Add monkey-patches
module Google
Module Cloud
Module Speech
class Job
def id
#grpc.name
end
end
class Project
def job id
Job.from_grpc(OpenStruct.new(name: id), speech.service).refresh!
end
end
end
end
end
# Use the new monkey-patched methods
speech = Google::Cloud::Speech.new
audio = speech.audio "path/to/audio.raw",
encoding: :linear16,
language: "en-US",
sample_rate: 16000
job = audio.recognize_job
# get the job's id
id = job.id #=> "1234567890"
# construct a new operation object from the id
job2 = speech.job id
# verify the jobs are the same
job.id == job2.id #=> true
job2.done? #=> false
job2.wait_until_done!
job2.done? #=> true
results = job2.results
Ok. Have a very ugly way of solving the issue.
Get the id of the Operation from the job object
operation_id = job.grpc.grpc_op.name
Get an access token to manually use the RestAPI
json_key_io = StringIO.new(ENV["GOOGLE_CLOUD_SPEECH_JSON_KEY"])
authorisation = Google::Auth::ServiceAccountCredentials.make_creds(
json_key_io:json_key_io,
scope:"https://www.googleapis.com/auth/cloud-platform"
)
token = authorisation.fetch_access_token!
Make an api call to retrieve the operation details.
This will return with a "done" => true parameter, once results are in and will display the results. If "done" => true isn't there then you'll have to poll again later until it is.
HTTParty.get(
"https://speech.googleapis.com/v1/operations/#{operation_id}",
headers: {"Authorization" => "Bearer #{token['access_token']}"}
)
There must be a better way of doing that. Seems such an obvious use case for the speech API.
Anyone from google in the house who can explain a much simpler/cleaner way of doing it?

Reporting in Microsoft AdCenter (Sandbox) - RoR

I am using AdCenter API for my RoR application. I searched a lot on Internet to find example of ruby code to fetch account performance report using API, But didn't get.. Now I have written following code but submitGenerateReport returns nil
Here is my code.
report_request = AccountPerformanceReportRequest.new
start_date = 10.days.ago.strftime("%Y-%m-%d")
end_date = Time.zone.now.strftime("%Y-%m-%d")
scope = AccountReportScope.new
scope.accountIds = [AppConfig.adcenter['accountId']]
# Specify the format of the report.
report_request.format = 'Xml'
report_request.returnOnlyCompleteData = false
report_request.language = 'English'
report_request.reportName = "My Account Report"
report_request.aggregation = 'Daily'
report_request.time = ReportTime.new(start_date, end_date)
report_request.columns = %w[ AccountName AccountName GregorianDate CurrentMaxCpc Impressions Clicks ]
report_request.scope = scope
report_request.filter = nil
report = SubmitGenerateReportRequest.new(report_request)
# Returns nil
puts response = svc.submitGenerateReport(report)
I have campaigns, adgroups as well as ads in specified account.
Can anyone please guide me where I am wrong or give some example of reporting adcenter through api using ruby?
Thanks in advance
Got the solution...
The time was not in right format so, start time and end time was unrecognisable in soap request. SOAP debugging helped me a lot..

Ruby: Dynamically defining classes based on user input

I'm creating a library in Ruby that allows the user to access an external API. That API can be accessed via either a SOAP or a REST API. I would like to support both.
I've started by defining the necessary objects in different modules. For example:
soap_connecton = Library::Soap::Connection.new(username, password)
response = soap_connection.create Library::Soap::LibraryObject.new(type, data, etc)
puts response.class # Library::Soap::Response
rest_connecton = Library::Rest::Connection.new(username, password)
response = rest_connection.create Library::Rest::LibraryObject.new(type, data, etc)
puts response.class # Library::Rest::Response
What I would like to do is allow the user to specify that they only wish to use one of the APIs, perhaps something like this:
Library::Modes.set_mode(Library::Modes::Rest)
rest_connection = Library::Connection.new(username, password)
response = rest_connection.create Library::LibraryObject.new(type, data, etc)
puts response.class # Library::Response
However, I have not yet discovered a way to dynamically set, for example, Library::Connection based on the input to Library::Modes.set_mode. What would be the best way to implement this functionality?
Murphy's law prevails; find an answer right after posting the question to Stack Overflow.
This code seems to have worked for me:
module Library
class Modes
Rest = 1
Soap = 2
def self.set_mode(mode)
case mode
when Rest
Library.const_set "Connection", Class.new(Library::Rest::Connection)
Library.const_set "LibraryObject", Class.new(Library::Rest::LibraryObject)
when Soap
Library.const_set "Connection", Class.new(Library::Soap::Connection)
Library.const_set "LibraryObject", Class.new(Library::Soap::LibraryObject)
else
throw "#{mode.to_s} is not a valid Library::Mode"
end
end
end
end
A quick test:
Library::Modes.set_mode(Library::Modes::Rest)
puts Library::Connection.class == Library::Rest::Connection.class # true
c = Library::Connection.new(username, password)

Resources