...
This commit is contained in:
142
lib/clients/vimeo/client.py
Normal file
142
lib/clients/vimeo/client.py
Normal file
@@ -0,0 +1,142 @@
|
||||
import os
|
||||
from typing import List, Optional
|
||||
|
||||
import requests
|
||||
import vimeo
|
||||
from model_video import VideoInfo, video_model_load, videos_model_load
|
||||
|
||||
|
||||
class VimeoClient:
|
||||
def __init__(self):
|
||||
# Retrieve necessary credentials from environment variables
|
||||
self.client_id = os.getenv("VIMEO_CLIENT_ID")
|
||||
self.client_secret = os.getenv("VIMEO_SECRET")
|
||||
self.access_token = os.getenv("VIMEO_ACCESSTOKEN_ID")
|
||||
self.user_id = os.getenv("VIMEO_USER_ID")
|
||||
|
||||
# Check if all environment variables are present
|
||||
if not all([self.client_id, self.client_secret, self.access_token, self.user_id]):
|
||||
raise EnvironmentError(
|
||||
"Please set the VIMEO_CLIENT_ID, VIMEO_SECRET,VIMEO_USER_ID and VIMEO_ACCESSTOKEN_ID environment variables."
|
||||
)
|
||||
|
||||
# Initialize the Vimeo client
|
||||
self.client = vimeo.VimeoClient(token=self.access_token, key=self.client_id, secret=self.client_secret)
|
||||
|
||||
def upload(self, file: str, video_title: str, description: str) -> str:
|
||||
video_uri = self.client.upload(file, data={"name": video_title, "description": description})
|
||||
return video_uri
|
||||
|
||||
def download(self, video_id: str, output_file: str = "myvid.mp4"):
|
||||
info = self.get_video_info(video_id)
|
||||
|
||||
size, link = 0, ""
|
||||
for item in info.download:
|
||||
if item["size"] > size:
|
||||
size = item["size"]
|
||||
link = item["link"]
|
||||
|
||||
if link == "":
|
||||
raise Exception("download link not provided for video")
|
||||
|
||||
video_response = requests.get(link, stream=True)
|
||||
downloaded_mb = 0
|
||||
with open(output_file, "wb") as video_file:
|
||||
for chunk in video_response.iter_content(chunk_size=1024):
|
||||
if chunk:
|
||||
downloaded_mb += len(chunk) / 1024
|
||||
print(f"{downloaded_mb}MB Downloaded...")
|
||||
video_file.write(chunk)
|
||||
|
||||
print(f"Video downloaded successfully to {output_file}!")
|
||||
|
||||
def get_video_info(self, video_id: str) -> VideoInfo:
|
||||
"""
|
||||
Get information about a video by URI.
|
||||
:param uri: URI of the Vimeo video.
|
||||
:return: Video information as a dictionary, or None if an error occurs.
|
||||
"""
|
||||
# , fields: List[str]
|
||||
response = self.client.get(f"/videos/{video_id}")
|
||||
if response.status_code == 200:
|
||||
myvideo = video_model_load(response.content)
|
||||
else:
|
||||
raise Exception(f"Failed to get video details. Status code: {response.status_code}, Error: {response.text}")
|
||||
return myvideo
|
||||
|
||||
def get_videos(self, folder: Optional[int] = None, folders: Optional[List[int]] = None) -> List[VideoInfo]:
|
||||
"""
|
||||
Get information about videos from specified folder(s) or all videos if no folder is specified.
|
||||
:param folder: ID of a single folder to fetch videos from.
|
||||
:param folders: List of folder IDs to fetch videos from.
|
||||
:return: List of VideoInfo objects.
|
||||
"""
|
||||
if self.user_id == 0:
|
||||
raise Exception("Can't find user ID, it's not set in env variables")
|
||||
|
||||
all_videos = []
|
||||
|
||||
if folder is not None:
|
||||
folders = [folder]
|
||||
elif folders is None:
|
||||
# If no folder or folders specified, get all videos
|
||||
response = self.client.get("/me/videos")
|
||||
if response.status_code == 200:
|
||||
return videos_model_load(response.content)
|
||||
else:
|
||||
raise Exception(f"Failed to get videos. Status code: {response.status_code}, Error: {response.text}")
|
||||
for folder_id in folders:
|
||||
response = self.client.get(f"/users/{self.user_id}/projects/{folder_id}/videos")
|
||||
if response.status_code == 200:
|
||||
videos = videos_model_load(response.content)
|
||||
all_videos.extend(videos)
|
||||
else:
|
||||
print(f"Failed to get videos for folder {folder_id}. Status code: {response.status_code}, Error: {response.text}")
|
||||
|
||||
return all_videos
|
||||
|
||||
# def get_videos(self,folder:int,folders:List[int]) -> List[VideoInfo]:
|
||||
# """
|
||||
# Get information about a video by URI.
|
||||
# :param uri: URI of the Vimeo video.
|
||||
# :return: Video information as a dictionary, or None if an error occurs.
|
||||
# """
|
||||
# if folder>0:
|
||||
# if self.user_id == 0:
|
||||
# return Exception("can't find userid, its not set in env variables")
|
||||
# # print(f"folderid:{folder}")
|
||||
# response = self.client.get(f"/users/{self.user_id}/projects/{folder}/videos")
|
||||
# # api_url = f"https://api.vimeo.com/users/{self.user_id}/projects/13139570/videos"
|
||||
# # print(api_url)
|
||||
# # access_token = "e65daca3b0dbc18c2fadc5cafcf81004"
|
||||
# # headers = {
|
||||
# # "Authorization": f"Bearer {access_token}"
|
||||
# # }
|
||||
# # Make the GET request to the Vimeo API
|
||||
# #response = requests.get(api_url, headers=headers)
|
||||
# else:
|
||||
# response = self.client.get(f"/me/videos/")
|
||||
|
||||
# if response.status_code == 200:
|
||||
# myvideos = videos_model_load(response.content)
|
||||
# else:
|
||||
# raise Exception(f"Failed to get video details. Status code: {response.status_code}, Error: {response.text}")
|
||||
# return myvideos
|
||||
|
||||
|
||||
def new() -> VimeoClient:
|
||||
return VimeoClient()
|
||||
|
||||
|
||||
# Example usage:
|
||||
if __name__ == "__main__":
|
||||
cl = new()
|
||||
v = cl.get_videos(folders=[10700101, 13139570, 12926235, 10752310, 10702046])
|
||||
for item in v:
|
||||
video_id = item.uri.split("/")[-1]
|
||||
print(f" - {item.name} : {video_id} ")
|
||||
# from IPython import embed; embed()
|
||||
# s
|
||||
# vi=cl.get_video_info("475353425")
|
||||
# print(json_to_yaml(vi))
|
||||
# cl.download("475353425", "/tmp/475353425.mp4")
|
177
lib/clients/vimeo/model_video.py
Normal file
177
lib/clients/vimeo/model_video.py
Normal file
@@ -0,0 +1,177 @@
|
||||
from dataclasses import dataclass, field
|
||||
from typing import List, Optional, Dict, Any
|
||||
from dataclasses_json import dataclass_json
|
||||
import json
|
||||
import yaml
|
||||
|
||||
def json_to_yaml(json_data):
|
||||
# If the input is a JSON string, parse it into a Python dictionary
|
||||
if isinstance(json_data, str):
|
||||
json_data = json.loads(json_data)
|
||||
|
||||
# Convert the dictionary to a YAML formatted string
|
||||
yaml_data = yaml.dump(json_data, sort_keys=False, default_flow_style=False)
|
||||
|
||||
return yaml_data
|
||||
|
||||
|
||||
@dataclass_json
|
||||
@dataclass
|
||||
class Size:
|
||||
width: int
|
||||
height: int
|
||||
link: str
|
||||
link_with_play_button: Optional[str] = None
|
||||
|
||||
@dataclass_json
|
||||
@dataclass
|
||||
class Pictures:
|
||||
uri: str
|
||||
active: bool
|
||||
type: str
|
||||
base_link: str
|
||||
sizes: List[Size]
|
||||
resource_key: str
|
||||
default_picture: bool
|
||||
|
||||
@dataclass_json
|
||||
@dataclass
|
||||
class Embed:
|
||||
html: str
|
||||
badges: Dict[str, Any]
|
||||
interactive: bool
|
||||
buttons: Dict[str, bool]
|
||||
logos: Dict[str, Any]
|
||||
play_button: Dict[str, Any]
|
||||
title: Dict[str, Any]
|
||||
end_screen: List[Any]
|
||||
playbar: bool
|
||||
quality_selector: Optional[str]
|
||||
pip: bool
|
||||
autopip: bool
|
||||
volume: bool
|
||||
color: str
|
||||
colors: Dict[str, str]
|
||||
event_schedule: bool
|
||||
has_cards: bool
|
||||
outro_type: str
|
||||
show_timezone: bool
|
||||
cards: List[Any]
|
||||
airplay: bool
|
||||
audio_tracks: bool
|
||||
chapters: bool
|
||||
chromecast: bool
|
||||
closed_captions: bool
|
||||
transcript: bool
|
||||
ask_ai: bool
|
||||
uri: Optional[str]
|
||||
email_capture_form: Optional[str]
|
||||
speed: bool
|
||||
|
||||
@dataclass_json
|
||||
@dataclass
|
||||
class Uploader:
|
||||
pictures: Pictures
|
||||
|
||||
@dataclass_json
|
||||
@dataclass
|
||||
class User:
|
||||
uri: str
|
||||
name: str
|
||||
link: str
|
||||
capabilities: Dict[str, bool]
|
||||
location: str
|
||||
gender: str
|
||||
bio: str
|
||||
short_bio: str
|
||||
created_time: str
|
||||
pictures: Pictures
|
||||
websites: List[Dict[str, Optional[str]]]
|
||||
#metadata: Dict[str, Any]
|
||||
location_details: Dict[str, Optional[Any]]
|
||||
skills: List[Any]
|
||||
available_for_hire: bool
|
||||
can_work_remotely: bool
|
||||
preferences: Dict[str, Any]
|
||||
content_filter: List[str]
|
||||
upload_quota: Dict[str, Any]
|
||||
resource_key: str
|
||||
account: str
|
||||
|
||||
@dataclass_json
|
||||
@dataclass
|
||||
class VideoInfo:
|
||||
uri: str
|
||||
name: str
|
||||
description: Optional[str]
|
||||
type: str
|
||||
link: str
|
||||
player_embed_url: str
|
||||
duration: int
|
||||
width: int
|
||||
height: int
|
||||
#embed: Embed
|
||||
created_time: str
|
||||
modified_time: str
|
||||
release_time: str
|
||||
content_rating: List[str]
|
||||
content_rating_class: str
|
||||
rating_mod_locked: bool
|
||||
license: Optional[str]
|
||||
privacy: Dict[str, Any]
|
||||
pictures: Pictures
|
||||
tags: List[Any]
|
||||
stats: Dict[str, int]
|
||||
categories: List[Any]
|
||||
uploader: Uploader
|
||||
#metadata: Dict[str, Any]
|
||||
manage_link: str
|
||||
#user: Optional[User]
|
||||
last_user_action_event_date: Optional[str]
|
||||
parent_folder: Optional[Dict[str, Any]]
|
||||
review_page: Optional[Dict[str, Any]]
|
||||
files: Optional[List[Dict[str, Any]]]
|
||||
download: Optional[List[Dict[str, Any]]]
|
||||
app: Optional[Dict[str, str]]
|
||||
play: Optional[Dict[str, Any]]
|
||||
status: str
|
||||
resource_key: str
|
||||
upload: Optional[Dict[str, Optional[str]]]
|
||||
transcode: Dict[str, str]
|
||||
is_playable: bool
|
||||
has_audio: bool
|
||||
|
||||
|
||||
def video_model_load(json_data:str,dojsonload:bool=True) -> VideoInfo:
|
||||
|
||||
if dojsonload:
|
||||
json_dict = json.loads(json_data)
|
||||
else:
|
||||
json_dict = json_data
|
||||
|
||||
json_dict.pop('metadata', {})
|
||||
json_dict.pop('embed', {})
|
||||
json_dict.pop('user', {})
|
||||
json_dict.pop('websites', {})
|
||||
# if 'user' in json_dict:
|
||||
# json_dict['user'].pop('metadata', None)
|
||||
# if 'websites' in json_dict:
|
||||
# json_dict['websites'].pop('metadata', None)
|
||||
|
||||
|
||||
json_data_cleaned = json.dumps(json_dict)
|
||||
|
||||
video_object = VideoInfo.from_json(json_data_cleaned)
|
||||
|
||||
return video_object
|
||||
|
||||
|
||||
def videos_model_load(json_data:str) -> List[VideoInfo]:
|
||||
json_list = json.loads(json_data)
|
||||
json_list2= list()
|
||||
|
||||
for item in json_list["data"]:
|
||||
d=video_model_load(item,dojsonload=False)
|
||||
json_list2.append(d)
|
||||
|
||||
return json_list2
|
Reference in New Issue
Block a user