qdown 1.0.3__py3-none-any.whl → 1.0.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qdown/__init__.py +3 -3
 - qdown/qdown.py +107 -0
 - {qdown-1.0.3.dist-info → qdown-1.0.4.dist-info}/METADATA +3 -1
 - qdown-1.0.4.dist-info/RECORD +10 -0
 - qdown-1.0.3.dist-info/RECORD +0 -10
 - {qdown-1.0.3.dist-info → qdown-1.0.4.dist-info}/WHEEL +0 -0
 - {qdown-1.0.3.dist-info → qdown-1.0.4.dist-info}/entry_points.txt +0 -0
 - {qdown-1.0.3.dist-info → qdown-1.0.4.dist-info}/top_level.txt +0 -0
 
    
        qdown/__init__.py
    CHANGED
    
    | 
         @@ -75,9 +75,9 @@ def download(download_url, output_path=None, output_dir=None, server_url="https: 
     | 
|
| 
       75 
75 
     | 
    
         
             
                # QDownクライアントの初期化
         
     | 
| 
       76 
76 
     | 
    
         
             
                client = QDown(server_url=server_url, quiet=quiet)
         
     | 
| 
       77 
77 
     | 
    
         | 
| 
       78 
     | 
    
         
            -
                #  
     | 
| 
       79 
     | 
    
         
            -
                return  
     | 
| 
      
 78 
     | 
    
         
            +
                # 同期版メソッドを呼び出す
         
     | 
| 
      
 79 
     | 
    
         
            +
                return client.download_by_file_id_sync(
         
     | 
| 
       80 
80 
     | 
    
         
             
                    file_id=file_id,
         
     | 
| 
       81 
81 
     | 
    
         
             
                    output=output_path,
         
     | 
| 
       82 
82 
     | 
    
         
             
                    output_dir=output_dir
         
     | 
| 
       83 
     | 
    
         
            -
                ) 
     | 
| 
      
 83 
     | 
    
         
            +
                )
         
     | 
    
        qdown/qdown.py
    CHANGED
    
    | 
         @@ -147,6 +147,113 @@ class QDown: 
     | 
|
| 
       147 
147 
     | 
    
         
             
                            print(f"エラー: {e}", file=sys.stderr)
         
     | 
| 
       148 
148 
     | 
    
         
             
                            return None
         
     | 
| 
       149 
149 
     | 
    
         | 
| 
      
 150 
     | 
    
         
            +
                def download_by_file_id_sync(self, file_id, output=None, output_dir=None):
         
     | 
| 
      
 151 
     | 
    
         
            +
                    """
         
     | 
| 
      
 152 
     | 
    
         
            +
                    ファイルIDを指定してファイルをダウンロード(同期版)
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                    Args:
         
     | 
| 
      
 155 
     | 
    
         
            +
                        file_id (str): ダウンロードするファイルのID (qd_id)
         
     | 
| 
      
 156 
     | 
    
         
            +
                        output (str, optional): 出力ファイル名
         
     | 
| 
      
 157 
     | 
    
         
            +
                        output_dir (str, optional): 出力ディレクトリ
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
                    Returns:
         
     | 
| 
      
 160 
     | 
    
         
            +
                        str: ダウンロードしたファイルのパス
         
     | 
| 
      
 161 
     | 
    
         
            +
                    """
         
     | 
| 
      
 162 
     | 
    
         
            +
                    url = f"{self.server_url}/download/{file_id}"
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
                    # 出力ディレクトリの設定
         
     | 
| 
      
 165 
     | 
    
         
            +
                    if output_dir:
         
     | 
| 
      
 166 
     | 
    
         
            +
                        os.makedirs(output_dir, exist_ok=True)
         
     | 
| 
      
 167 
     | 
    
         
            +
                    else:
         
     | 
| 
      
 168 
     | 
    
         
            +
                        output_dir = "."
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
                    with httpx.Client(timeout=self.timeout) as client:
         
     | 
| 
      
 171 
     | 
    
         
            +
                        # まず、ヘッド要求を送信してファイル情報を取得
         
     | 
| 
      
 172 
     | 
    
         
            +
                        try:
         
     | 
| 
      
 173 
     | 
    
         
            +
                            head_response = client.head(url)
         
     | 
| 
      
 174 
     | 
    
         
            +
             
     | 
| 
      
 175 
     | 
    
         
            +
                            if head_response.status_code == 404:
         
     | 
