Retrieve AEM Page Properties via Search/QueryBuilder API - aem

Is there a way to retrieve data stored as page metadata (Page Properties) stored in a separate JCR node via the QueryBuilder API?
Example:
The search results should include the data under ~/article-1/jcr:content/thumbnail. However, the only results I am getting are data under the ~article-1/jcr:content/content (a parsys included on the template).
An example query:
http://localhost:4502/bin/querybuilder.json?p.hits=full&path=/content/path/to/articles
Results in (snippet):
{
"jcr:path":"/content/path/to/articles/article-1",
"jcr:createdBy":"admin",
"jcr:created":"Tue Dec 03 2013 16:26:51 GMT-0500",
"jcr:primaryType":"cq:Page"
},
{
"jcr:path":"/content/path/to/articles/article-1/jcr:content",
"sling:resourceType":"myapp/components/global/page/productdetail",
"jcr:lockIsDeep":true,
"jcr:uuid":"4ddebe08-82e1-44e9-9197-4241dca65bdf",
"jcr:title":"Article 1",
"jcr:mixinTypes":[
"mix:lockable",
"mix:versionable"
],
"jcr:created":"Tue Dec 03 2013 16:26:51 GMT-0500",
"jcr:baseVersion":"24cabbda-1e56-4d37-bfba-d0d52aba1c00",
"cq:lastReplicationAction":"Activate",
"jcr:isCheckedOut":true,
"cq:template":"/apps/myapp/templates/global/productdetail",
"cq:lastModifiedBy":"admin",
"jcr:primaryType":"cq:PageContent",
"jcr:predecessors":[
"24cabbda-1e56-4d37-bfba-d0d52aba1c00"
],
"cq:tags":[
"mysite:mytag"
],
"jcr:createdBy":"admin",
"jcr:versionHistory":"9dcd41d4-2e10-4d52-b0c0-1ea20e102e68",
"cq:lastReplicatedBy":"admin",
"cq:lastModified":"Mon Dec 09 2013 17:57:59 GMT-0500",
"cq:lastReplicated":"Mon Dec 16 2013 11:42:54 GMT-0500",
"jcr:lockOwner":"admin"
}
Search configuration is the out-of-the-box default.
EDIT: Data is returning in JSON, however, is not accessable in the API:
Result:
{
"success":true,
"results":2,
"total":2,
"offset":0,
"hits":[
{
"jcr:path":"/content/path/to/articles/article-a",
"jcr:createdBy":"admin",
"jcr:created":"Tue Dec 03 2013 16:27:01 GMT-0500",
"jcr:primaryType":"cq:Page",
"jcr:content":{
"sling:resourceType":"path/to/components/global/page/productdetail",
"_comment":"// ***SNIP*** //",
"thumbnail":{
"jcr:lastModifiedBy":"admin",
"imageRotate":"0",
"jcr:lastModified":"Wed Dec 04 2013 12:10:47 GMT-0500",
"jcr:primaryType":"nt:unstructured"
}
}
},
{
"jcr:path":"/content/path/to/articles/article-1",
"jcr:createdBy":"admin",
"jcr:created":"Tue Dec 03 2013 16:26:51 GMT-0500",
"jcr:primaryType":"cq:Page",
"jcr:content":{
"sling:resourceType":"path/to/components/global/page/productdetail",
"_comment":"// ***SNIP*** //",
"thumbnail":{
"jcr:lastModifiedBy":"admin",
"imageRotate":"0",
"fileReference":"/content/dam/path/to/IBMDemo/apparel/women/wsh005_shoes/WSH005_0533_is_main.jpg",
"jcr:lastModified":"Mon Dec 09 2013 17:57:58 GMT-0500",
"jcr:primaryType":"nt:unstructured"
}
}
}
]
}
Implementation code:
searchCriteria.put("path", path);
searchCriteria.put("type", "cq:Page");
searchCriteria.put("p.offset", offset.toString());
searchCriteria.put("p.limit", limit.toString());
searchCriteria.put("p.hits", "full");
searchCriteria.put("p.properties", "thumbnail");
searchCriteria.put("p.nodedepth", "2");
PredicateGroup predicateGroup = PredicateGroup.create(searchCriteria);
Query query = queryBuilder.createQuery(predicateGroup, session);
SearchResult result = query.getResult();
for (Hit hit : result.getHits()) {
try {
ValueMap properties = hit.getProperties();
VFSearchResult res = new VFSearchResult();
res.setUrl(hit.getPath());
res.setImageUrl((String)properties.get("thumbnail"));
res.setTags((String[])properties.get("cq:tags"));
res.setTeaserText((String)properties.get("teaserText"));
res.setTitle((String)properties.get("jcr:title"));
searchResults.add(res);
} catch (RepositoryException rex) {
logger.debug(String.format("could not retrieve node properties: %1s", rex));
}
}

