From 110034697182e286986368aa82ae39986cf28e1b Mon Sep 17 00:00:00 2001 From: taizan-hokuto <55448286+taizan-hokuto@users.noreply.github.com> Date: Thu, 16 Apr 2020 23:18:58 +0900 Subject: [PATCH] Add setup.py --- MANIFEST.in | 2 + README.md | 55 ++++++++++++++++++++ __init__.py | 0 requirements.txt | 1 + setup.py | 62 ++++++++++++++++++++++ yvi/__init__.py | 12 +++++ {config => yvi/config}/__init__.py | 0 exceptions.py => yvi/exceptions.py | 0 {util => yvi/util}/__init__.py | 0 yvi.py => yvi/yvi.py | 82 ++++++++++++++++++------------ 10 files changed, 182 insertions(+), 32 deletions(-) create mode 100644 MANIFEST.in create mode 100644 README.md delete mode 100644 __init__.py create mode 100644 requirements.txt create mode 100644 yvi/__init__.py rename {config => yvi/config}/__init__.py (100%) rename exceptions.py => yvi/exceptions.py (100%) rename {util => yvi/util}/__init__.py (100%) rename yvi.py => yvi/yvi.py (71%) diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..383078b --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,2 @@ +include requirements.txt +global-exclude pytchat/testrun*.py \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..19dd23c --- /dev/null +++ b/README.md @@ -0,0 +1,55 @@ +## Install +```bash +pip install yvi +``` + +## Usage +```python +import yvi + +info = yvi.get_info(video_id = "xxxxxxxx") +info.get_title() +info.get_channel_id() +``` +## Parameter +### video_id + +- video id + +### session + +- session object of requests. + +## Funtions +### get_duration() +動画の長さ(アーカイブのみ。ライブ動画または待機画面の場合0) + +### get_title() +-   動画タイトル + +### get_title_escaped() +-   動画タイトル(絵文字なし。GUIライブラリ等で絵文字が含まれていてエラーが出る場合はこちらを使用してください) + +### get_channel_id() +- チャンネルID + +### get_thumbnail() +-   動画サムネイルURL + +### get_owner_name() +-   配信者名 + +### get_owner_name_escaped() +-   配信者名(絵文字なし) + +### get_owner_image() +-   配信者プロフィール画像URL + +### get_user_name() +-   視聴者名 + +### get_user_name_escaped() +-   視聴者名(絵文字なし) + +### get_user_image() +-   視聴者プロフィール画像URL diff --git a/__init__.py b/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..663bd1f --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +requests \ No newline at end of file diff --git a/setup.py b/setup.py index e69de29..9f7fe8b 100644 --- a/setup.py +++ b/setup.py @@ -0,0 +1,62 @@ +from setuptools import setup, find_packages, Command +from os import path, system, remove, rename, removedirs +import re + +package_name = "yvi" + +root_dir = path.abspath(path.dirname(__file__)) + +def _requirements(): + return [name.rstrip() + for name in open(path.join( + root_dir, 'requirements.txt')).readlines()] + +with open(path.join(root_dir, package_name, '__init__.py')) as f: + init_text = f.read() + version = re.search( + r'__version__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1) + license = re.search( + r'__license__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1) + author = re.search( + r'__author__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1) + author_email = re.search( + r'__author_email__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1) + url = re.search( + r'__url__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1) + +assert version +assert license +assert author +assert author_email +assert url + + + + +with open('README.md', encoding='utf-8') as f: + long_description = f.read() + + + +setup( + author=author, + author_email=author_email, + classifiers=[ + 'Natural Language :: Japanese', + 'Development Status :: 4 - Beta', + 'Programming Language :: Python', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'License :: OSI Approved :: MIT License', + ], + description="Retrieve youtube video info.", + install_requires=_requirements(), + keywords='youtube', + license=license, + long_description=long_description, + long_description_content_type='text/markdown', + name=package_name, + packages=find_packages(exclude=['*log.txt','*tests','*testrun']), + url=url, + version=version, +) \ No newline at end of file diff --git a/yvi/__init__.py b/yvi/__init__.py new file mode 100644 index 0000000..09731ba --- /dev/null +++ b/yvi/__init__.py @@ -0,0 +1,12 @@ +""" +Retriever tool for youtube video information. +""" +__copyright__ = 'Copyright (C) 2020 taizan-hokuto' +__version__ = '0.0.0' +__license__ = 'MIT' +__author__ = 'taizan-hokuto' +__author_email__ = '55448286+taizan-hokuto@users.noreply.github.com' +__url__ = 'https://github.com/taizan-hokuto/yvi' + +from yvi.yvi import get_info + diff --git a/config/__init__.py b/yvi/config/__init__.py similarity index 100% rename from config/__init__.py rename to yvi/config/__init__.py diff --git a/exceptions.py b/yvi/exceptions.py similarity index 100% rename from exceptions.py rename to yvi/exceptions.py diff --git a/util/__init__.py b/yvi/util/__init__.py similarity index 100% rename from util/__init__.py rename to yvi/util/__init__.py diff --git a/yvi.py b/yvi/yvi.py similarity index 71% rename from yvi.py rename to yvi/yvi.py index 0e78f4b..dcb3095 100644 --- a/yvi.py +++ b/yvi/yvi.py @@ -1,10 +1,10 @@ +from . import config +import emoji import json import re import requests -import config -from exceptions import InvalidVideoIdException - -headers = config.headers +from . import util +from . exceptions import InvalidVideoIdException pattern = re.compile(r"yt\.setConfig\({'PLAYER_CONFIG': ({.*})}\);") @@ -44,7 +44,7 @@ item_thumbnail = [ "url" ] -item_channel_name = [ +item_owner_name = [ "videoDetails", "embeddedPlayerOverlayVideoDetailsRenderer", "expandedRenderer", @@ -55,25 +55,17 @@ item_channel_name = [ "text" ] -item_username = [ +item_user_name = [ "args", "user_display_name", ] -item_userimage = [ +item_user_image = [ "args", "user_display_image", ] -item_moving_thumbnail = [ - "movingThumbnail", - "thumbnails", - 0, - "url" -] - - class VideoInfo: ''' VideoInfo object retrieves YouTube video information. @@ -88,7 +80,7 @@ class VideoInfo: Occurs when video_id does not exist on YouTube. ''' - def __init__(self, video_id, session=None): + def __init__(self, video_id, session:requests.Session = None): if session: self.session = session else: @@ -100,16 +92,17 @@ class VideoInfo: def _get_page_text(self, video_id): url = f"https://www.youtube.com/embed/{video_id}" - resp = self.session.get(url, headers=headers) + resp = self.session.get(url) resp.raise_for_status() return resp.text def _parse(self, text): result = re.search(pattern, text) - res = json.loads(result.group(1)) - response = self._get_item(res, item_response) + self._res = json.loads(result.group(1)) + response = self._get_item(self._res, item_response) if response is None: - self._check_video_is_private(res.get("args")) + self._check_video_is_private(self._res.get("args")) + self._renderer = self._get_item(json.loads(response), item_renderer) if self._renderer is None: raise InvalidVideoIdException( @@ -151,26 +144,51 @@ class VideoInfo: for run in self._renderer["title"]["runs"]][0] return None + def get_title_escaped(self): + return self._no_emoji(self.get_title()) + def get_channel_id(self): channel_url = self._get_item(self._renderer, item_channel_id) if channel_url: return channel_url[9:] return None - def get_owner_image(self): - return self._get_item(self._renderer, item_owner_image) - def get_thumbnail(self): return self._get_item(self._renderer, item_thumbnail) - def get_channel_name(self): - return self._get_item(self._renderer, item_channel_name) + def get_owner_image(self): + return self._get_item(self._renderer, item_owner_image) - def get_username(self): - return self._get_item(self._renderer, item_username) + def get_owner_name(self): + return self._get_item(self._renderer, item_owner_name) - def get_userimage(self): - return self._get_item(self._renderer, item_userimage) - - def get_moving_thumbnail(self): - return self._get_item(self._renderer, item_moving_thumbnail) + def get_owner_name_escaped(self): + return self._no_emoji(self.get_owner_name()) + + def get_user_name(self): + return self._get_item(self._res, item_user_name) + + def get_user_name_escaped(self): + return self._no_emoji(self.get_user_name()) + + def get_user_image(self): + return self._get_item(self._res, item_user_image) + + def _no_emoji(self, text:str): + if text is None: + return None + return ''.join(c for c in text + if c not in emoji.UNICODE_EMOJI) + +def get_info(video_id:str, session:requests.Session = None) -> VideoInfo: + """ + Paaramters + ---------- + video_id : str : + video_id + + session : requests.Session + session object + """ + + return VideoInfo(video_id = video_id, session = session)