| 
      
 176 
     | 
    
         
            +
                                print(f"エラー: ID '{file_id}' のファイルが見つかりませんでした", file=sys.stderr)
         
     | 
| 
      
 177 
     | 
    
         
            +
                                return None
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
      
 179 
     | 
    
         
            +
                            if head_response.status_code != 200:
         
     | 
| 
      
 180 
     | 
    
         
            +
                                print(f"エラー: ステータスコード {head_response.status_code}", file=sys.stderr)
         
     | 
| 
      
 181 
     | 
    
         
            +
                                return None
         
     | 
| 
      
 182 
     | 
    
         
            +
             
     | 
| 
      
 183 
     | 
    
         
            +
                            # Content-Dispositionヘッダーからファイル名を取得
         
     | 
| 
      
 184 
     | 
    
         
            +
                            original_filename = None
         
     | 
| 
      
 185 
     | 
    
         
            +
                            if "content-disposition" in head_response.headers:
         
     | 
| 
      
 186 
     | 
    
         
            +
                                cd = head_response.headers["content-disposition"]
         
     | 
| 
      
 187 
     | 
    
         
            +
                                if "filename=" in cd:
         
     | 
| 
      
 188 
     | 
    
         
            +
                                    # 安全なファイル名を抽出(URLエンコードの解除)
         
     | 
| 
      
 189 
     | 
    
         
            +
                                    filename_part = cd.split("filename=")[1].strip('"')
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
      
 191 
     | 
    
         
            +
                                    # filename*=UTF-8 形式のエンコードがある場合
         
     | 
| 
      
 192 
     | 
    
         
            +
                                    if "filename*=UTF-8''" in cd:
         
     | 
| 
      
 193 
     | 
    
         
            +
                                        encoded_part = cd.split("filename*=UTF-8''")[1]
         
     | 
| 
      
 194 
     | 
    
         
            +
                                        # セミコロンやダブルクォートがあれば処理
         
     | 
| 
      
 195 
     | 
    
         
            +
                                        if '"' in encoded_part:
         
     | 
| 
      
 196 
     | 
    
         
            +
                                            encoded_part = encoded_part.split('"')[0]
         
     | 
| 
      
 197 
     | 
    
         
            +
                                        if ';' in encoded_part:
         
     | 
| 
      
 198 
     | 
    
         
            +
                                            encoded_part = encoded_part.split(';')[0]
         
     | 
| 
      
 199 
     | 
    
         
            +
                                        # URLデコードして正しいファイル名を取得
         
     | 
| 
      
 200 
     | 
    
         
            +
                                        original_filename = urllib.parse.unquote(encoded_part)
         
     | 
| 
      
 201 
     | 
    
         
            +
                                    else:
         
     | 
| 
      
 202 
     | 
    
         
            +
                                        # 通常のファイル名(エスケープ処理)
         
     | 
| 
      
 203 
     | 
    
         
            +
                                        original_filename = filename_part.replace('"', '').split(';')[0]
         
     | 
| 
      
 204 
     | 
    
         
            +
             
     | 
| 
      
 205 
     | 
    
         
            +
                            # 保存用のファイル名を決定
         
     | 
| 
      
 206 
     | 
    
         
            +
                            if not output:
         
     | 
| 
      
 207 
     | 
    
         
            +
                                if original_filename:
         
     | 
| 
      
 208 
     | 
    
         
            +
                                    # パスとして安全なファイル名に変換
         
     | 
| 
      
 209 
     | 
    
         
            +
                                    safe_filename = os.path.basename(original_filename)
         
     | 
| 
      
 210 
     | 
    
         
            +
                                    output_filename = safe_filename
         
     | 
| 
      
 211 
     | 
    
         
            +
                                else:
         
     | 
| 
      
 212 
     | 
    
         
            +
                                    output_filename = f"download_{file_id}"
         
     | 
| 
      
 213 
     | 
    
         
            +
                            else:
         
     | 
| 
      
 214 
     | 
    
         
            +
                                output_filename = output
         
     | 
| 
      
 215 
     | 
    
         
            +
             
     | 
| 
      
 216 
     | 
    
         
            +
                            file_path = os.path.join(output_dir, output_filename)
         
     | 
| 
      
 217 
     | 
    
         
            +
             
     | 
| 
      
 218 
     | 
    
         
            +
                            # ファイルサイズを取得(プログレスバー用)
         
     | 
| 
      
 219 
     | 
    
         
            +
                            total_size = int(head_response.headers.get("content-length", 0))
         
     | 
