YouTube Data API V3 - value status.privacyStatus on private video - youtube-data-api

I'm doing the first tests with the new YouTube Data API V3 to migrate as soon as my site from old "API V2" to the new "V3 API."
I have the following problem: for a full request on a video id set as "private" as:
https://www.googleapis.com/youtube/v3/videos?id=7J7tGINYazA&key=**************************&part=snippet,contentDetails,statistics,status
the result is the following:
{
  "kind", "youtube # videoListResponse"
  "etag": "\" yHwg34KvgIlW9-uBcSEkgasDbzI / T_9s-xed4wEGn3XBIbu1JsPGi2U \ "",
  "PageInfo": {
   "totalResults": 0,
   "resultsPerPage": 0
  },
  "items": []
}
as in the case of a video that does not exist ...
but according to what reported in the literature:
https://developers.google.com/youtube/v3/docs/videos#status.privacyStatus
should not be returned an sippet containing the status of the private video like this:
{
  "kind", "youtube # videoListResponse"
  "etag": "\" yHwg34KvgIlW9-uBcSEkgasDbzI / ULL6GjWjIQ4a7ruFwiAk1ExdLiw \ "",
  "PageInfo": {
   "totalResults": 1,
   "resultsPerPage": 1
  },
  "items": [
   {
    "kind", "youtube video #"
    "etag": "\" yHwg34KvgIlW9-uBcSEkgasDbzI / CWIAg26CY5tX532HpkYrib52e0c \ "",
    "id": "nemioqnQa0Y"
    "status": {
     "uploadStatus": "processed"
     "privacyStatus": "private"
     "license": "youtube"
     "embeddable": false,
     "publicStatsViewable": false
    }
   }
  ]
}
The parameter privacyStatus should not contain 3 possible values (private, public, unlisted), as indicated in the documentation?
How in the world does not return the value "private"? ... Is this a bug?
Can you help? thanks

This is happening because the video is private. Using the api key, anyone can request any video if they know the id. However, since your video is set to private, you would need to use OAuth to authenticate.
Another way to think of it is like this - If I somehow gained access to your private video ID, perhaps I just got lucky and picked a random made-up id and got yours, I still should not be able to view it just because I know the id, and have a key - I would need to authenticate first to prove to YouTube that I am the owner of that private video.

Related

Elastic Search - Reactive document APIs

My requirement is to create a spring boot application controller/service that calls elastic search reactive apis with out using traditional model and repositories. i need to pass dynamic json object to create documents in elastic search using spring controller and return dynamic json as a result for queries.
Could you please help me with below questions
Does elastic search has reactive document apis for CRUDQ operations.if exists can we tie those to springboot application for CRUDQ operations without defining a model
I did check few blogs where we can use ReactiveElasticsearchClient (Elasticsearch APIs centric) but takes a model as input to the api. can we create an api without providing model and pass dynamic json for create and return dynamic object as query results.
Thank you in advance!!!
With the repository approach it may not be possible without the models. Having said that , the other way is to use the HTTP API using webflux to approach this problem.
As an example , I have set up a sample index with some data including an employee that matches this name
curl -XPOST "http://localhost:9200/_search" -H 'Content-Type: application/json' -d'{"query": {"match": {"name":"JohnSmith77067"}}}' |jq
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 3.205453,
"hits": [
{
"_index": "sample",
"_type": "employee",
"_id": "KbxD6IEBCsN8USu280mF",
"_score": 3.205453,
"_source": {
"id": null,
"organization": {
"id": 31,
"name": "TestO31",
"address": "Test Street No. 31"
},
"department": {
"id": 3631,
"name": "TestD3631"
},
"name": "JohnSmith77067",
"age": 66,
"position": "Developer"
}
}
]
}
}
will try and emulate this through a free query run through reactive web client
#RestController
#RequestMapping("/employees")
public class EmployeeController {
private static final Logger LOGGER = LoggerFactory.getLogger(EmployeeController.class);
private final WebClient client = WebClient.create();
#PostMapping("/customselect")
public Mono<String> generateMulti() throws URISyntaxException {
return client.post().uri(new URI("http://localhost:9200/_search")).
accept(MediaType.APPLICATION_JSON).
header("Content-Type", "application/json").
body(Mono.just("{\"query\": {\"match\": {\"name\":\"JohnSmith77067\"}}}"), String.class)
.retrieve()
.bodyToMono(String.class);
}
}
starting the app up and then hitting the endpoint will return similar results You could pass a custom query in the body , but you get the idea of this.
[![Postman results][1]][1]
Having a repository based approach takes away all the boilerplate and provides a lot of goodies & error handling through config driven approaches. Having said that if that does not suit , for ES the way would be to use the raw HTTP API (there are many things you could attach to the web clients such as Auth , timeout etc that i have done) and then take it from there. Hope this helps a bit
[1]: https://i.stack.imgur.com/FIAXR.png