After setting the path in the query, then set one or more property filters, such as in this example:
type=cq:Page
path=/content/path/to/articles
property=jcr:content/thumbnail
property.operation=exists
p.hits=selective
p.properties=jcr:content/thumbnail someSpecificThumbnailPropertyToRetrieve
p.limit=100000
You can set those on /libs/cq/search/content/querydebug.html and then also use that to get the JSON URL for the same query.
Check this out for some other examples: http://dev.day.com/docs/en/cq/5-5/dam/customizing_and_extendingcq5dam/query_builder.html

You could use CURL to retrieve node properties in the HTML/ JSON/ XML format. All you have to do is install download CURL and run your curl commands from your terminal from the same directory as the curl's .exe file.
HTML example:
C:\Users\****\Desktop>curl -u username:password http://localhost:4502/content/geometrixx-media/en/gadgets/leaps-in-ai.html
JSON example:
**C:\Users\****\Desktop>**curl -u username:password http://localhost:4502/content/geometrixx-media/en/gadgets/leaps-in-ai.html.tidy.infinity.json
Note: infinity in the above query ensures you get every property of every node under your specified path recursively

Related

unable to upload an image file to slack through hubot

I am trying to get an image of a web page using pageres package, And post the image to slack using hubot. I am able to get the image, but for some reason i am not able to post it to slack using slack upload api. Here is my code, can you tell me what could be wrong? (not a coffee lint issue)
fs = require("fs")
Pageres = require('pageres')
util = require("util")
request = require("request")
module.exports = (robot) ->
robot.respond /screenshot page (\S*)?( at )?(\S*)?/i, (msg) ->
pageres = new Pageres({delay: 30})
domain = msg.match[1].replace("http://", "")
if msg.match[3] == undefined
size = '960x1024'
else
size = msg.match[3]
dest = './screenshots'
msg.send "Acquiring screenshot of #{domain}"
pageres.src(domain, [size]).dest(dest)
pageres.run (err) ->
if err
robot.logger.error err
msg.send "Um..., you better check the log"
else
opts = {
method: 'POST',
uri: 'https://slack.com/api/files.upload',
formData: {
channels: process.env.HUBOT_SCREENSHOT_SLACK_CHANNEL,
initial_comment: "Screenshot of #{domain}",
token: process.env.HUBOT_SLACK_TOKEN,
file: fs.createReadStream("#{dest}/#{domain}.png")
}
}
request.post opts, (error, response, body) ->
if error
robot.logger.error error
else
robot.logger.debug 'screenshot posted to slack'
return
The bot is connected to slack, and receiving messages from slack, parsing them fine and getting the image back to the local destination, but not able to post it to slack, There are no errors as well in the log.
[Wed Apr 11 2018 16:16:47 GMT+0000 (UTC)] DEBUG Received message: '#hubot screenshot page http://www.google.com' in channel: ****, from: ******
[Wed Apr 11 2018 16:16:47 GMT+0000 (UTC)] DEBUG Message '#hubot screenshot page http://www.google.com' matched regex //^\s*[#]?hubot[:,]?\s*(?:screenshot page (\S*)?( at )?(\S*)?)/i/; listener.options = { id: null }
[Wed Apr 11 2018 16:16:47 GMT+0000 (UTC)] DEBUG Executing listener callback for Message '#hubot screenshot page http://www.google.com'
[Wed Apr 11 2018 16:16:47 GMT+0000 (UTC)] DEBUG Sending to *****: Acquiring screenshot of www.google.com
You can use curl command which can be called using child_process to upload a file in the channel.
curl -F file=#dramacat.gif -F channels=C024BE91L,#general -F token=xxxx-xxxxxxxxx-xxxx https://slack.com/api/files.upload
It seems the formData property in your opts variable should be slightly different like this:
formData: {
token: process.env.HUBOT_SLACK_TOKEN,
title: "Screenshot of #{domain}",
filename: "image.png",
filetype: "auto",
channels: channel_id,
file: fs.createReadStream("path_to_your_image"),
}
The channel_id is your slack channel id which you can see in the browser address bar when you access the channel.

