Google Experiments Server Side Variation - server-side

I'm trying to implement Google server-side experiments by following this reference:
https://developers.google.com/analytics/solutions/experiments-server-side
My goal is to let Google decide which variation I should show to user from the experiment.
I have figured out that this can be achieved by setting "servingFramework" option to API.
I'm stuck on which steps I should complete to get the variation chosen by Google?
The main question is - how can I achieve the same results as from the following example, but server-side:
var variation = cxApi.chooseVariation();
This is necessary because first of all, I need to get variation and just after that to show it to the user.

According to deividaspetraitis in a comment:
I have solved it like this:
$googleAPI = ''; // googleAPI
$serviceExperiments = $googleAPI->getService('Experiments')>setId("experiment_id");
$serviceExperiments->setCacheTtl(500);
$serviceExperiments->setCacheDir(CACHE);
$experimentData = $serviceExperiments->getData();
# $mt_random = (mt_rand(0, 10) / 100 );
$mt_random = (float) number_format((float)rand()/(float)getrandmax(), 2, '.', '');
if( ($mt_random <= $experimentData["participation"]) !== true ) { return; }

Related

Instagram ?__a=1 not working anymore

I've been using Instagram's undocumented API https://www.instagram.com/<user>/?__a=1 to get a public user feed on a website. Since a while now, this is not working anymore, probably because Facebook removed it. Is there an other way to get the data of an instagram account in a easy way?
I built a small server which does that transformation. You'll receive the instagram data as before with ?__a=1 (as JSON ) - have fun 😊
https://www.instapi.io/u/<username>
https://www.instapi.io/u/appwithus
EDIT 12/2020: Unfortunately the service is no longer available
Edit 15/03 NOT WORKING ANYMORE Seems like instagram changed again their API, now it gives a CORS error.
As of 2 february 2021, I have found a solution
Instead of using https://www.instagram.com/username/?__a=1 which it asks for a login.
Justing adding a /channel seems to make it work, like so:
https://www.instagram.com/username/channel/?__a=1
There is a JSON data in https://www.instagram.com/<user>/.
You can use regexp to find what you need.
Sample
// This regexp gets widest possible dict around "profile_pic_url"
// but inside tag <script type="text/javascript">...</script>
let r = new RegExp('<script type="text\/javascript">' +
'([^{]+?({.*profile_pic_url.*})[^}]+?)' +
'<\/script>');
let source = document.documentElement.outerHTML;
let jsonStr = source.match(r)[2];
let data = JSON.parse(jsonStr);
console.log('data', data);
let oldVariantOfData = data['entry_data']['ProfilePage'][0];
console.log('oldVariantOfData', oldVariantOfData);
The same response is attached in the html response of the profile url, I perform this temporal solution (when I can't use the API) in python:
url_recent_media = 'https://www.instagram.com/%s/' % instagram_id
response = urllib2.urlopen(url_recent_media)
insta_html = response.read()
insta_html_split = insta_html.split('"ProfilePage":[')
if len(insta_html_split) > 1:
insta_html_split_2 = insta_html_split[1].split(']},"gatekeepers"')
if len(insta_html_split_2) > 1:
json_dict = json.loads(insta_html_split_2[0])
I hope this help you.
you can try without using instagram API.
import json, urllib2
img_dicts = []
url = 'https://www.instagram.com/{}/'.format(instagram_username)
try:
r = urllib2.urlopen(url, timeout=10.0)
instagram_html = r.read()
instagram_html_data = instagram_html.split('"ProfilePage":[')
if len(instagram_html_data) > 1:
instagram_html_final_data = instagram_html_data[1].split(']},"gatekeepers"')
if len(instagram_html_final_data) > 1:
json_dict = json.loads(instagram_html_final_data[0])
media = json_dict['graphql']['user']['edge_owner_to_timeline_media']['edges']
for obj in media:
img_dicts.append({
'id': obj['node']['id'],
'caption': obj['node']['edge_media_to_caption']['edges'][0]['node']['text'],
'imgurl_standard': obj['node']['display_url'],
'imgurl_lower': obj['node']['thumbnail_resources'][4]['src'],
'imgurl_thumb': obj['node']['thumbnail_resources'][3]['src']
})
img_dicts will give you images in different quality and caption of instagram post.

Doctrine CreateQueryBuilder returns repeated result

In Symfony3 I'm running
php app/console generate:doctrine:entity --entity=AcmeBlogBundle:Post
It creates 2 files: Post (in entity folder) and PostRepository (in repository folder extending \Doctrine\ORM\EntityRepository)
Everything is fine until I try to run the following repository-custom-function in my controller
$rir = $this->getDoctrine()->getRepository("AcmeBlogBundle:Post");
$replacementInstruction = $rir->getOneBy(
array("id" => 6)
);
My custom repository function is as follow
public function getOneBy($option)
{
$alias = "p";
$fields = $this->prepareRequestSelectFields("p");
$qb = $this->createQueryBuilder('Post');
$qb->select($fields)
->from('AcmeBlogBundle:Post', $alias)
->where($alias . '.id = :id')
->setParameter('id', 6)
;
$result = $qb->getQuery()->getResult();
}
private function prepareRequestSelectFields($alias)
{
return $alias. ".id";
}
In my database there are 10 posts with id from 1 to 10, so I expect it to return 1 result, however it return correct Post (id 6) 10 times
Why is that?
p.s. if I move the query builder to a custom service wrapper e.g. PostManager it works just fine (returning 1)
This doesn't really answer my question but apparently createQueryBuilder() in EntityRepository and in EntityManager are different, thanks to https://maltronic.io/2014/12/22/doctrine-createquerybuilder-entitymanager-vs-entityrepository/
So in my EntityRepository it should be
...
$qb = $this->createQueryBuilder('p'); // this should be the alias
$qb->select($fields)
// ->from('AcmeBlogBundle:Post', $alias) // remove this
->where($alias . '.id = :id')
->setParameter('id', 6)
;
...
Personally I dislike how 2 different functions has the same name, but I guess it's fine because one is from Doctrine and one is from Symfony. They are decoupled
edit Actually I might be wrong, they are both from Doctrine ... sigh
Still tho, it doesn't answer why in my original code, it returns multiple time
What about getSingleResult() rather than getResult() ? And you should maybe use the doctrine method findOneBy()
You can use the helper methods provided by the repositories, allowing you to fetch one or multiples entities from repositories with dynamic method names, in your case you want to fetch one post by id:
//fetch one
$replacementInstruction = $this->getDoctrine()->getRepository("AcmeBlogBundle:Post")->findOneById(6);
For information, fetching all entities is done with ->findByProperty

Meteor regex find() far slower than in MongoDB console

I've been researching A LOT for past 2 weeks and can't pinpoint the exact reason of my Meteor app returning results too slow.
Currently I have only a single collection in my Mongo database with around 2,00,000 documents. And to search I am using Meteor subscriptions on the basis of a given keyword. Here is my query:
db.collection.find({$or:[
{title:{$regex:".*java.*", $options:"i"}},
{company:{$regex:".*java.*", $options:"i"}}
]})
When I run above query in mongo shell, the results are returned instantly. But when I use it in Meteor client, the results take almost 40 seconds to return from server. Here is my meteor client code:
Template.testing.onCreated(function () {
var instance = this;
// initialize the reactive variables
instance.loaded = new ReactiveVar(0);
instance.limit = new ReactiveVar(20);
instance.autorun(function () {
// get the limit
var limit = instance.limit.get();
var keyword = Router.current().params.query.k;
var searchByLocation = Router.current().params.query.l;
var startDate = Session.get("startDate");
var endDate = Session.get("endDate");
// subscribe to the posts publication
var subscription = instance.subscribe('sub_testing', limit,keyword,searchByLocation,startDate,endDate);
// if subscription is ready, set limit to newLimit
$('#searchbutton').val('Searching');
if (subscription.ready()) {
$('#searchbutton').val('Search');
instance.loaded.set(limit);
} else {
console.log("> Subscription is not ready yet. \n\n");
}
});
instance.testing = function() {
return Collection.find({}, {sort:{id:-1},limit: instance.loaded.get()});
}
And here is my meteor server code:
Meteor.publish('sub_testing', function(limit,keyword,searchByLocation,startDate,endDate) {
Meteor._sleepForMs(200);
var pat = ".*" + keyword + ".*";
var pat2 = ".*" + searchByLocation + ".*";
return Jobstesting.find({$or:[{title:{$regex: pat, $options:"i"}}, { company:{$regex:pat,$options:"i"}},{ description:{$regex:pat,$options:"i"}},{location:{$regex:pat2,$options:"i"}},{country:{$regex:pat2,$options:"i"}}],$and:[{date_posted: { $gte : endDate, $lt: startDate }},{sort:{date_posted:-1},limit: limit,skip: limit});
});
One point I'd also like to mention here that I use "Load More" pagination and by default the limit parameter gets 20 records. On each "Load More" click, I increment the limit parameter by 20 so on first click it is 20, on second click 40 and so on...
Any help where I'm going wrong would be appreciated.
But when I use it in Meteor client, the results take almost 40 seconds to return from server.
You may be misunderstanding how Meteor is accessing your data.
Queries run on the client are processed on the client.
Meteor.publish - Makes data available on the server
Meteor.subscribe - Downloads that data from the server to the client.
Collection.find - Looks through the data on the client.
If you think the Meteor side is slow, you should time it server side (print time before/after) and file a bug.
If you're implementing a pager, you might try a meteor method instead, or
a pager package.

Query Facebook Opengraph next page parameters

I am unable to implement pagination with Facebook OpenGraph. I have exhausted every option I have found.
My hope is to query for 500 listens repeatedly until there are none left. However, I am only able to receive a response from my first query. Below is my current code, but I have tried setting the parameters to different amounts rather than having the fields from the [page][next] dictate them
$q_param['limit'] = 500;
$next_exists = true;
while($next_exists){
$music = $facebook->api('/me/music.listens','GET', $q_param);
$music_data = array_merge($music_data, $music['data']);
if($music["paging"]["next"]==null || $music["paging"]["next"]=="")
$next_exists = false;
else{
$url = $music["paging"]["next"];
parse_str(parse_url($url, PHP_URL_QUERY), $array);
foreach ($array as $key => $value) {
$q_param[$key]=$value;
}
}
}
}
a - Can you please share what do you get after first call?
b - Also, possible if you can share the whole file?
I think your script is timing out. Try adding following on top of your file:
set_time_limit(0);
Can you check apache log files?
sudo tail -f /var/log/apache2/error.log

Call multiple webservices from play 2

I am a play2.0-Scala-beginner and have to call several Webservices to generate a HTML page.
After reading the The Play WS API page and a very interesting article from Sadek Drobi I am still unsure what's the best way to accomplish this.
The article shows some code snippets which I don't fully understand as a Play beginner.
Figure 2 on page 4:
val response: Either[Response,Response] =
WS.url("http://someservice.com/post/123/comments").focusOnOk
val responseOrUndesired: Either[Result,Response] = response.left.map {
case Status(4,0,4) => NotFound
case Status(4,0,3) => NotAuthorized
case _ => InternalServerError
}
val comments: Either[Result,List[Comment]] =
responseOrUndesired.right.map(r => r.json.as[List[Comment]])
// in the controller
comment.fold(identity, cs => Ok(html.showComments(cs)))
What does the last line with the fold do? Should comment be comments? Haven't I group the last statement in an Async block?
Figure 4 shows how to combine several IO calls with a single for-expression:
for {
profile <- profilePromise
events <- attachedEventsPromise
articles <- topArticlesPromise
} yield Json.obj(
"profile" -> profile,
"events" -> events,
"articles" -> articles )
}
// in the controller
def showInfo(...) = Action { rq =>
Async {
actorInfo(...).map(info => Ok(info))
}
}
How can I use this snippet? (I am a bit confused by the extra-} after the for-expression.)
Should I write something like this?
var actorInfo = for { // Model
profile <- profilePromise
events <- attachedEventsPromise
articles <- topArticlesPromise
} yield Json.obj(
"profile" -> profile,
"events" -> events,
"articles" -> articles )
def showInfo = Action { rq => // Controller
Async {
actorInfo.map(info => Ok(info))
}
}
What's the best way to combine the snippets from figure 2 and 4 (error handling + composition of IO non-blocking calls)? (f.ex. I want to produce a Error 404 status code if any of the called webservice produce an Error 404).
Maybe someone knows a complete example of calling webservices in the play framework (cannot find an example in the play Sample applications or anywhere else).
I have to say that the article is wrong in the example you show in Figure 2. The method focusOnOk does not exist in Play 2.0. I assume the author of the article used a pre-release version of Play 2 then.
Regarding comment, yes it should be comments. The fold in the statement is operating on an Either. It takes 2 functions as parameters. The first is a function to apply if it is a left value. The second is a function to apply if it is a right value. A more detailed explanation can be found here: http://daily-scala.blogspot.com/2009/11/either.html
So what the line does is. If I have a left value (which meant I got an undesired response), apply the built-in identity function which just gives you back the value. If it has a right value (which means I got an OK response), make a new result that shows the comments somehow.
Regarding Async, it's not actually asynchronous. focusOnOk is a blocking function (a remnant from the old Java days of Play 1.x). But remember, that's not valid Play 2 code.
As for Figure 4, the trailing } is actually because it's a partial alternative of what's in Figure 3. Instead of the numerous promise flatMaps. You can do a for comprehension instead. Also, I think it should be userInfo(...).map instead of actorInfo(...).map.
The Play documentation you linked to actually already shows you a full example.
def feedTitle(feedUrl: String) = Action {
Async {
WS.url(feedUrl).get().map { response =>
Ok("Feed title: " + (response.json \ "title").as[String])
}
}
}
will get whatever is at feedUrl, and you map it to do something with the response which has a status field you can check to see if it was a 404 or something else.
To that end, the Figure 3 and 4 of your linked article should give you a starting point. So you'd have something like,
def getInfo(...) : Promise[String] = {
val profilePromise = WS.url(...).get()
val attachedEventsPromise = WS.url(...).get()
val topArticlesPromise = WS.url(...).get()
for {
profile <- profilePromise
events <- attachedEventsPromise
articles <- topArticlesPromise
} yield {
// or return whatever you want
// remember to change String to something else in the return type
profile.name
}
}
def showInfo(...) = Action { rq =>
Async {
getInfo(...).map { info =>
// convert your info to a Result
Ok(info)
}
}
}