How to get proper Facebook likes count for URL - facebook-graph-api

I need to get proper count of likes per URL, identical with the count shown in Like button bubble, but all ways I tried returns wrong count, sample - in moment of writing some CNN article shows 117 likes with this code:
<div class="fb-like" data-send="false" data-layout="box_count"
data-width="90" data-show-faces="false" data-action="recommend"
href="http://www.cnn.com/2013/06/14/world/europe/london-underground-lego/index.html">
</div>
Anyway when querying for this via FQL it returns totally different result (only 34 likes):
https://graph.facebook.com/fql?q=SELECT like_count FROM link_stat WHERE url='http://www.cnn.com/2013/06/14/world/europe/london-underground-lego/index.html'
(Of course CNN sample is just a sample - I can not publish my real case now, however results are similar - in both cases counts doesn't match :/)
Question: is there some other absolutely sure way for fetching URL's likes via any Facebook API?

The number shown inside the CNN article, which at this very moment is 131, represents the total amount of times that link was shared, liked, or commented on.
So, according to the reference, use the following FQL to get that number:
https://graph.facebook.com/fql?q=SELECT total_count FROM link_stat WHERE url='http://www.cnn.com/2013/06/14/world/europe/london-underground-lego/index.html'

Related

I dont know how to pass two queryset parameters into one URL

I really struggled to explain my problem and the only way I found it would be possible is - through screenshots as I have a lot of code and I am not sure what is really needed here. So if you want any code, tell me I will add.
The numbers on the pictures indicate the order.
Choosing the category
Selecting the category it redirects me to - /products_list?category=(that category_id)
Filtering through brand in that category
Now please pay attention to the URL and what happens after I have chosen the brand I want to filter with.
Back on the first page
Problem is here:
Now I am back on the first page, where are all the products but I wanted it to stay on that URL where are that kind of category products.
What I wanted to happen? Instead of it taking me to the page where are ALL the products and then doing the filtering, I want it to stay on that category page and return the filtered products there.
The brand dropdown menu also should only show that category products that I am in, not all.
You need to pass the other parameters as well. So that means that for two parameters category_id and brand, you create a URL that looks like:
{% url 'product-list' %}?category={{ category_id|urlencode }}&brand={{ brand|urlencode }}
If you thus already filtered the category down, you pass the category_id to the template, and render the URLs with the ?category={{ category_id|urlencode }} part.

Filtering a queryset across a foreign key, using a parameter e.g. as argument from the view

I'm trying to build a flexible queryset that gives a result size based on parameters I use, but currently I'm only accessing that data from across a foreign key. Here's the setup.
My first table is a set of "blog posts" - the model is pretty self explanatory:
class BlogPost(models.Model):
title = models.CharField(max_length=100)
dateStamp = models.DateTimeField(auto_now_add=True)
post = models.TextField()
The second is a table that holds all the images for all the posts in a one-to-many relationship:
class BlogImageSeqFilter(models.Manager):
def get_querySet(self):
## slice the first three images with sequence between 1 and 3
return self.filter(sequence__gte=1, sequence__lte=3)[:3]
class BlogImage(models.Model):
blog = models.ForeignKey(BlogPost, null=True, on_delete=models.SET_NULL)
img = models.ImageField(upload_to=imgFolder, blank=True)
sequence = models.IntegerField(null=False, blank=False, default=0)
objects = BlogImageSeqFilter() ## Custom Manager class BlogImageSeqFilter
(The manager method comes in a little later in my question - I don't even know if using it has been the right approach so far...)
In my view, the set of blog posts is included contextually in the rendering of the html tmeplate:
def blogPage(request, proj):
## Limit to the newest 5 posts
blogs = project.blogpost_set.all().order_by("-dateStamp")[:5]
return render(request, 'blog/blogPage.html', {"blogs":blogs})
So in my template, I am displaying each blog post in a separate container, and including the set of images relevant to that blog using blogimage_set. A simplification of what I've got so far would be:
{% for post in blogs %}
<div>
{{post.title}}
{{post.post}}
{% for image in post.blogimage_set.get_querySet %}
<img src="yada yada {{image.img}} yada yada></img>
{% endfor %}
</div>
{% endfor %}
Now, what I am stuck on. I want to change the model and the view, so that I can pass an argument somehow to limit the number of items in each post (as I understand it you can't really pass arguments from the template backwards, unless you start faffing with custom template tags which I don't want to do in this case because I'm sure there is a better way of doing it, and I want to learn that way.)
I want something flexible enough that I could re-use the blog images somewhere else, using a different parameter to represent the number of images returned. But it's not as simple as "Give me the first x images in the table".
Say I upload 10 images, I will assign them all sequence #s from 1-10 (hence the 'sequence' field in the model). But that sequence might not be in the same order that I uploaded. So overall I want to be able to choose in a given view which x images from the set of 10 will appear on that blog post. "Give me images between seq #1 and #3" or "Give me 5 images starting from seq #4" or something.
My first incremental attempt towards achieving this functionality was to create the BlogImageSeqFilter Manager and its method which gives a limited queryset of three items having sequence between 1 and 3.
Changing the model (or rather the Manager/its method) to accept an argument seems like the simple bit. But what I can't figure out is how to modify the view and the template to use parameters, in such a way that I can include "blogImages" in the render's context while still displaying them in the template as shown above ("for each post in the given blog ...do some html and... for each x images for that post...do some more html").
I appreciate that changing up the images displayed in a conventional "blog post" after the initial posting isn't a context that makes much sense - but as mentioned I want that flexibility to maybe use elsewhere, or reuse the code for something else at a later date. And I have a feeling I'm stuck because of a knowledge/skill gap or a wider problem with the way I'm currently working, so might as well identify it here.
I think you're overcomplicating things a bit. If you want to control how many images you display in a particular context, you can just slice the image queryset, at the point of use.
So in your template you would do something like this to render the first three images:
{% for image in post.blogimage_set.all|slice:":3" %}
<img src="yada yada {{image.img}} yada yada></img>
{% endfor %}
Note that querysets are lazy, so this will only fetch the first three images from your database.
If somewhere else you want to use more/fewer images, you just slice the queryset differently. I don't think you need a custom model manager to achieve this.

Facebook FQL Query only returning a limited amount of objects?

I am running an FQL query through the Facebook api:
SELECT username FROM page WHERE CONTAINS("Musician/Band")
I am expecting this to return a large amount of items, but it only returned about 100. Is there a limit on the amount of items a query like this will return? Or is this just not a query that is written wrong? In case you couldn't tell, I wanted the usernames of all of the musical artists on FB.
Thank you for your insight.
FQL has LIMIT and OFFSET keywords. You can get upto 5000 results at a time but better way to do it is through pagination
eg:
SELECT username FROM page WHERE CONTAINS("Musician/Band") LIMIT 200 //gets first 200 results
SELECT username FROM page WHERE CONTAINS("Musician/Band") LIMIT 200 OFFSET 201 //to get next 200 results
and so on..
Also you can use Facebook multiquery to minimize number of queries made.

Get most commented posts in django with django comments

I'm trying to get the ten most commented posts in my django app, but I'm unable to do it because I can't think a proper way.
I'm currently using the django comments framework, and I've seen a possibility of doing this with aggregate or annotate , but I can figure out how.
The thing would be:
Get all the posts
Calculate the number of comments per post (I have a comment_count method for that)
Order the posts from most commented to less
Get the first 10 (for example)
Is there any "simple" or "pythonic" way to do this? I'm a bit lost since the comments framework is only accesible via template tags, and not directly from the code (unless you want to modify it)
Any help is appreciated
You're right that you need to use the annotation and aggregation features. What you need to do is group by and get a count of the object_pk of the Comment model:
from django.contrib.comments.models import Comment
from django.db.models import Count
o_list = Comment.objects.values('object_pk').annotate(ocount=Count('object_pk'))
This will assign something like the following to o_list:
[{'object_pk': '123', 'ocount': 56},
{'object_pk': '321', 'ocount': 47},
...etc...]
You could then sort the list and slice the top 10:
top_ten_objects = sorted(o_list, key=lambda k: k['ocount'])[:10]
You can then use the values in object_pk to retrieve the objects that the comments are attached to.
Annotate is going to be the preferred way, partially because it will reduce db queries and it's basically a one-liner. While your theoretical loop would work, I bet your comment_count method relies on querying comments for a given post, which would be 1 query per post that you loop over- nasty!
posts_by_score = Comment.objects.filter(is_public=True).values('object_pk').annotate(
score=Count('id')).order_by('-score')
post_ids = [int(obj['object_pk']) for obj in posts_by_score]
top_posts = Post.objects.in_bulk(post_ids)
This code is shameless adapted from Django-Blog-Zinnia (no affiliation)

How to get a real-size profile picture from a user?

Having a User ID xUID, i know I can get a profile picture this way:
http://graph.facebook.com/xUID/picture?type=large
The problem is that the picture returned from that URL is not the real size (it's about 200px wide).
I need to get that user picture, but real size.
What i've done so far is:
1. Getting the user albums
https://graph.facebook.com/me/albums?access_token=xToken
2. Iterating on that, and getting the album that have the type="profile".
3. With that Album ID (xAID) I can construct a FQL query:
SELECT pid, object_id, src_big FROM photo WHERE album_object_id = xAID
4. And getting the profile pictures there.
5. I need to iterate and find the lastone uploaded by the user.
So, this process is complex and time consuming. Is there any better/simpler/faster way to acomplish this?
Thanks a lot!
http://graph.facebook.com/xUID/picture?width=720&height=720
You need to perform only one FQL query:
SELECT pid, object_id, src_big
FROM photo
WHERE object_id IN
(SELECT cover_object_id
FROM album
WHERE owner=me() AND type="profile")
src_big will contain link to profile original source.
If you need to get specific user's profile picture please change me() with specific user id.
Ok, just did as the question said. Browse the Albums, and getting the first profile picture from there.
The answer from Julio doesn't work becouse it's not possible to include "type" on a WHERE clause, becouse it's not an indexable column.
The cover photo also isn't always the most recent photo, as of a few days ago.
Get cover_object_id:
fql?q=SELECT cover_object_id, type FROM album WHERE owner="userid" AND type="profile"
Get src_big:
fql?q=SELECT pid, object_id, src_big FROM photo WHERE object_id="cover object id obtained above"
img src="src_big obtained above"
This helps in something?