Retrieving individual resources that have legacy UUIDs in Eve

I have a MongoDB collection with legacy UUID _id fields.
I can retrieve individual objects with pymongo by passing UUID objects:
from uuid import UUID
from pymongo import MongoClient
client = MongoClient('localhost', 27017)
db = client[DB_NAME]
collection = db[COLLECTION_NAME]
one_ok = collection.find_one(
filter={'_id': UUID('eedacde6-e241-4f37-a57d-c4e8eb6601a7')})
one_not_ok = collection.find_one(
filter={'_id': 'eedacde6-e241-4f37-a57d-c4e8eb6601a7'})
print(one_ok is None) # prints False
print(one_not_ok is None) # prints True
However I can't seem to get individual resources using Eve. I get a 404 for:
http://localhost:5000/collection1/eedacde6-e241-4f37-a57d-c4e8eb6601b7
The list returned by http://localhost:5000/collection1 mentions a link collection1/eedacde6-e241-4f37-a57d-c4e8eb6601b7 that seems to match the URL that returns a 404:
<resource href="collection1" title="collection1">
<link rel="parent" href="/" title="home"/>
<_meta>
<max_results>25</max_results>
<page>1</page>
<total>2</total>
</_meta>
<resource href="collection1/eedacde6-e241-4f37-a57d-c4e8eb6601b7" title="Collection1">
<_created>Thu, 01 Jan 1970 00:00:00 GMT</_created>
<_etag>9718572fe2d17b12358691602f6bd5f1ee345b06</_etag>
<_id>eedacde6-e241-4f37-a57d-c4e8eb6601b7</_id>
<_updated>Thu, 01 Jan 1970 00:00:00 GMT</_updated>
</resource>
<resource href="collection1/98c67ae6-ee7b-4bd3-9ec1-56b70fa2a9c7" title="Collection1">
<_created>Thu, 01 Jan 1970 00:00:00 GMT</_created>
<_etag>75c2451d19750e1007274315672bf893f9654273</_etag>
<_id>98c67ae6-ee7b-4bd3-9ec1-56b70fa2a9c7</_id>
<_updated>Thu, 01 Jan 1970 00:00:00 GMT</_updated>
</resource>
</resource>
This is my DOMAIN variable in settings.py. I set it up that way after following http://python-eve.org/tutorials/custom_idfields.html .
DOMAIN = {
'collection1': {
'item_url': 'regex("[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}")',
'schema': {
'_id': {'type': 'uuid'},
},
}
}
I suspect this doesn't work because the UUIDs are 'Legacy UUIDs', but I might be wrong.
Any ideas on how I can make URL such as http://localhost:5000/collection1/eedacde6-e241-4f37-a57d-c4e8eb6601b7 return individual resources?
Workaround: hack Eve
I am able to make it work by hacking Eve. The code below must be added for each HTTP verb (GET, POST, etc).
In eve/methods/get.py
def getitem_internal(resource, **lookup):
"""
<...>
"""
req = parse_request(resource)
resource_def = config.DOMAIN[resource]
embedded_fields = resolve_embedded_fields(resource, req)
#### hack ###
if '_id' in lookup:
if 'schema' in resource_def and '_id' in resource_def['schema']:
if resource_def['schema']['_id'].get('type') == 'uuid':
lookup['_id'] = UUID(lookup['_id'])
#### end of hack ###
soft_delete_enabled = config.DOMAIN[resource]['soft_delete']
if soft_delete_enabled:
# GET requests should always fetch soft deleted documents from the db
# They are handled and included in 404 responses below.
req.show_deleted = True
document = app.data.find_one(resource, req, **lookup)
<...>

