Документация¶
- Автор: Алексей Орозбаев
- Группа: КН-101
- Задача: http://anytask.urgu.org/course/21 - Адресная книга
Подготовка к работе¶
В консоли вводим.:
pip install gdata
pip install grab
Далее для работы нужен модуль lxml с некоторыми изменениями:
Если вы пользователь linux.:
sudo apt-get install python-lxml
Если же вы пользователь windows то необходимо скачать и установить следующий файл.:
http://grablib.org/static/download/pycurl-ssl-7.19.0.win32-py2.7.msi
Запуск скрипта¶
Ключи программы.:
--id VK / --vk VK - ваш id vkontakte
--gmail-user EMAIL - google email
--yandex-user EMAIL - yandex email
--sync-action vk/yandex - приоритет информации(в случае совпадения)
--verbose on/off -- отражение хода работы программы
Пример запуска программы.:
python main.py --vk=1 --rt@gmail.com --zuck --sync-action=yandex --verbose=on
После того, как вы введете данную строку, необходимо будет ввести пароли от gmail и yandex.
Информация¶
Информация о классах и их методах¶
Vkontakte¶
vkontakte.py - класс, позволяющий получить контакты из соц. сети VK, по ID.
Метод init.:
def __init__(self, id):
self.vk_id = id
self.access_token = token
self.access_scope = 'contacts, photo_big'
self.api_method = 'friends.get'
В нем мы задаем ключевые параметры для построения ссылки, которая в свою очередь выполнит запрос к API.
Метод makelink.:
def makelink(self):
link = 'https://api.vk.com/method/' \
'%s?uid=%s&access_token=%s&fields=%s' % \
(self.api_method, self.vk_id,
self.access_token, self.access_scope)
return link
В данном методе происходит построение ссылки для запроса к API.
Метод connectapi.:
def connectapi(self):
link = self.makelink()
connect = urllib.urlopen(link).read()
return connect
Подключение к API и возвращение содержимого ответа.
Метод makedict.:
def makedict(self):
dicts = self.connectapi()
list_obj = ast.literal_eval(dicts)
return list_obj
Строку полученную в connectapi преобразует в словарь.
Метод printres.:
def printres(self):
lname = self.makedict()
for i in lname['response']:
try:
if len(i['mobile_phone']) > 0:
phone = str(i['mobile_phone'])
phone = phone.replace('(', '')
phone = phone.replace(')', '')
phone = phone.replace(' ', '')
phone = phone.replace('-', '')
if (phone[:2] == '+7'):
phone = phone.replace('+7', '8')
if(phone.isdigit() is True and len(phone) == 11):
pic = i['photo_big'].replace('\\', '')
strz = '%s %s - %s %s %s' %\
(i['first_name'], i['last_name'], 'none', pic, phone)
vk_contacts.append(strz)
except KeyError:
continue
Данный метод извлекает данные из словаря, нормирует вид мобильного номера, подготавливает данные.
Метод preparecontacts.:
def preparecontacts(self):
for i in vk_contacts:
temp = i.split(' - ')
lst = temp[1].split(' ')
vkc[temp[0]] = lst
Метод создает окончательный словарь, который уже пойдет в merge для последующей обработки.
Мой круг¶
Информация о mk.py mk.py - класс позволяющий получить контакты из соц. сети Мой круг.
Метод init.:
def __init__(self, login, password):
self.login = login
self.passwd = password
self.mode = 'auth'
self.froms = 'moikrug'
self.retpath = 'http://moikrug.ru/circles/first/users/'
Метод с необходимыми данными для авторизации.
Метод grabconnect.:
# Используется специальный модуль grab!
def grabconnect(self):
g = Grab()
link = 'https://passport.yandex.ru/' \
'passport?mode=%s&from=%s&retpath=%s' % \
(self.mode, self.froms, self.retpath)
g.go(link)
g.set_input('login', self.login)
g.set_input('passwd', self.passwd)
g.submit()
g.go('http://moikrug.ru/circles/first/users/')
return g.response.body.decode('cp1251').encode('utf-8')
В данном методе происходит переход на страницу авторизации, ввод в поля необходимых данных, и авторизация, далее, получение исходного кода страницы с 1м кругом.
Метод parsedata.:
def parsedata(self, text):
contactscode = re.findall(r'<tr id="row_(.+?)</tr>', text)
for i in contactscode:
str = ''
strz = ''
listEmail = re.findall(r'<a href="mailto:(.+?)"', i)
listAvatar = re.findall(r'src="//moikrug.ru/(.+?)"', i)
listName = (re.findall(r'class="searchable" title="(.+?)">', i))
listPhone = re.findall(r': </span>(.+?)</li>', i)
listAvatar[0] = listAvatar[0].replace('-square', '-p')
listAvatar[0] = listAvatar[0].replace('square50', 'portrait')
str += '%s - %s - %s - ' % (listName[0], listEmail[0], 'http://moikrug.ru/%s' % listAvatar[0])
for i in listPhone:
if len(i) == 10:
strz += '8' + i
if len(i) == 12:
strz += '8' + i[2:]
if len(i) <= 7:
strz = i
str += '%s - ' % strz
strz = ''
mk_contacts.append(str)
В данном методе мы с помощью регулярных выражений выдергиваем из исходника нужные нам данные.
Метод makedict.:
def makedict(self):
for i in mk_contacts:
temp = i.split(' - ')
mkc[temp[0]] = temp[1:-1]
Аналогично методу из модуля vkontakte подготавливает словарь, для следующей обработки в merge.
Merge¶
merge.py - класс для склейки контактов, то есть если в моём круге и вконтакте у вас есть одинаковый контакт, то здесь это будет видно, в методе init мы ничего не определяем, так как всё нужно импортируется из классов vkontakte и mk.
Метод merge.:
def merge(self):
for i in vkc:
exist = False
for j in mkc:
if vkc[i][2] in mkc[j][2:]:
print "Eq %s - %s" % (i, j)
print "%s or %s(1,2)" % (i, j)
res = input()
if res == 1:
name = i
if res == 2:
name = j
print "avatar: VK or MK(1, 2):"
res = input()
if vkc[i][0] == 'none' and mkc[j][0] != 'none':
email = mkc[j][0]
if res == 1:
avatar = vkc[i][1]
if res == 2:
avatar = mkc[j][1]
phone_number = mkc[j][2:]
contacts_list = []
contacts_list.append(email)
contacts_list.append(avatar)
for x in phone_number:
contacts_list.append(x)
gcc['%s' % name] = contacts_list
exist = True
if exist is True:
continue
else:
gcc[i] = vkc[i]
На входе у нас есть два словаря, vkc(c данными о vkontakte) и mkc(c данными о Моём круге), так как вконтакте более популярная социальная сеть, то за основу поиска совпадений возьмем именно vkc, однако во вконтакте для указания номера телефона, доступно лишь одно поле, в то время как в моём круге несколько, значит по номерам телефона из моего круга создадим список, и будем искать номер телефона из вконтакте в этом списке. При нахождении совпадения, необходимо разьяснить некоторые вещи, какое имя выбрать, и откуда взять фотографию, так как правилами конфиденциальности во вконтакте API нельзя получить email, то если email есть в моём круге, то добавим его в данные. На выходе словарь gcc со всеми данными которые далее пойдут в google.
Google¶
google.py - класс выполняющий одну из самых важный функций в работе приложения, он отправляет полученные нами ранее данные в контакты на наш аккаунт Google.
Метод init.:
def __init__(self, email, passw):
self.email = email
self.passw = passw
self.kolres = '1000'
self.google = gdata.contacts.client.\
ContactsClient(source='Aleks Orozbaev Sync App G')
self.google.ClientLogin(self.email, self.passw, self.google.source)
В данном методе мы инициализируем входные данные и подготавливаемся к подключению к API.
Метод connect.:
def connect(self):
googleContacts = self.contacts(self.google)
return googleContacts
Подключаемся к API.
Метод contacts.:
def contacts(self):
query = gdata.contacts.client.ContactsQuery()
query.max_results = self.kolres
feed = self.google.GetContacts(q=query)
for entry in feed.entry:
try:
strz = '%s' % (entry.name.full_name.text)
except AttributeError:
continue
for contact in entry.phone_number:
if contact.primary and contact.primary == 'true':
phone = contact.text
phone = phone.replace(' ', '')
phone = phone.replace('-', '')
if phone[:2] == '+7':
phone = phone.replace('+7', '8')
if(phone.isdigit() is True and len(phone) == 11):
strz1 = '%s - %s ' % (strz, phone)
google_contacts.append(strz1)
Получаем текущие контакты из вашего аккаунта Google и нормируем вид номера телефона.
Метод preparecontacts.:
def preparecontacts(self):
for i in google_contacts:
temp = i.split(' - ')
gc[temp[0]] = temp[1]
Подготавливаем данные для последующего сравнения с контактами из словаря полученного в результате работы класса merge(gcc).
Метод getphoto.:
def getphoto(self, url, name):
request = Request(url)
f = urlopen(request)
local = open(name, 'wb')
local.write(f.read())
local.close()
Скачиваем на компьютер аватарку из VK или MK.
Метод createcontact.:
def createcontact(self, name, phonenumber, email, avatar):
if email == 'none':
email = ''
if avatar == 'none' or avatar == '':
avatar = ''
newc = gdata.contacts.data.ContactEntry()
print name
print phonenumber
newc.name = gdata.data.Name(
full_name=gdata.data.FullName(text=name))
for i in phonenumber:
newc.phone_number.append(gdata.data.PhoneNumber(
text=i, rel=gdata.data.MOBILE_REL))
contact_entry = self.google.CreateContact(newc)
self.getphoto(avatar, 'pic.jpg')
self.google.ChangePhoto('pic.jpg', contact_entry, content_type='image/jpeg')
print 'Created!'
Метод создания контакта.
Метод addcontacts.:
def addcontacts(self):
for i in gcc:
temp = False
for j in gc:
try:
for x in gcc[i][2:]:
if int(gc[j]) == int(x):
temp = True
break
except UnicodeEncodeError:
continue
if temp is True:
print i
print gcc[i][2]
print 'Allready exist!'
else:
self.createcontact(i, gcc[i][2:], gcc[i][0], gcc[i][1])
Включает в себя проверку на наличие контакта в Google Contacts и в противном случае вызываем метод createcontacts.
P.S. Код в стадии дописывания, возможны некоторые корректировки.
Контакты¶
По вопросам можно писать на orozbaev.ru@gmail.com или vk.com/orozbaev