Error trying invoke business network. missing required field

I want to send a POST request from Node-RED to the Composer REST server.
Error trying invoke business network. Error: No valid responses from any peers.Response from attempted peer comms was an error: Error: 2 UNKNOWN: error executing chaincode: transaction returned with failure: ValidationException: Instance org.acme.shipping.perishable.AccelReading#c8c829bfd738d7ec63180c5225ae85bd77fad29b4ad9d8ad4bc40a14362f1060 missing required field accel_x
Playground/Test
{
  "$class": "org.acme.shipping.perishable.AccelReading",
  "accel_x": 0,
  "accel_y": 0,
  "accel_z": 0,
  "latitude": "",
  "longitude": "",
  "readingTime": "",
  "shipment": "resource:org.acme.shipping.perishable.Shipment#4879"
}
Node-RED URL
http://...:31090/api/AccelReading?data=
{"$class":"org.acme.shipping.perishable.AccelReading",
"accel_x":23264,
"accel_y":-20960,
"accel_z":-2448,
"readingTime":"2018-02-14T15:16:44.284Z",
"latitude":"51",
"longitude":"11",
"shipment":"resource:org.acme.shipping.perishable.Shipment#320022000251363131363432"
}
Payload
Postman POST request with all parameters defined as key/value pairs in the body
Response
{
"error": {
"statusCode": 422,
"name": "ValidationError",
"message": "The `AccelReading` instance is not valid. Details: `shipment` can't be blank (value: undefined).",
"details": {
"context": "AccelReading",
"codes": {
"shipment": [
"presence"
]
},
"messages": {
"shipment": [
"can't be blank"
]
}
},
"stack": "ValidationError: The `AccelReading` instance is not valid. Details: `shipment` can't be blank (value: undefined).\n at /home/composer/.npm-global/lib/node_modules/#ibmblockchain/composer-rest-server/node_modules/loopback-datasource-juggler/lib/dao.js:398:12\n at AccelReading.<anonymous> (/home/composer/.npm-global/lib/node_modules/#ibmblockchain/composer-rest-server/node_modules/loopback-datasource-juggler/lib/validations.js:578:11)\n at AccelReading.next (/home/composer/.npm-global/lib/node_modules/#ibmblockchain/composer-rest-server/node_modules/loopback-datasource-juggler/lib/hooks.js:93:12)\n at AccelReading.<anonymous> (/home/composer/.npm-global/lib/node_modules/#ibmblockchain/composer-rest-server/node_modules/loopback-datasource-juggler/lib/validations.js:575:23)\n at AccelReading.trigger (/home/composer/.npm-global/lib/node_modules/#ibmblockchain/composer-rest-server/node_modules/loopback-datasource-juggler/lib/hooks.js:83:12)\n at AccelReading.Validatable.isValid (/home/composer/.npm-global/lib/node_modules/#ibmblockchain/composer-rest-server/node_modules/loopback-datasource-juggler/lib/validations.js:541:8)\n at /home/composer/.npm-global/lib/node_modules/#ibmblockchain/composer-rest-server/node_modules/loopback-datasource-juggler/lib/dao.js:394:9\n at doNotify (/home/composer/.npm-global/lib/node_modules/#ibmblockchain/composer-rest-server/node_modules/loopback-datasource-juggler/lib/observer.js:155:49)\n at doNotify (/home/composer/.npm-global/lib/node_modules/#ibmblockchain/composer-rest-server/node_modules/loopback-datasource-juggler/lib/observer.js:155:49)\n at doNotify (/home/composer/.npm-global/lib/node_modules/#ibmblockchain/composer-rest-server/node_modules/loopback-datasource-juggler/lib/observer.js:155:49)\n at doNotify (/home/composer/.npm-global/lib/node_modules/#ibmblockchain/composer-rest-server/node_modules/loopback-datasource-juggler/lib/observer.js:155:49)\n at Function.ObserverMixin._notifyBaseObservers (/home/composer/.npm-global/lib/node_modules/#ibmblockchain/composer-rest-server/node_modules/loopback-datasource-juggler/lib/observer.js:178:5)\n at Function.ObserverMixin.notifyObserversOf (/home/composer/.npm-global/lib/node_modules/#ibmblockchain/composer-rest-server/node_modules/loopback-datasource-juggler/lib/observer.js:153:8)\n at Function.ObserverMixin._notifyBaseObservers (/home/composer/.npm-global/lib/node_modules/#ibmblockchain/composer-rest-server/node_modules/loopback-datasource-juggler/lib/observer.js:176:15)\n at Function.ObserverMixin.notifyObserversOf (/home/composer/.npm-global/lib/node_modules/#ibmblockchain/composer-rest-server/node_modules/loopback-datasource-juggler/lib/observer.js:153:8)\n at Function.ObserverMixin._notifyBaseObservers (/home/composer/.npm-global/lib/node_modules/#ibmblockchain/composer-rest-server/node_modules/loopback-datasource-juggler/lib/observer.js:176:15)"
}
}
Postman/JSON
The issue was a refresh of Composer REST server was required, to reflect the desired fields appearing in Swagger. This means to delete the REST server container and re-create using the internal 192.x address - the steps in Kubernetes are:
bx cs cluster-config blockchain
export KUBECONFIG=/Users/<name>/.bluemix/plugins/container-service/clusters/blockchain/kube-config-mil01-blockchain.yml
./delete/delete_composer-rest-server.sh
./create/create_composer-rest-server.sh --business-network-card admin#perishable-network
Attaching a screenshot of what the POST should look like (after refresh) for the IoT business network referred to

