diff --git a/kodi-vk.inpos.ru/addon.xml b/kodi-vk.inpos.ru/addon.xml
index d7ddb27..34bafee 100644
--- a/kodi-vk.inpos.ru/addon.xml
+++ b/kodi-vk.inpos.ru/addon.xml
@@ -5,6 +5,7 @@ name="VK Add-on"
provider-name="inpos">
+
image video audio
diff --git a/kodi-vk.inpos.ru/default.py b/kodi-vk.inpos.ru/default.py
index ab15f4f..dc75a9e 100644
--- a/kodi-vk.inpos.ru/default.py
+++ b/kodi-vk.inpos.ru/default.py
@@ -3,8 +3,12 @@ import sys, os, vk, time
from math import ceil
import xbmc, xbmcplugin, xbmcaddon, xbmcgui
import urlparse
-from urllib3 import request
+import urllib2
from urllib import urlencode
+import re
+import simplejson as json
+
+_VERSION = '0.0.1'
_ADDON_NAME = 'kodi-vk.inpos.ru'
_addon = xbmcaddon.Addon(id = _ADDON_NAME)
@@ -27,13 +31,17 @@ _CTYPE_IMAGE = 'image'
_DO_HOME = 'home'
_DO_MY_VIDEO = 'my_video'
+_DO_ALL_VIDEO = 'all_video'
+_DO_PLAY_VIDEO = 'play_video'
_DO_MY_AUDIO = 'my_audio'
_DO_MY_PHOTO = 'my_photo'
_DO_ALL_PHOTO = 'all_photo'
_DO_FRIENDS = 'friends'
_DO_GROUPS = 'groups'
-
+_VK_VIDEO_SOURCE = 'vk_video'
+_YOUTUBE_VIDEO_SOURCE = 'youtube_video'
+_UNKNOWN_VIDEO_SOURCE = 'unknown_video'
DELAY = 1.0 / 3 # 3 запроса в секунду
@@ -105,7 +113,7 @@ def photos(conn, oid, page_items = 20, page = 1, album = None):
offset = ((page_items * page) - page_items),
count = page_items)
count = photos['count']
- pages = ceil(count / page_items)
+ pages = int(ceil(count / float(page_items)))
l = []
for i in photos['items']:
ph = Photo(i['id'], conn)
@@ -124,10 +132,11 @@ def videos(conn, oid, page_items = 20, page = 1, album = None):
count = page_items,
album_id = album)
count = vids['count']
- pages = ceil(count / page_items)
+ pages = int(ceil(count / float(page_items)))
l = []
for i in vids['items']:
- v = Video(i['id'], conn)
+ vid = str(i['owner_id']) + '_' + str(i['id'])
+ v = Video(vid, conn)
v.info = i
l.append(v)
return {'pages': pages, 'total': count, 'items': l}
@@ -138,8 +147,10 @@ class Video(object):
self.id = vid
self.info = {}
@property
- def files(self):
- pass
+ def v_url(self):
+ return self.info['player']
+ def set_info(self):
+ self.info = self.conn.video.get(videos = self.id)['items'][0]
class User(object):
'''Этот класс описывает свойства и методы пользователя.'''
@@ -187,11 +198,64 @@ class KodiVKGUIPhotos(object):
self.root.add_folder(self.root.gui._string(400508), {'do': _DO_ALL_PHOTO, 'oid': self.root.u.id, 'page': 1})
xbmcplugin.endOfDirectory(_addon_id)
+class KodiVKGUIVideos(object):
+ def __init__(self, root):
+ self.root = root
+ def __get_video_source_(self, v):
+ is_vk_url_re = re.compile('https?\:\/\/[^\/]*vk.com\/.*')
+ is_youtube_url_re = re.compile('https\:\/\/www.youtube.com\/.*')
+ player_url = v.info['player']
+ if len(is_vk_url_re.findall(player_url)) > 0: return _VK_VIDEO_SOURCE
+ if len(is_youtube_url_re.findall(player_url)) > 0: return _YOUTUBE_VIDEO_SOURCE
+ return _UNKNOWN_VIDEO_SOURCE
+
+ def _my_video(self):
+ self.root.add_folder(self.root.gui._string(400509), {'do': _DO_ALL_VIDEO, 'oid': self.root.u.id, 'page': 1})
+ xbmcplugin.endOfDirectory(_addon_id)
+ def _all_video(self):
+ page = int(self.root.params['page'])
+ oid = self.root.params['oid']
+ if page > 1:
+ self.root.add_folder(self.root.gui._string(400601), {'do': _DO_ALL_VIDEO, 'oid': self.root.u.id, 'page': page - 1})
+ vids = videos(self.root.conn, oid, page = page)
+ xbmc.log('pages: %s, total videos: %s' % (vids['pages'], vids['total']))
+ for v in vids['items']:
+ list_item = xbmcgui.ListItem(v.info['title'])
+ list_item.setInfo('video', {
+ 'title' : v.info['title'],
+ 'duration' : int(v.info['duration']),
+ 'plot' : v.info['description']
+ }
+ )
+ list_item.setArt({'thumb': v.info['photo_130'], 'icon': v.info['photo_130'], 'fanart': v.info['photo_130']})
+ list_item.setProperty('IsPlayable', 'true')
+ v_source = self.__get_video_source_(v)
+ if v_source == _VK_VIDEO_SOURCE:
+ params = {'do': _DO_PLAY_VIDEO, 'vid': v.id}
+ url = self.root.url(**params)
+ xbmcplugin.addDirectoryItem(_addon_id, url, list_item, isFolder = False)
+ else:
+ continue
+ if page < vids['pages']:
+ self.root.add_folder(self.root.gui._string(400602), {'do': _DO_ALL_VIDEO, 'oid': self.root.u.id, 'page': page + 1})
+ xbmcplugin.endOfDirectory(_addon_id)
+ def _play_video(self):
+ vid = self.root.params['vid']
+ v = Video(vid, self.root.conn)
+ v.set_info()
+ v_url = v.info['player']
+ paths = self.root.parse_vk_player_html(v_url)
+ ### Здесь должно браться разрешение из настроек
+ k = max(paths.keys())
+ play_item = xbmcgui.ListItem(path = paths[k])
+ xbmcplugin.setResolvedUrl(_addon_id, True, listitem = play_item)
class KodiVkGUI:
'''Окошки, диалоги, сообщения'''
def __init__(self, root):
self.root = root
+ self.photos = KodiVKGUIPhotos(self.root)
+ self.videos = KodiVKGUIVideos(self.root)
def _string(self, string_id):
return _addon.getLocalizedString(string_id).encode('utf-8')
def _login_form(self):
@@ -234,7 +298,6 @@ class KodiVk:
conn = None
def __init__(self):
self.gui = KodiVkGUI(self)
- self.gui_photos = KodiVKGUIPhotos(self)
p = {'do': _DO_HOME}
if sys.argv[2]:
p.update(dict(urlparse.parse_qsl(sys.argv[2][1:])))
@@ -272,13 +335,39 @@ class KodiVk:
except vk.api.VkAuthError:
continue
return conn
+ def parse_vk_player_html(self, v_url):
+ p = re.compile('var\s+playerParams\s*=\s*(.*?);')
+ headers = {'User-Agent' : 'Kodi-vk/%s (linux gnu)' % (_VERSION,)}
+ req = urllib2.Request(v_url, None, headers)
+ http_res = urllib2.urlopen(req)
+ if http_res.code != 200:
+ return None
+ html = http_res.read()
+ h_c_type = http_res.info()['Content-type'].split('charset=')
+ if len(h_c_type) < 2:
+ cs_re = re.compile('content="text/html; charset=([^"]+)"', re.I)
+ cs = cs_re.findall(html)[0]
+ else:
+ cs = h_c_type[1].strip()
+ re_res = p.findall(html)
+ if len(re_res) < 1:
+ return None
+ playerParams = json.loads(re_res[0], encoding = cs)
+ v_keys = filter(lambda x: x.startswith('url'), playerParams['params'][0].keys())
+ res = {}
+ for k in v_keys:
+ res[k.lstrip('url')] = playerParams['params'][0][k]
+ return res
if __name__ == '__main__':
kvk = KodiVk()
_DO = {
_DO_HOME: kvk.gui._home,
- _DO_MY_PHOTO: kvk.gui_photos._my_photo
+ _DO_MY_PHOTO: kvk.gui.photos._my_photo,
+ _DO_MY_VIDEO: kvk.gui.videos._my_video,
+ _DO_ALL_VIDEO: kvk.gui.videos._all_video,
+ _DO_PLAY_VIDEO: kvk.gui.videos._play_video
}
_do_method = kvk.params['do']
diff --git a/kodi-vk.inpos.ru/resources/language/English/strings.po b/kodi-vk.inpos.ru/resources/language/English/strings.po
index 3c6e78e..c93ee14 100644
--- a/kodi-vk.inpos.ru/resources/language/English/strings.po
+++ b/kodi-vk.inpos.ru/resources/language/English/strings.po
@@ -39,3 +39,17 @@ msgstr "Access token"
msgctxt "#400508"
msgid "All Photos"
msgstr "All Photos"
+
+msgctxt "#400509"
+msgid "All Videos"
+msgstr "All Videos"
+
+
+
+msgctxt "#400601"
+msgid "Previous page"
+msgstr "[B]Previous page[/B]"
+
+msgctxt "#400602"
+msgid "Next page"
+msgstr "[B]Next page[/B]"
diff --git a/kodi-vk.inpos.ru/resources/language/Russian/strings.po b/kodi-vk.inpos.ru/resources/language/Russian/strings.po
index ca7c90c..bbd586d 100644
--- a/kodi-vk.inpos.ru/resources/language/Russian/strings.po
+++ b/kodi-vk.inpos.ru/resources/language/Russian/strings.po
@@ -39,3 +39,17 @@ msgstr "Токен доступа"
msgctxt "#400508"
msgid "All Photos"
msgstr "Все фотографии"
+
+msgctxt "#400509"
+msgid "All Videos"
+msgstr "Все видеозаписи"
+
+
+
+msgctxt "#400601"
+msgid "Previous page"
+msgstr "[B]Предыдущая страница[/B]"
+
+msgctxt "#400602"
+msgid "Next page"
+msgstr "[B]Следующая страница[/B]"