2016-02-13 17:06:36 -06:00
# -*- coding: utf-8 -*-
2016-02-14 17:39:56 -06:00
import time
2016-02-13 17:06:36 -06:00
import arrow
import languageHandler
import paths
import vkSessionHandler
import logging
import utils
from config_utils import Configuration , ConfigurationResetException
log = logging . getLogger ( " vk.session " )
sessions = { }
2016-02-17 08:11:47 -06:00
# Saves possible set of identifier keys for VK'S data types
# see https://vk.com/dev/datatypes for more information.
# I've added the Date identifier (this is a field in unix time format), for special objects (like friendships indicators) because these objects doesn't have an own identifier.
identifiers = [ " aid " , " gid " , " uid " , " pid " , " id " , " post_id " , " nid " , " date " ]
def find_item ( list , item ) :
""" Finds an item in a list by taking an identifier """
# determines the kind of identifier that we are using
global identifiers
identifier = None
for i in identifiers :
if item . has_key ( i ) :
identifier = i
if identifier == None :
2016-02-17 09:18:36 -06:00
# if there are objects that can't be processed by lack of identifier, let's print keys for finding one.
2016-02-17 08:11:47 -06:00
print item . keys ( )
for i in list :
if i . has_key ( identifier ) and i [ identifier ] == item [ identifier ] :
return True
return False
2016-02-13 17:06:36 -06:00
def add_attachment ( attachment ) :
""" Adds information about the attachment files in posts. It only adds the text, I mean, no attachment file is added here.
This will produce a result like ' Title of a web page: http://url.xxx ' , etc . """
msg = u " "
if attachment [ " type " ] == " link " :
msg = u " {0} : {1} " . format ( attachment [ " link " ] [ " title " ] , attachment [ " link " ] [ " url " ] )
elif attachment [ " type " ] == " photo " :
msg = attachment [ " photo " ] [ " text " ]
if msg == " " :
return " photo with no description available "
elif attachment [ " type " ] == " video " :
msg = u " video: {0} " . format ( attachment [ " video " ] [ " title " ] , )
return msg
def add_text ( status ) :
""" This shorts the text to 140 characters for displaying it in the list control. """
message = " "
if status . has_key ( " text " ) :
if len ( status [ " text " ] ) < 140 :
2016-02-22 08:49:51 -06:00
message = utils . clean_text ( status [ " text " ] )
2016-02-13 17:06:36 -06:00
else :
2016-02-22 08:49:51 -06:00
message = utils . clean_text ( status [ " text " ] [ : 139 ] )
2016-02-13 17:06:36 -06:00
return message
def compose_new ( status , session ) :
""" This method is used to compose an item of the news feed. """
user = session . get_user_name ( status [ " source_id " ] )
2016-02-22 05:53:37 -06:00
if status . has_key ( " copy_owner_id " ) :
user = _ ( u " {0} has shared the {1} ' s post " ) . format ( user , session . get_user_name ( status [ " copy_owner_id " ] ) )
2016-02-13 17:06:36 -06:00
message = " "
original_date = arrow . get ( status [ " date " ] )
created_at = original_date . humanize ( locale = languageHandler . getLanguage ( ) )
if status [ " type " ] == " post " :
message + = add_text ( status )
if status . has_key ( " attachment " ) and len ( status [ " attachment " ] ) > 0 :
message + = add_attachment ( status [ " attachment " ] )
if message == " " :
message = " no description available "
elif status [ " type " ] == " audio " :
2016-02-22 05:53:37 -06:00
message = _ ( u " {0} has added an audio: {1} " ) . format ( user , u " , " . join ( compose_audio ( status [ " audio " ] [ 1 ] , session ) ) , )
2016-02-13 17:06:36 -06:00
elif status [ " type " ] == " friend " :
msg_users = u " "
2016-02-17 09:18:36 -06:00
for i in status [ " friends " ] [ 1 : ] :
msg_users = msg_users + u " {0} , " . format ( session . get_user_name ( i [ " uid " ] ) )
2016-02-17 08:11:47 -06:00
message = _ ( u " {0} hadded friends: {1} " ) . format ( user , msg_users )
2016-02-13 17:06:36 -06:00
else :
if status [ " type " ] != " post " : print status [ " type " ]
return [ user , message , created_at ]
def compose_status ( status , session ) :
user = session . get_user_name ( status [ " from_id " ] )
message = " "
original_date = arrow . get ( status [ " date " ] )
created_at = original_date . humanize ( locale = languageHandler . getLanguage ( ) )
2016-02-22 05:53:37 -06:00
if status . has_key ( " copy_owner_id " ) :
user = _ ( u " {0} has shared the {1} ' s post " ) . format ( user , session . get_user_name ( status [ " copy_owner_id " ] ) )
if status [ " post_type " ] == " post " or status [ " post_type " ] == " copy " :
2016-02-13 17:06:36 -06:00
message + = add_text ( status )
if status . has_key ( " attachment " ) and len ( status [ " attachment " ] ) > 0 :
message + = add_attachment ( status [ " attachment " ] )
if message == " " :
message = " no description available "
return [ user , message , created_at ]
def compose_audio ( audio , session ) :
2016-02-19 17:30:11 -06:00
if audio == False : return [ _ ( u " Audio removed from library " ) , " " , " " ]
2016-02-13 17:06:36 -06:00
return [ audio [ " title " ] , audio [ " artist " ] , utils . seconds_to_string ( audio [ " duration " ] ) ]
class vkSession ( object ) :
def order_buffer ( self , name , data , field ) :
2016-02-17 08:11:47 -06:00
""" Put new items on the local database. Useful for cursored buffers
2016-02-13 17:06:36 -06:00
name str : The name for the buffer stored in the dictionary .
data list : A list with items and some information about cursors .
returns the number of items that has been added in this execution """
2016-02-17 08:11:47 -06:00
first_addition = False
2016-02-13 17:06:36 -06:00
num = 0
if self . db . has_key ( name ) == False :
self . db [ name ] = { }
self . db [ name ] [ " items " ] = [ ]
2016-02-17 08:11:47 -06:00
first_addition = True
2016-02-13 17:06:36 -06:00
for i in data :
if i . has_key ( " type " ) and i [ " type " ] == " wall_photo " : continue
2016-02-17 08:11:47 -06:00
if find_item ( self . db [ name ] [ " items " ] , i ) == False :
# if i not in self.db[name]["items"]:
if first_addition :
if self . settings [ " general " ] [ " reverse_timelines " ] == False : self . db [ name ] [ " items " ] . append ( i )
else : self . db [ name ] [ " items " ] . insert ( 0 , i )
else :
if self . settings [ " general " ] [ " reverse_timelines " ] == False : self . db [ name ] [ " items " ] . insert ( 0 , i )
else : self . db [ name ] [ " items " ] . append ( i )
2016-02-13 17:06:36 -06:00
num = num + 1
2016-02-17 08:11:47 -06:00
2016-02-13 17:06:36 -06:00
return num
def __init__ ( self , session_id ) :
self . session_id = session_id
self . logged = False
self . settings = None
self . vk = vkSessionHandler . vkObject ( )
self . db = { }
self . db [ " users " ] = { }
self . db [ " groups " ] = { }
@property
def is_logged ( self ) :
return self . logged
def get_configuration ( self ) :
""" Gets settings for a session. """
file_ = " %s /session.conf " % ( self . session_id , )
# try:
log . debug ( " Creating config file %s " % ( file_ , ) )
self . settings = Configuration ( paths . config_path ( file_ ) , paths . app_path ( " session.defaults " ) )
# except:
# log.exception("The session configuration has failed.")
def login ( self ) :
""" Login using credentials from settings.
2016-02-17 08:11:47 -06:00
if the user account isn ' t authorised, it ' ll call self . authorise ( ) before login .
If the access_token has expired , it will call authorise ( ) too , for getting a new access token . """
2016-02-13 17:06:36 -06:00
if self . settings [ " vk " ] [ " token " ] != None :
2016-02-14 18:46:23 -06:00
result = self . vk . login_access_token ( self . settings [ " vk " ] [ " token " ] )
2016-02-13 17:06:36 -06:00
self . logged = True
log . debug ( " Logged. " )
2016-02-14 18:46:23 -06:00
if result == False :
self . authorise ( )
2016-02-13 17:06:36 -06:00
else :
2016-02-14 18:46:23 -06:00
self . authorise ( )
2016-02-19 17:30:11 -06:00
self . get_my_data ( )
2016-02-13 17:06:36 -06:00
def authorise ( self ) :
2016-02-14 18:46:23 -06:00
self . vk . login ( self . settings [ " vk " ] [ " user " ] , self . settings [ " vk " ] [ " password " ] )
self . settings [ " vk " ] [ " token " ] = self . vk . client . _session . access_token
self . settings . write ( )
2016-02-13 17:06:36 -06:00
def post_wall_status ( self , message , * args , * * kwargs ) :
2016-02-17 08:11:47 -06:00
""" Sends a post to an user, group or community wall. """
2016-02-13 17:06:36 -06:00
response = self . vk . client . wall . post ( message = message , * args , * * kwargs )
def get_newsfeed ( self , name = " newsfeed " , no_next = True , endpoint = " " , * args , * * kwargs ) :
data = getattr ( self . vk . client . newsfeed , " get " ) ( * args , * * kwargs )
if data != None :
2016-02-17 09:18:36 -06:00
self . process_usernames ( data )
2016-02-13 17:06:36 -06:00
num = self . order_buffer ( name , data [ " items " ] [ : - 1 ] , " post_id " )
return num
def get_page ( self , name = " " , no_next = True , endpoint = " " , * args , * * kwargs ) :
data = None
full_list = False
if kwargs . has_key ( " parent_endpoint " ) :
p = kwargs [ " parent_endpoint " ]
kwargs . pop ( " parent_endpoint " )
if kwargs . has_key ( " full_list " ) :
print kwargs
full_list = True
kwargs . pop ( " full_list " )
if kwargs . has_key ( " identifier " ) :
identifier = kwargs [ " identifier " ]
kwargs . pop ( " identifier " )
p = getattr ( self . vk . client , p )
data = getattr ( p , endpoint ) ( * args , * * kwargs )
# print data
if data != None :
# try:
if full_list == False :
num = self . order_buffer ( name , data [ 1 : ] , identifier )
else :
num = self . order_buffer ( name , data , identifier )
# except:
# num = self.order_buffer(name, data["items"][:-1])
ids = " "
for i in data [ 1 : ] :
if i . has_key ( " from_id " ) :
if str ( i [ " from_id " ] ) not in ids : ids + = " {0} , " . format ( i [ " from_id " ] )
self . get_users ( ids )
return num
def get_user_name ( self , user_id ) :
if user_id > 0 :
if self . db [ " users " ] . has_key ( user_id ) :
return self . db [ " users " ] [ user_id ]
else :
return " no specified user "
else :
if self . db [ " groups " ] . has_key ( abs ( user_id ) ) :
return self . db [ " groups " ] [ abs ( user_id ) ]
else :
return " no specified community "
def get_users ( self , user_ids = None , group_ids = None ) :
if user_ids != None :
u = self . vk . client . users . get ( user_ids = user_ids , fields = " uid, first_name, last_name " )
for i in u :
self . db [ " users " ] [ i [ " uid " ] ] = u " {0} {1} " . format ( i [ " first_name " ] , i [ " last_name " ] )
if group_ids != None :
g = self . vk . client . groups . getById ( group_ids = group_ids , fields = " name " )
for i in g :
self . db [ " groups " ] [ i [ " gid " ] ] = i [ " name " ]
2016-02-17 09:18:36 -06:00
def process_usernames ( self , data ) :
for i in data [ " profiles " ] :
self . db [ " users " ] [ i [ " uid " ] ] = u " {0} {1} " . format ( i [ " first_name " ] , i [ " last_name " ] )
for i in data [ " groups " ] :
2016-02-19 17:30:11 -06:00
self . db [ " groups " ] [ i [ " gid " ] ] = i [ " name " ]
def get_my_data ( self ) :
self . user_id = self . vk . client . users . get ( fields = " uid " ) [ 0 ] [ " uid " ]