How can I get the logo for an "Item" from the Plaid api?

I looked over the API documentation and I didn't see anything about how to get logos, but plaid clearly has them as they appear in the link app. Is there any way that I can also get access to those logo as part of the API or through another mechanism using an "Item" id?
While not documented at the time of this writing, it apparently can be done by adding an options parameter to a institution request with the value of {"include_display_data": true}. With the node API using the getInstitutionById method and Vangaurd it looks like this.
client.getInstitutionById('ins_108768', {include_display_data: true} (err, result) => {
// Handle err
const logo = result.institution.logo;
});
The value of logo will either be null or a base64 encoded string containing the binary data of the logo.
The current version of a plaid ruby gem(6.1.0) doesn't retrieve a logo but you can extend a plaid library and use include_display_data parameter to get a logo.
module Plaid
class Institutions < BaseProduct
def get_by_id_with_logo(institution_id)
post_with_public_key 'institutions/get_by_id',
SingleInstitutionResponse,
institution_id: institution_id,
options: { include_display_data: true }
end
end
end
Usage:
ins = client.institutions.get_by_id_with_logo(YOUR_INSTITUTION_ID)
puts ins.institution[:logo]
To get a list of all institutions from Plaid API one needs to hit /institutions/get with a POST request. To get logos and other institution attributes such as home page URL and brand color one needs to add options attribute in the body of the request with a key=>value pair of "include_optional_metadata" => true. The count parameter indicates the number of institutions you want returned (perPage) while offset is the number of institutions to skip.
curl -X POST \
https://sandbox.plaid.com/sandbox/institutions/get \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"client_id": "clientIdFromPlaidDashboard",
"secret": "secretFromPlaidDashboard",
"count": 500,
"offset": 0,
"options" => [
"include_optional_metadata" => true
]
}'
Expected response from Plaid doc:
http code 200
{
"institutions": [
{
"country_codes": ["US"],
"credentials": [{
"label": "User ID",
"name": "username",
"type": "text"
}, {
"label": "Password",
"name": "password",
"type": "password"
}],
"has_mfa": true,
"institution_id": "ins_109508",
"mfa": [
"code",
"list",
"questions",
"selections"
],
"name": "First Platypus Bank",
// the following are included when
// options.include_optional_metadata is true
"primary_color": "#1f1f1f",
"url": "https://plaid.com",
"logo": null,
]
}
],
"request_id": "m8MDnv9okwxFNBV",
"total": 1
}

Splitting Logs in Different ElasticSearch Document using Logstash

Hi StackOverflow community
I am working on implementing ELK for one of my project. I have a continuous stream of logs getting generated in the format. By continuous stream I mean that logs are getting generated in the following format(Date in starting of each log)
03 Apr 2017 05:54:30,416 [INFO] Log text
I want to parse these logs and convert to a structured document using Logstash and then put in ElasticSearch. Logs are going to ElasticSearch but they are in a block(i.e. for one request, all logs generated are part of one elasticsearch document) and every log is not creating a new document.
My logstash's input configuration is like following:
input {
file {
path => "/Users/abc/logfile.txt"
start_position => "beginning"
codec => multiline {
             pattern => "^([0-9]{2} [A-Za-z]{3} [0-9]{4} [0-9:]{8},[0-9]+)"
             negate => true
             what => previous
         }
}
}
Is there some issue with this configuration? The regex pattern added in multiline codec is tested using regex tester and it correctly identifies Date in the starting of log.

