...
This commit is contained in:
		
							
								
								
									
										0
									
								
								herolib/clients/vimeo/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								herolib/clients/vimeo/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										142
									
								
								herolib/clients/vimeo/client.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								herolib/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
									
								
								herolib/clients/vimeo/model_video.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								herolib/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