| 
      
 220 
     | 
    
         
            +
             
     | 
| 
      
 221 
     | 
    
         
            +
                            # ストリーミングダウンロードを開始
         
     | 
| 
      
 222 
     | 
    
         
            +
                            with client.stream("GET", url) as response:
         
     | 
| 
      
 223 
     | 
    
         
            +
                                if response.status_code != 200:
         
     | 
| 
      
 224 
     | 
    
         
            +
                                    print(f"エラー: ダウンロード中にエラーが発生しました。ステータスコード: {response.status_code}", file=sys.stderr)
         
     | 
| 
      
 225 
     | 
    
         
            +
                                    return None
         
     | 
| 
      
 226 
     | 
    
         
            +
             
     | 
| 
      
 227 
     | 
    
         
            +
                                with open(file_path, "wb") as f:
         
     | 
| 
      
 228 
     | 
    
         
            +
                                    if not self.quiet and total_size > 0:
         
     | 
| 
      
 229 
     | 
    
         
            +
                                        progress_bar = tqdm(
         
     | 
| 
      
 230 
     | 
    
         
            +
                                            total=total_size,
         
     | 
| 
      
 231 
     | 
    
         
            +
                                            unit="B",
         
     | 
| 
      
 232 
     | 
    
         
            +
                                            unit_scale=True,
         
     | 
| 
      
 233 
     | 
    
         
            +
                                            desc=f"ダウンロード中: {output_filename}"
         
     | 
| 
      
 234 
     | 
    
         
            +
                                        )
         
     | 
| 
      
 235 
     | 
    
         
            +
             
     | 
| 
      
 236 
     | 
    
         
            +
                                    downloaded = 0
         
     | 
| 
      
 237 
     | 
    
         
            +
             
     | 
| 
      
 238 
     | 
    
         
            +
                                    for chunk in response.iter_bytes():
         
     | 
| 
      
 239 
     | 
    
         
            +
                                        f.write(chunk)
         
     | 
| 
      
 240 
     | 
    
         
            +
                                        if not self.quiet and total_size > 0:
         
     | 
| 
      
 241 
     | 
    
         
            +
                                            downloaded += len(chunk)
         
     | 
| 
      
 242 
     | 
    
         
            +
                                            progress_bar.update(len(chunk))
         
     | 
| 
      
 243 
     | 
    
         
            +
             
     | 
| 
      
 244 
     | 
    
         
            +
                                    if not self.quiet and total_size > 0:
         
     | 
| 
      
 245 
     | 
    
         
            +
                                        progress_bar.close()
         
     | 
| 
      
 246 
     | 
    
         
            +
             
     | 
| 
      
 247 
     | 
    
         
            +
                            if not self.quiet:
         
     | 
| 
      
 248 
     | 
    
         
            +
                                print(f"[qdown] ファイルを保存しました: {file_path}")
         
     | 
| 
      
 249 
     | 
    
         
            +
                            return file_path
         
     | 
| 
      
 250 
     | 
    
         
            +
             
     | 
| 
      
 251 
     | 
    
         
            +
                        except httpx.RequestError as e:
         
     | 
| 
      
 252 
     | 
    
         
            +
                            print(f"エラー: リクエストに失敗しました - {e}", file=sys.stderr)
         
     | 
| 
      
 253 
     | 
    
         
            +
                            return None
         
     | 
| 
      
 254 
     | 
    
         
            +
                        except Exception as e:
         
     | 
| 
      
 255 
     | 
    
         
            +
                            print(f"エラー: {e}", file=sys.stderr)
         
     | 
| 
      
 256 
     | 
    
         
            +
                            return None
         
     | 
| 
       150 
257 
     | 
    
         | 
| 
       151 
258 
     | 
    
         
             
            def main():
         
     | 
| 
       152 