How to check whether Google User's image is default or uploaded?

How do I check whether user's profile picture is default or uploaded in Google?
Note: When you get user details from APIs.
All of default profile pictures have the following URL:
https://lh3.googleusercontent.com/-XdUIqdMkCWA/AAAAAAAAAAI/AAAAAAAAAAA/4252rscbv5M/photo.jpg
You can just compare string equality of profile picture with the given one.
people.get includes a isDefault value in the image object. E.g. if you try it for +Google you will get;
"image": {
"url": "https://lh4.googleusercontent.com/-v0soe-ievYE/AAAAAAAAAAI/AAAAAAACyas/yR1_yhwBcBA/photo.jpg?sz=50",
"isDefault": false
}
people.get no longer has isDefault as a property.
https://developers.google.com/+/web/api/rest/latest/people#resource
Updating this answer for 2020: it's now possible to get the user's profile picture by sending a request to the people.get API with photos as the personFields to request.
You'll get back an array of images, and whenever default: true is present, it means it's a default (not user-set) image:
Example (if you're using this with OAuth):
GET https://people.googleapis.com/v1/people/me
Sample response (with profile picture)
{
"resourceName": "people/117055959617985617271",
"etag": "%EgQBAzcuGgQBAgUHIgxHamp6MG9wZ3hOcz0=",
"photos": [
{
"metadata": {
"primary": true,
"source": {
"type": "PROFILE",
"id": "117055959617985617271"
}
},
"url": "https://lh3.googleusercontent.com/a-/AOh14Gg_-udXd3O6K1URTBTEK2rLa2DOh6G2dgmOHcOBOtE=s100"
},
{
"metadata": {
"source": {
"type": "CONTACT",
"id": "2"
}
},
"url": "https://lh3.googleusercontent.com/a/default-user=s100",
"default": true
}
]
}
Sample response (default only)
{
"resourceName": "people/113009277022343767972",
"etag": "%EgQBAzcuGgQBAgUHIgxxdHVTY3IxZVJIUT0=",
"photos": [
{
"metadata": {
"primary": true,
"source": {
"type": "PROFILE",
"id": "113009277022343767972"
}
},
"url": "https://lh6.googleusercontent.com/-6NS3awoYRXw/AAAAAAAAAAI/AAAAAAAAAAA/AMZuucnTo-mElIpcAEazDV9DAs1VyYDEIw/s100/photo.jpg",
"default": true
}
]
}
in ruby with devise and omniauth-google-oauth2
in your devise.rb
config.omniauth :google_oauth2 (Other options....), skip_image_info: false
then in your user.rb / other place:
def self.parse_auth_image(auth)
if auth.provider == "google_oauth2"
return nil if auth.dig("extra", "raw_info", "image", "isDefault")
end
auth.info.image
end
The best way to do this in FULL DETAIL:
require 'open-uri'
Default image:
default = "https://lh3.googleusercontent.com/-
XdUIqdMkCWA/AAAAAAAAAAI/AAAAAAAAAAA/4252rscbv5M/photo.jpg"
Image to check:
image_to_check = "https://lh3.googleusercontent.com/-
uh4wK1JDtCI/AAAAAAAAAAI/AAAAAAAAAAA/huieBSbV4zg/s64-
c/100695019739939096169.jpg"
Comparison check
blob_for_default_image = open(default).read
blob_for_image_to_check = open(image_to_check).read
Then you compare the 2 image blobs:
blob_for_default_image == blob_for_image_to_check
If you are using PHP, It's fairly simple, just use this code
$profile_img_end = explode("/", $userData['picture']); // Exploding the URL and Dividing it into several terms
if (end($profile_img_end) === "photo.jpg") { // Now Simply Check if last part of array is equal to "photo.jpg" which is common in all default images
$profile_img = null; // If it's default then set it equal to null
} else {
$profile_img = $userData['picture']; // Else get the Link of the Image
}
Alternative in JavaScript
var url = ""; // Image URL
var img_split = url.split("/"); // Split it Again from / (forward slash)
if (img_split[img_split.length - 1] === 'photo.jpg') { // Check if last array is equal to photo.jpg (By Default Image)
var image = null;
} else {
var image = url;
}
HOPE IT HELPS!

Resources