Failed to send event to MongoDb

I am using logstash to collect data from android device using http-poller as input plugin. I want to store the collected data in a NoSQL(mongodb) using mongodb as output plugin. I have successfully set up the configuration file but when I run my set-up, I get the following error:
Failed to send event to MongoDB {:event=>#, #cancelled=false, #data={"error"=>501, "#version"=>"1", "#timestamp"=>"2016-10-03T18:02:11.337Z", "http_poller_metadata"=>{"name"=>"some_other_service", "host"=>"s18660276.domainepardefaut.fr", "request"=>{"method"=>"post", "url"=>"http://127.0.0.1/web/app.php/api/addsmartlog"}, "runtime_seconds"=>0.526, "code"=>200, "response_headers"=>{"date"=>"Mon, 03 Oct 2016 18:02:11 GMT", "server"=>"Apache/2.2.22 (Debian)", "x-powered-by"=>"PHP/5.5.30-1~dotdeb+7.1", "cache-control"=>"no-cache", "content-length"=>"13", "keep-alive"=>"timeout=5, max=100", "connection"=>"Keep-Alive", "content-type"=>"application/json"}, "response_message"=>"OK", "times_retried"=>0}}, #metadata={}, #accessors=#501, "#version"=>"1", "#timestamp"=>"2016-10-03T18:02:11.337Z", "http_poller_metadata"=>{"name"=>"some_other_service", "host"=>"s18660276.domainepardefaut.fr", "request"=>{"method"=>"post", "url"=>"http://127.0.0.1/web/app.php/api/addsmartlog"}, "runtime_seconds"=>0.526, "code"=>200, "response_headers"=>{"date"=>"Mon, 03 Oct 2016 18:02:11 GMT", "server"=>"Apache/2.2.22 (Debian)", "x-powered-by"=>"PHP/5.5.30-1~dotdeb+7.1", "cache-control"=>"no-cache", "content-length"=>"13", "keep-alive"=>"timeout=5, max=100", "connection"=>"Keep-Alive", "content-type"=>"application/json"}, "response_message"=>"OK", "times_retried"=>0}}, #lut={"http_poller_metadata"=>[{"error"=>501, "#version"=>"1", "#timestamp"=>"2016-10-03T18:02:11.337Z", "http_poller_metadata"=>{"name"=>"some_other_service", "host"=>"s18660276.domainepardefaut.fr", "request"=>{"method"=>"post", "#timestamp"=>"2016-10-03T18:02:11.337Z", "http_poller_metadata"=>{"name"=>"some_other_service", "host"=>"s18660276.domainepardefaut.fr", "request"=> "runtime_seconds"=>0.526, "code"=>200, "response_headers"=>{"date"=>"Mon, 03 Oct 2016 18:02:11 GMT", "server"=>"Apache/2.2.22 (Debian)", "x-powered-by"=>"PHP/5.5.30-1~dotdeb+7.1", "cache-control"=>"no-cache", "content-length"=>"13", "keep-alive"=>"timeout=5, max=100", "connection"=>"Keep-Alive", "content-type"=>"application/json"}, "response_message"=>"OK", "times_retried"=>0}}, "#timestamp"]}>>, :exception=>#"admin"}, #server_selection_timeout=30>>, :backtrace=>["/opt/logstash/vendor/bundle/jruby/1.9/gems/mongo-2.0.6/lib/mongo/server_selector/selectable.rb:99:in select_server'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/mongo-2.0.6/lib/mongo/cluster.rb:122:innext_primary'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/mongo-2.0.6/lib/mongo/collection.rb:190:in insert_many'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/mongo-2.0.6/lib/mongo/collection.rb:175:ininsert_one'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-output-mongodb-2.0.5/lib/logstash/outputs/mongodb.rb:56:in receive'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-2.4.0-java/lib/logstash/outputs/base.rb:109:inmulti_receive'", "org/jruby/RubyArray.java:1613:in each'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-2.4.0-java/lib/logstash/outputs/base.rb:109:inmulti_receive'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-2.4.0-java/lib/logstash/output_delegator.rb:130:in worker_multi_receive'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-2.4.0-java/lib/logstash/output_delegator.rb:114:inmulti_receive'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-2.4.0-java/lib/logstash/pipeline.rb:301:in output_batch'", "org/jruby/RubyHash.java:1342:ineach'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-2.4.0-java/lib/logstash/pipeline.rb:301:in output_batch'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-2.4.0-java/lib/logstash/pipeline.rb:232:inworker_loop'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-2.4.0-java/lib/logstash/pipeline.rb:201:in `start_workers'"], :level=>:warn}
^CSIGINT received. Shutting down the agent. {:level=>:warn}
Can anyone help out?

Sorting a Meteor Cursor

I am using Ionic 2 with Meteor/Mongo.
I am trying to sort a Cursor, but find it just keeps the original order which the items were inserted.
model
interface Chat {
_id?: string;
memberIds?: string[];
title?: string;
subTitle?: string;
picture?: string;
lastMessage?: Message;
lastMessageCreatedAt?: Date;
receiverComp?: Tracker.Computation;
lastMessageComp?: Tracker.Computation;
}
ts
private sortLocalChats(): void {
this.localChatCursor = this.localChatCollection.find({}, { sort: { lastMessageCreatedAt: -1 } });
this.localChatCursor.forEach((chat: Chat) => {
console.log(chat.title+' '+chat.lastMessageCreatedAt);
});
console.log('==> loaded sorted local chats: ' + this.localChatCollection.find().count());
output
Ashton Marais Thu Oct 06 2016 16:50:36 GMT+0800 (CST)
Ashton Marais Wed Oct 12 2016 21:20:18 GMT+0800 (CST)
ghjghj ghjghg Wed Oct 05 2016 23:37:49 GMT+0800 (CST)
Brett Simpson Thu Oct 06 2016 23:52:05 GMT+0800 (CST)
==> loaded sorted local chats: 4
I would have expected this to be sorted by lastMessageCreatedAt.
Any help appreciated.
To get sorted results you probably need to call fetch() first. So in the above example this works:
this.localChatCursor.fetch().forEach(...);

is there any way to get key "last-modified" from zend Google Doc Adapter?

I write some code like this to getting cell value in google Spreadsheet
this code exactly work
$query = new Zend_Gdata_Spreadsheets_DocumentQuery();
$query->setSpreadsheetKey($this->spreadsheetId);
$feed = $this->spreadsheetService->getWorksheetFeed($query);
var_dump($feed);
but I need value of last modified this spreadsheet
this value are protected in $feed object :
["Last-modified"]=>
string(29) "Wed, 18 Sep 2013 08:58:44 GMT"
is there any way to get key "last-modified" of Goolgle Doc?
AND How i can access it via zend V.1?