def update_counters(self): """ Update counters for user with special query and calculate sum of them """ try: response = api_call('users.get', ids=self.remote_id, fields='counters') except VkontakteError as e: log.warning( "There is vkontakte error [code=%d] while updating user [id=%d] counters: %s" % (e.code, self.remote_id, e.description)) return False if 'counters' not in response[0]: log.info("There is no counters field in response %s" % response) else: for counter in self.counters: if counter in response[0]['counters']: setattr(self, counter, response[0]['counters'][counter]) self.sum_counters = sum( [getattr(self, counter) for counter in self.counters]) self.counters_updated = timezone.now() self.save()
def fetch_likes_user_ids(self, likes_type, owner_id, item_id, offset=0, count=1000, filter='likes', **kwargs): if count > 1000: raise ValueError("Parameter 'count' can not be more than 1000") if filter not in ['likes', 'copies']: raise ValueError( "Parameter 'filter' should be equal to 'likes' or 'copies'") if likes_type is None: raise ImproperlyConfigured( "'likes_type' attribute should be specified") kwargs['type'] = likes_type kwargs['owner_id'] = owner_id kwargs['item_id'] = item_id kwargs['filter'] = filter kwargs['friends_only'] = 0 kwargs['offset'] = int(offset) kwargs['count'] = int(count) log.debug('Fetching like users ids of %s %s_%s, offset %d' % (likes_type, owner_id, item_id, offset)) response = api_call('likes.getList', **kwargs) return response['users']
def fetch_members(self, group, offset=0, count=1000): response = api_call('groups.getMembers', group_id=group.pk, fields='first_name,last_name,sex,bdate,country,city', offset=offset, count=count, v=5.9) users = User.remote.parse_response_users(response, items_field='items') ids = [u.pk for u in users] return ids
def api_call(self, *args, **kwargs): if 'ids' in kwargs and 'get_by_ids' in self.methods: kwargs['cids'] = ','.join(map(lambda i: str(i), kwargs.pop('ids'))) method = self.methods['get_by_ids'] else: if 'country' in kwargs and isinstance(kwargs['country'], Country): kwargs['country'] = kwargs['country'].remote_id method = self.methods['get'] return api_call(self.model.methods_namespace + '.' + method, **kwargs)
def fetch_members(self, offset=0, count=1000): response = api_call('groups.getMembers', group_id=self.pk, fields='first_name,last_name,sex,bdate,country,city', offset=offset, count=count, v=5.9) users = User.remote.parse_response_users(response, items_field='items') users_to_fetch.disconnect(receiver=fetch_users) # prevent fetch users work self.members.add(*users) return users
def update_counters(self): """ Update counters for user with special query and calculate sum of them """ try: response = api_call('users.get', uids=self.remote_id, fields='counters') except VkontakteError, e: log.warning("There is vkontakte error [code=%d] while updating user [id=%d] counters: %s" % ( e.code, self.remote_id, e.description)) return False
def get_group_members_online_count(self, group, *args, **kwargs): if 'vkontakte_groups' not in settings.INSTALLED_APPS: raise ImproperlyConfigured("Application '%s' not in INSTALLED_APPS" % 'vkontakte_groups') from vkontakte_groups.models import Group if not isinstance(group, Group): raise ValueError("Argument 'group' should be instance of Group") kwargs['group_id'] = group.remote_id kwargs['online'] = 1 response = api_call('users.search', **kwargs) return response[0]
def fetch_likes_user_ids(self, likes_type, owner_id, item_id, offset=0, count=1000, filter='likes', **kwargs): if count > 1000: raise ValueError("Parameter 'count' can not be more than 1000") if filter not in ['likes', 'copies']: raise ValueError("Parameter 'filter' should be equal to 'likes' or 'copies'") if likes_type is None: raise ImproperlyConfigured("'likes_type' attribute should be specified") # type # тип Like-объекта. Подробнее о типах объектов можно узнать на странице Список типов Like-объектов. kwargs['type'] = likes_type # owner_id # идентификатор владельца Like-объекта (id пользователя или id приложения). Если параметр type равен sitepage, # то в качестве owner_id необходимо передавать id приложения. Если параметр не задан, то считается, что он # равен либо идентификатору текущего пользователя, либо идентификатору текущего приложения (если type равен # sitepage). kwargs['owner_id'] = owner_id # item_id # идентификатор Like-объекта. Если type равен sitepage, то параметр item_id может содержать значение параметра # page_id, используемый при инициализации виджета «Мне нравится». kwargs['item_id'] = item_id # page_url # url страницы, на которой установлен виджет «Мне нравится». Используется вместо параметра item_id. # filter # указывает, следует ли вернуть всех пользователей, добавивших объект в список "Мне нравится" или только тех, # которые рассказали о нем друзьям. Параметр может принимать следующие значения: # likes – возвращать всех пользователей # copies – возвращать только пользователей, рассказавших об объекте друзьям # По умолчанию возвращаются все пользователи. kwargs['filter'] = filter # friends_only # указывает, необходимо ли возвращать только пользователей, которые являются друзьями текущего пользователя. # Параметр может принимать следующие значения: # 0 – возвращать всех пользователей в порядке убывания времени добавления объекта # 1 – возвращать только друзей текущего пользователя в порядке убывания времени добавления объекта # Если метод был вызван без авторизации или параметр не был задан, то считается, что он равен 0. kwargs['friends_only'] = 0 # offset # смещение, относительно начала списка, для выборки определенного подмножества. Если параметр не задан, то # считается, что он равен 0. kwargs['offset'] = int(offset) # count # количество возвращаемых идентификаторов пользователей. # Если параметр не задан, то считается, что он равен 100, если не задан параметр friends_only, в противном # случае 10. Максимальное значение параметра 1000, если не задан параметр friends_only, в противном случае 100. kwargs['count'] = int(count) log.debug('Fetching like users ids of %s %s_%s, offset %d' % (likes_type, owner_id, item_id, offset)) response = api_call('likes.getList', **kwargs) return response['users']
def get_group_members_online_count(self, group, *args, **kwargs): if 'vkontakte_groups' not in settings.INSTALLED_APPS: raise ImproperlyConfigured( "Application '%s' not in INSTALLED_APPS" % 'vkontakte_groups') from vkontakte_groups.models import Group if not isinstance(group, Group): raise ValueError("Argument 'group' should be instance of Group") kwargs['group_id'] = group.remote_id kwargs['online'] = 1 response = api_call('users.search', **kwargs) return response[0]
def fetch_likes_user_ids(self, likes_type, owner_id, item_id, offset=0, count=1000, filter='likes', **kwargs): if count > 1000: raise ValueError("Parameter 'count' can not be more than 1000") if filter not in ['likes', 'copies']: raise ValueError("Parameter 'filter' should be equal to 'likes' or 'copies'") if likes_type is None: raise ImproperlyConfigured("'likes_type' attribute should be specified") kwargs['type'] = likes_type kwargs['owner_id'] = owner_id kwargs['item_id'] = item_id kwargs['filter'] = filter kwargs['friends_only'] = 0 kwargs['offset'] = int(offset) kwargs['count'] = int(count) log.debug('Fetching like users ids of %s %s_%s, offset %d' % (likes_type, owner_id, item_id, offset)) response = api_call('likes.getList', **kwargs) return response['users']
def update_counters(self): """ Update counters for user with special query and calculate sum of them """ try: response = api_call('users.get', ids=self.remote_id, fields='counters') except VkontakteError as e: log.warning("There is vkontakte error [code=%d] while updating user [id=%d] counters: %s" % ( e.code, self.remote_id, e.description)) return False if 'counters' not in response[0]: log.info("There is no counters field in response %s" % response) else: for counter in self.counters: if counter in response[0]['counters']: setattr(self, counter, response[0]['counters'][counter]) self.sum_counters = sum([getattr(self, counter) for counter in self.counters]) self.counters_updated = timezone.now() self.save()
def fetch_reposts_items(self, offset=0, count=1000, *args, **kwargs): if count > 1000: raise ValueError("Parameter 'count' can not be more than 1000") # owner_id # идентификатор пользователя или сообщества, на стене которого находится запись. Если параметр не задан, то он считается равным идентификатору текущего пользователя. # Обратите внимание, идентификатор сообщества в параметре owner_id необходимо указывать со знаком "-" — например, owner_id=-1 соответствует идентификатору сообщества ВКонтакте API (club1) kwargs['owner_id'] = self.owner_remote_id # post_id # идентификатор записи на стене. kwargs['post_id'] = self.remote_id_short # offset # смещение, необходимое для выборки определенного подмножества записей. kwargs['offset'] = int(offset) # count # количество записей, которое необходимо получить. # положительное число, по умолчанию 20, максимальное значение 100 kwargs['count'] = int(count) response = api_call('wall.getReposts', **kwargs) log.debug('Fetching reposts for post %s: %d returned, offset %d, count %d' % (self.remote_id, len(response['items']), offset, count)) return response['items']
def update_for_group(self, group, offset=0): ''' Fetch all users for this group, save them as IDs and after make m2m relations ''' try: stat, created = self.get_or_create(group=group, time=None) except MultipleObjectsReturned: self.filter(group=group, time=None).delete() stat = self.create(group=group, time=None, offset=0) created = True if created: stat.set_defaults() offset = offset or stat.offset offset_step = 1000 while True: response = api_call('groups.getMembers', gid=group.remote_id, offset=offset) ids = response['users'] log.debug('Call returned %s ids for group "%s" with offset %s, now members_ids %s' % (len(ids), group, offset, len(stat.members_ids))) if len(ids) == 0: break # add new ids to group stat members stat.members_ids += ids stat.offset = offset # stat.save() offset += offset_step yield (offset + len(ids), response['count'], offset_step) # save stat with time and other fields stat.time = timezone.now() stat.save_final() signals.group_migration_updated.send(sender=GroupMigration, instance=stat)
def fetch_reposts_items(self, offset=0, count=1000, *args, **kwargs): if count > 1000: raise ValueError("Parameter 'count' can not be more than 1000") # owner_id # идентификатор пользователя или сообщества, на стене которого находится запись. Если параметр не задан, то он считается равным идентификатору текущего пользователя. # Обратите внимание, идентификатор сообщества в параметре owner_id необходимо указывать со знаком "-" — например, owner_id=-1 соответствует идентификатору сообщества ВКонтакте API (club1) kwargs['owner_id'] = self.owner_remote_id # post_id # идентификатор записи на стене. kwargs['post_id'] = self.remote_id_short # offset # смещение, необходимое для выборки определенного подмножества записей. kwargs['offset'] = int(offset) # count # количество записей, которое необходимо получить. # положительное число, по умолчанию 20, максимальное значение 100 kwargs['count'] = int(count) response = api_call('wall.getReposts', **kwargs) log.debug( 'Fetching reposts for post %s: %d returned, offset %d, count %d' % (self.remote_id, len(response['items']), offset, count)) return response['items']
def get_query(self, q, request): # TODO: make model Suggestion and use it response = api_call('ads.getSuggestions', methods_access_tag='ads', **{'section': self.section, 'q': q}) # print response return response
def get_objects(self, ids): response = api_call('ads.getSuggestions', methods_access_tag='ads', **{'section': self.section, 'cities': '1'}) return [item['name'] for item in response if item['id'] in ids]
def get_vk_detail(self, link): from vkontakte_api.api import api_call, api_recursive_call # like https://vk.com/dev/likes.getList # share https://vk.com/dev/wall.getReposts # comment https://vk.com/dev/wall.getComments # members(followers) https://vk.com/dev/users.getFollowers rows = OrderedDict() matches = re.match(r'^https?://vk\.com/wall(-?\d+_\d+)$', link) if matches: post_id = matches.group(1) owner_id = post_id.split('_')[0] item_id = post_id.split('_')[1] # check posts = api_call('wall.getById', posts=post_id, v=5.44) if len(posts) == 0: rows['errors'] = 'Post not found' return rows # getting followers if int(owner_id) > 0: response = api_recursive_call( 'users.getFollowers', user_id=owner_id, fields='last_name', count=1000, v=5.44 ) # fields='last_name' added here to get 'deactivated' field else: group_id = -1 * int(owner_id) response = api_recursive_call( 'groups.getMembers', group_id=group_id, fields='last_name', count=1000, v=5.44 ) # fields='last_name' added here to get 'deactivated' field subscribers = {} subscribers_user_ids = [] for u in response['items']: user_id = u['id'] subscribers[user_id] = u subscribers_user_ids.append(user_id) # getting likes response = api_recursive_call('likes.getList', type='post', owner_id=owner_id, item_id=item_id, count=1000, v=5.44) likes_user_ids = response['items'] # getting shares response = api_recursive_call('wall.getReposts', owner_id=owner_id, post_id=item_id, count=1000, v=5.44) shares = response['items'] shares_user_ids = [] for share in shares: user_id = share['from_id'] shares_user_ids.append(user_id) # getting comments # count max 100 response = api_recursive_call('wall.getComments', owner_id=owner_id, post_id=item_id, count=100, v=5.44) comments = response['items'] comments_user_ids = [] for comment in comments: user_id = comment['from_id'] comments_user_ids.append(user_id) user_ids = set() # lets get unique set user_ids.update(subscribers_user_ids, likes_user_ids, shares_user_ids, comments_user_ids) user_ids_list = list(user_ids) start_pos = 0 STEP = 350 # 350 is near maximum ids what method accepted, this number getting by experiment end_pos = STEP while start_pos < len(user_ids_list): slice = user_ids_list[start_pos:end_pos] user_ids_str = ','.join([str(id) for id in slice]) response = api_call( 'users.get', user_ids=user_ids_str, fields='first_name, last_name, sex, bdate, country, city', v=5.8) for user in response: u = self.vk_user(user) user_id = user['id'] if user_id in subscribers_user_ids: u['member'] = 1 if 'deactivated' in subscribers[user_id]: u['deactivated'] = subscribers[user_id][ 'deactivated'] if user_id in likes_user_ids: u['like'] = 1 if user_id in shares_user_ids: u['share'] = 1 if user_id in comments_user_ids: u['comment'] = comments_user_ids.count(user_id) rows[user_id] = u # increse start_pos += STEP end_pos += STEP else: rows['errors'] = 'Invalid post link' return rows
def get_vk_detail(self, link): from vkontakte_api.api import api_call, api_recursive_call # like https://vk.com/dev/likes.getList # share https://vk.com/dev/wall.getReposts # comment https://vk.com/dev/wall.getComments # members(followers) https://vk.com/dev/users.getFollowers rows = OrderedDict() matches = re.match(r'^https?://vk\.com/wall(-?\d+_\d+)$', link) if matches: post_id = matches.group(1) owner_id = post_id.split('_')[0] item_id = post_id.split('_')[1] # check posts = api_call('wall.getById', posts=post_id, v=5.44) if len(posts) == 0: rows['errors'] = 'Post not found' return rows # getting followers if int(owner_id) > 0: response = api_recursive_call('users.getFollowers', user_id=owner_id, fields='last_name', count=1000, v=5.44) # fields='last_name' added here to get 'deactivated' field else: group_id = -1 * int(owner_id) response = api_recursive_call('groups.getMembers', group_id=group_id, fields='last_name', count=1000, v=5.44) # fields='last_name' added here to get 'deactivated' field subscribers = {} subscribers_user_ids = [] for u in response['items']: user_id = u['id'] subscribers[user_id] = u subscribers_user_ids.append(user_id) # getting likes response = api_recursive_call('likes.getList', type='post', owner_id=owner_id, item_id=item_id, count=1000, v=5.44) likes_user_ids = response['items'] # getting shares response = api_recursive_call('wall.getReposts', owner_id=owner_id, post_id=item_id, count=1000, v=5.44) shares = response['items'] shares_user_ids = [] for share in shares: user_id = share['from_id'] shares_user_ids.append(user_id) # getting comments # count max 100 response = api_recursive_call('wall.getComments', owner_id=owner_id, post_id=item_id, count=100, v=5.44) comments = response['items'] comments_user_ids = [] for comment in comments: user_id = comment['from_id'] comments_user_ids.append(user_id) user_ids = set() # lets get unique set user_ids.update(subscribers_user_ids, likes_user_ids, shares_user_ids, comments_user_ids) user_ids_list = list(user_ids) start_pos = 0 STEP = 350 # 350 is near maximum ids what method accepted, this number getting by experiment end_pos = STEP while start_pos < len(user_ids_list): slice = user_ids_list[start_pos:end_pos] user_ids_str = ','.join([str(id) for id in slice]) response = api_call('users.get', user_ids=user_ids_str, fields='first_name, last_name, sex, bdate, country, city', v=5.8) for user in response: u = self.vk_user(user) user_id = user['id'] if user_id in subscribers_user_ids: u['member'] = 1 if 'deactivated' in subscribers[user_id]: u['deactivated'] = subscribers[user_id]['deactivated'] if user_id in likes_user_ids: u['like'] = 1 if user_id in shares_user_ids: u['share'] = 1 if user_id in comments_user_ids: u['comment'] = comments_user_ids.count(user_id) rows[user_id] = u # increse start_pos += STEP end_pos += STEP else: rows['errors'] = 'Invalid post link' return rows