259 
     | 
    
         
             
                parser = argparse.ArgumentParser(
         
     | 
| 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            Metadata-Version: 2.1
         
     | 
| 
       2 
2 
     | 
    
         
             
            Name: qdown
         
     | 
| 
       3 
     | 
    
         
            -
            Version: 1.0. 
     | 
| 
      
 3 
     | 
    
         
            +
            Version: 1.0.4
         
     | 
| 
       4 
4 
     | 
    
         
             
            Summary: Client for QualitegDrive
         
     | 
| 
       5 
5 
     | 
    
         
             
            Home-page: https://github.com/qualiteg/qdown
         
     | 
| 
       6 
6 
     | 
    
         
             
            Author: Qualiteg Inc.
         
     | 
| 
         @@ -22,6 +22,8 @@ Requires-Dist: tqdm (>=4.64.0) 
     | 
|
| 
       22 
22 
     | 
    
         | 
| 
       23 
23 
     | 
    
         
             
            A Python client for downloading files from QualitegDrive operated by Qualiteg Inc.
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
      
 25 
     | 
    
         
            +
            [Japanese](README.ja.md)
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
       25 
27 
     | 
    
         
             
            # install
         
     | 
| 
       26 
28 
     | 
    
         | 
| 
       27 
29 
     | 
    
         
             
            ```
         
     | 
| 
         @@ -0,0 +1,10 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            qdown/__init__.py,sha256=rNxBW4Zo6nfWYN2JnLwJVpyGEX3RtBjoE7QlSy0FcxU,2975
         
     | 
| 
      
 2 
     | 
    
         
            +
            qdown/gdown.py,sha256=3MpnwlBpEFGi1rdAMzixdBETtw8q5xItaHU1QmtPrEo,6421
         
     | 
| 
      
 3 
     | 
    
         
            +
            qdown/qdown.py,sha256=KeU9DN9LdDQwhoPZfDVDz51TlFnjWYUxUpJz8-DtBKI,12432
         
     | 
| 
      
 4 
     | 
    
         
            +
            z_examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         
     | 
| 
      
 5 
     | 
    
         
            +
            z_examples/example.py,sha256=3FQoW22Frgyx5ulb7JOgwgcEBd8K3FI_BuFZP2E54ck,137
         
     | 
| 
      
 6 
     | 
    
         
            +
            qdown-1.0.4.dist-info/METADATA,sha256=CVbfXYkssfEtEkbmRxs2Z-zmgUDAPsdd9DmbIZvm4cM,1515
         
     | 
| 
      
 7 
     | 
    
         
            +
            qdown-1.0.4.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
         
     | 
| 
      
 8 
     | 
    
         
            +
            qdown-1.0.4.dist-info/entry_points.txt,sha256=4uunDwX_8iGbNA0DKwggOftuKUXvoHxGzvXUd2SW9LM,43
         
     | 
| 
      
 9 
     | 
    
         
            +
            qdown-1.0.4.dist-info/top_level.txt,sha256=eVEHrbec1mx2PWv03GzKwFTbdvQqFOAps3GuveF2Ap8,17
         
     | 
| 
      
 10 
     | 
    
         
            +
            qdown-1.0.4.dist-info/RECORD,,
         
     | 
    
        qdown-1.0.3.dist-info/RECORD
    DELETED
    
    | 
         @@ -1,10 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            qdown/__init__.py,sha256=iAC1eU57pgDdmgWVyu2MdOddLXcel2BxR5fH7m2OImg,2983
         
     | 
| 
       2 
     | 
    
         
            -
            qdown/gdown.py,sha256=3MpnwlBpEFGi1rdAMzixdBETtw8q5xItaHU1QmtPrEo,6421
         
     | 
| 
       3 
     | 
    
         
            -
            qdown/qdown.py,sha256=NJhqUCgceCd9ojSQCbNuOdNOAVKJywKv_kYohpQblYg,7309
         
     | 
| 
       4 
     | 
    
         
            -
            z_examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         
     | 
| 
       5 
     | 
    
         
            -
            z_examples/example.py,sha256=3FQoW22Frgyx5ulb7JOgwgcEBd8K3FI_BuFZP2E54ck,137
         
     | 
| 
       6 
     | 
    
         
            -
            qdown-1.0.3.dist-info/METADATA,sha256=5_W60o0W3VTDOfhj-zDjDDB4xXZhKU-1BcJYYosai5k,1487
         
     | 
| 
       7 
     | 
    
         
            -
            qdown-1.0.3.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
         
     | 
| 
       8 
     | 
    
         
            -
            qdown-1.0.3.dist-info/entry_points.txt,sha256=4uunDwX_8iGbNA0DKwggOftuKUXvoHxGzvXUd2SW9LM,43
         
     | 
| 
       9 
     | 
    
         
            -
            qdown-1.0.3.dist-info/top_level.txt,sha256=eVEHrbec1mx2PWv03GzKwFTbdvQqFOAps3GuveF2Ap8,17
         
     | 
| 
       10 
     | 
    
         
            -
            qdown-1.0.3.dist-info/RECORD,,
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     |