Is there any caching policy of images in GitHub?
I am facing trouble while rendering an image from an API. The image works fine when I open it in the browser.
However, Github renders some older version of that image.
How can I workaround this issue or is there any fix?
Considering this netlify/netlify-cms PR, maybe adding the ts=$(date) as parameter of a GitHub API v3 call would be enough of a "cache busting" for your need.
From the code:
const cacheBuster = new Date().getTime();
const params = [`ts=${cacheBuster}`];
if (options.params) {
for (const key in options.params) {
params.push(`${ key }=${ encodeURIComponent(options.params[key]) }`);
}
}
if (params.length) {
path += `?${ params.join("&") }`;
}
return this.api_root + path;
This adds a &ts=xxx timestamp parameter to the api.github.com call.
I'm building an app with titanium and I would like to save in the phone, the user's profile picture. In my login function, after the API response, I tried to do :
Ti.App.Properties.setString("user_picture_name", res.profil_picture);
var image_to_save = Ti.UI.createImageView({image:img_url}).toImage();
var picture = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, res.profil_picture); //As name, the same as the one in DB
picture.write(image_to_save);
And in the view in which I want to display the image :
var f = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory,Ti.App.Properties.getString("user_picture_name") );
var image = Ti.UI.createImageView({
image:f.read(),
width:200,
height:100,
top:20
});
main_container.add(image);
But the image doesn't appears. Could someone help me ?
Thanks a lot :)
There are 2 issues with your code:
1 - You cannot use toImage() method unless your image view is rendered on UI stack or simply on display. Rather you should use toBlob() method.
2 - Point no. 1 will also not work the way you are using because you cannot directly use toBlob() method until or unless the image from the url is completely loaded, means until it's shown on image view. To check when the image is loaded, use Ti.UI.ImageView onload event
But, there's another better approach to do such type of tasks.
Since you have the image url from your Login API response, you can use this url to fetch image from http client call like this:
function fetchImage() {
var xhr = Ti.Network.createHTTPClient({
onerror : function() {
alert('Error fetching profile image');
},
onload : function() {
// this.responseData holds the binary data fetched from url
var image_to_save = this.responseData;
//As name, the same as the one in DB
var picture = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, res.profil_picture);
picture.write(image_to_save);
Ti.App.Properties.setString("user_picture_name", res.profil_picture);
image_to_save = null;
}
});
xhr.open("GET", img_url);
xhr.send();
}
You don't need to manually cache remote images, because
Remote images are cached automatically on the iOS platform and, since
Release 3.1.0, on the Android platform.
[see docs here & credit to Fokke Zandbergen]
Just use the remote image url in your UI, at first access Titanium will download and cache it for you; next accesses to the same image url will actually be on the automatically cached version on local device (no code is best code)
Hth.
I'm working on a web application where I need to access elements of an iFrame using JavaScript. To do that, the iFrame has to send an "Allow-Control-Allow-Origin: *" header to the browser.
Unfortunately this doesn't happen, that's why I'm using an extension to modify the response headers, but for some reason, setResponseHeader doesn't work.
It gets even more confusing since I'm using setResponseHeader to strip X-Frame-Options, but when I'm setting a custom header, it just won't work.
I'm using Firefox's "Inspect Element"'s Network tab to observe the requests, and while it shows the request header being set correctly, it doesn't show the response header.
That's how I'm setting the request and response headers.
var chrome = require("chrome");
chrome.Cc["#mozilla.org/observer-service;1"].getService( chrome.Ci.nsIObserverService ).addObserver({
observe : function(subject, topic, data) {
var channel = subject.QueryInterface( chrome.Ci.nsIHttpChannel );
channel.setRequestHeader("x-mysite-extended", "somedata", false);
}
},"http-on-modify-request",false);
chrome.Cc["#mozilla.org/observer-service;1"].getService( chrome.Ci.nsIObserverService ).addObserver({
observe : function(subject, topic, data) {
var channel = subject.QueryInterface( chrome.Ci.nsIHttpChannel );
channel.setResponseHeader("x-mysite-extended", "somedata", false);
}
},"http-on-examine-response",false);
Again, the request header works according to the Network tab. I tried http-on-modify-request to set the response header but that didn't work as well.
That's how I'm stripping of the X-Frame-Options header, which works.
let myListener =
{
observe : function (aSubject, aTopic, aData)
{
console.log(aTopic);
if (aTopic == "http-on-examine-response")
{
let channel = aSubject.QueryInterface(Ci.nsIHttpChannel);
try
{ // getResponseHeader will throw if the header isn't set
let hasXFO = channel.getResponseHeader('X-Frame-Options');
if (hasXFO)
{
// Header found, disable it
channel.setResponseHeader('X-Frame-Options', '', false);
}
}
catch (e) {}
}
}
}
var observerService = Cc["#mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
observerService.addObserver(myListener, "http-on-examine-response", false);
I've been trying to solve this for two hours now so any help is appreciated. Thanks.
You're adding obserer for http-on-examine-response, with this you can only getResponseHeader
change it to http-on-modify-request. then you can setRequestHeader, you cant getResponseHeader in on modify request though.
This is scrap code but it worked for me:
observe : function(aSubject, aTopic, aData) {
// Make sure it is our connection first.
if (aSubject == channel) {
//this is our channel
//alert('is my mine');
cdxFire.myChannel = aSubject.QueryInterface(Components.interfaces.nsIHttpChannel);
if (cdxFire.myChannel.requestMethod == 'GET') {
//alert('its a get so need to removeObserver now');
//cdxFire.observerService.removeObserver(modHeaderListener, "http-on-modify-request");
}
if (aTopic == 'http-on-modify-request' && cdxFire.myChannel.requestMethod == 'POST') {
//can set headers here including cookie
try {
var xContentLength = httpChannel.getRequestHeader('Content-Length');
var xContentType = httpChannel.getRequestHeader('Content-Type');
//alert('content length is there so change it up');
cdxFire.myChannel.setRequestHeader('Content-Type','',false);
cdxFire.myChannel.setRequestHeader('Content-Type',xContentType,false);
cdxFire.myChannel.setRequestHeader('Content-Length','',false);
cdxFire.myChannel.setRequestHeader('Content-Length',xContentLength,false);
I have some problem on this. Can I get public tagged photo from Instagram api without getting any code or access token?
Please share any link for reading because I cannot found any. I feel it is less knowledge about Instagram api on web.
Thanks!
You can pull public media by tag without authentication.
Take a look at the API documentation for the get /tags/tag-name/media/recent endpoint. Here's the URL: http://instagram.com/developer/endpoints/tags/#get_tags_media_recent
The documentation can be confusing, it shows using an access_token for this endpoint in the example, but it is not required. You will need to register an application and get a client ID.
I use MeteorJS and call a method server side that returns essentially the 'view source' of the instagram page. So if you can run a server side scrape on the tag url you will be able to handle the response with what i have below and it will push all the images into an array.
//server side method
Meteor.methods({
'scrapeInst':function(tag){
return Scrape.url('https://www.instagram.com/explore/tags/'+tag+'/')
}})
//client side logic
Meteor.call('scrapeInst',Session.get('params').tag,function(err,resp){
var theInstResp = resp;
cleanOne = resp.replace(/>|window._sharedData = |;</|;|#47;|<|/g,'').split('script')
var splitter = cleanOne[22].split(',');
var theArr = [];
_.each(splitter,function(e){
var theFinal = {};
var theS = e.split(":");
if(theS[0].replace(/"| |/g,'') === "display_src"){
theFinal[theS[0].replace(/"| |/g,'')] = theS[2].replace(/%22/g,'');
theArr.push(theFinal)
}
});
Session.set('photos',theArr);
setTimeout(function(){
Session.set('loading',false)
},1000)
})
Is there an easy way to grab a users LinkedIn profile photo?
Ideally similar to how you would with Facebook - http://graph.facebook.com/userid/picture
You can retrieve the original photo size with this call:
http://api.linkedin.com/v1/people/~/picture-urls::(original)
Note that this could be any size, so you'll need to do scaling on your side, but the image is the original one uploaded by the user.
Not as easy... You need to go through OAuth, then on behalf of the member, you ask for:
http://api.linkedin.com/v1/people/{user-id}/picture-url
If you use the 2.0 version of the API (all developers need to migrate by March 1, 2019), you should use projections to expand the profilePicture.displayImage. If you do this, you will have a full JSON element displayImage~ (the '~' is not a typo) inside profilePicture with all the info you may need.
https://api.linkedin.com/v2/me?projection=(id,profilePicture(displayImage~:playableStreams))
You can see more at the Profile Picture API doc to look at the JSON response or the Profile API doc.
Once the Linkedin user authentication using OAuth 2.x is done, make a request to the people URL.
https://api.linkedin.com/v1/people/~:(id,email-address,first-name,last-name,formatted-name,picture-url)?format=json
Where ~ stands for current authenticated user. The response will be something like this ...
{
"id": "KPxRFxLxuX",
"emailAddress": "johndoe#example.com",
"firstName": "John",
"lastName": "Doe",
"formattedName": "John Doe",
"pictureUrl": "https://media.licdn.com/mpr/mprx/0_0QblxThAqcTCt8rrncxxO5JAr...cjSsn6gRQ2b"
}
Hope this helps!
I'm using OWIN in my solution so after the user allows your application to use LinkedIn credentials a simple and plain GET request to URL https://api.linkedin.com/v1/people/~:(picture-URL)?format=json, as explained before with a Bearer authorization in request headers, solved my problems.
My Startup.Auth.cs file
var linkedInOptions = new LinkedInAuthenticationOptions()
{
ClientId = [ClientID],
ClientSecret = [ClientSecret],
Provider = new LinkedInAuthenticationProvider()
{
OnAuthenticated = (context) =>
{
// This is the access token received by your application after user allows use LinkedIn credentials
context.Identity.AddClaim(new Claim(
"urn:linkedin:accesstoken", context.AccessToken));
context.Identity.AddClaim(new Claim(
"urn:linkedin:name", context.Name));
context.Identity.AddClaim(new Claim(
"urn:linkedin:username", context.UserName));
context.Identity.AddClaim(new Claim(
"urn:linkedin:email", context.Email));
context.Identity.AddClaim(new Claim(
"urn:linkedin:id", context.Id));
return Task.FromResult(0);
}
}
};
app.UseLinkedInAuthentication(linkedInOptions);
My method to get the user's profile picture in LinkedIn:
public string GetUserPhotoUrl(string accessToken)
{
string result = string.Empty;
var apiRequestUri = new Uri("https://api.linkedin.com/v1/people/~:(picture-url)?format=json");
using (var webClient = new WebClient())
{
webClient.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + accessToken);
var json = webClient.DownloadString(apiRequestUri);
dynamic x = JsonConvert.DeserializeObject(json);
string userPicture = x.pictureUrl;
result = userPicture;
}
return result;
}
And finally a snippet of my action that consumes the method above:
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
...
var externalIdentity = HttpContext.GetOwinContext().Authentication.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
string accessToken =
externalIdentity.Result.Claims.FirstOrDefault(c => c.Type == "urn:linkedin:accesstoken").Value;
model.PhotoUrl = GetUserPhotoUrl(accessToken);
...
}
I hope it could help.
Best regards
This works well for me!
Explained -
This is for a thumbnail with all other data-
https://api.linkedin.com/v1/people/~:(id,location,picture-urls::(original),specialties,public-profile-url,email-address,formatted-name)?format=json
This is for original image with all other data -
https://api.linkedin.com/v1/people/~:(id,location,picture-url,specialties,public-profile-url,email-address,formatted-name)?format=json
Just use picture-urls::(original)instead of picture-url !
This is currently being used in Gradbee
When you login to linkedin, you will get accesstoken. Use that access token and you can retrieve users data
LinkedInApiClient client = factory.createLinkedInApiClient(accessToken);
com.google.code.linkedinapi.schema.Person person = client.getProfileForCurrentUser(EnumSet.of(
ProfileField.ID, ProfileField.FIRST_NAME, ProfileField.LAST_NAME, ProfileField.HEADLINE,
ProfileField.INDUSTRY, ProfileField.PICTURE_URL, ProfileField.DATE_OF_BIRTH,
ProfileField.LOCATION_NAME, ProfileField.MAIN_ADDRESS, ProfileField.LOCATION_COUNTRY));
String imgageUrl=person.getPictureUrl();
If your goal is simply to display the photo on your site then the LinkedIn Member Profile Plugin may work out for you. It will display the photo, some additional info, along with LinkedIn branding.
Since the LinkedIn API is designed to be used only on behalf of the current logged in user it does not offer similar functionality as the facebook graph api.
This is my solution and it works very very well:
def callback(self):
self.validate_oauth2callback()
oauth_session = self.service.get_auth_session(
data={'code': request.args['code'],
'grant_type': 'authorization_code',
'redirect_uri': self.get_callback_url()},
decoder=jsondecoder
)
me = oauth_session.get('people/~:(id,first-name,last-name,public-profile-url,email-address,picture-url,picture-urls::(original))?format=json&oauth2_access_token='+str(oauth_session.access_token), data={'x-li-format': 'json'}, bearer_auth=False).json()
social_id = me['id']
name = me['firstName']
surname = me['lastName']
email = me['emailAddress']
url = me['publicProfileUrl']
image_small = me.get('pictureUrl', None)
image_large = me.get('pictureUrls', {}).get('values', [])[0]
return social_id, name, surname, email, url, image_small, image_large, me
This may not be quite what you're asking for, but it's useful for individual investigations.
Call up the page in Firefox, left-click the menu over the background image.
Select Inspect Element(Q).
search for -target-image"
That will be the end of of id attribute in an img element.
The src attribute of that img element, will be the URL of the background image.
For me this works
image= auth.extra.raw_info.pictureUrls.values.last.first
with omniauth-linkedin gem