qdown 1.0.0__tar.gz → 1.0.3__tar.gz

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-1.0.3/PKG-INFO ADDED
@@ -0,0 +1,68 @@
1
+ Metadata-Version: 2.1
2
+ Name: qdown
3
+ Version: 1.0.3
4
+ Summary: Client for QualitegDrive
5
+ Home-page: https://github.com/qualiteg/qdown
6
+ Author: Qualiteg Inc.
7
+ Author-email: qualiteger@qualiteg.com
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.7
13
+ Classifier: Programming Language :: Python :: 3.8
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Requires-Python: >=3.7
17
+ Description-Content-Type: text/markdown
18
+
19
+ # qdown
20
+
21
+ A Python client for downloading files from QualitegDrive operated by Qualiteg Inc.
22
+
23
+ # install
24
+
25
+ ```
26
+ pip install qdown
27
+ ```
28
+
29
+ or
30
+
31
+ ```
32
+ pip install git+https://github.com/qualiteg/qdown.git
33
+ ```
34
+
35
+ # usage
36
+
37
+ ```
38
+
39
+ qdown ID [options]
40
+
41
+ Options:
42
+ -O FILENAME Specify output filename
43
+ -o DIR Specify output directory
44
+ -s SERVER Specify server URL (default: https://drive.qualiteg.com)
45
+ -q, --quiet Hide progress display
46
+ -h, --help Display help
47
+ ```
48
+
49
+ ## download example1
50
+
51
+ ```
52
+ qdown xxxxxxxxxxxxx -O my_file.txt
53
+ ```
54
+
55
+ ## download example2
56
+
57
+ From Your Original HTTP Server
58
+
59
+ ```
60
+ qdown xxxxxxxxxxxxx -O my_file.txt -s http://host.docker.internal:3000
61
+ ```
62
+
63
+
64
+ # uninstall
65
+
66
+ ```
67
+ pip uninstall qdown -y
68
+ ```
@@ -31,7 +31,7 @@ Options:
31
31
  ## download example1
32
32
 
33
33
  ```
34
- gdown xxxxxxxxxxxxx -O my_file.txt
34
+ qdown xxxxxxxxxxxxx -O my_file.txt
35
35
  ```
36
36
 
37
37
  ## download example2
@@ -39,7 +39,7 @@ gdown xxxxxxxxxxxxx -O my_file.txt
39
39
  From Your Original HTTP Server
40
40
 
41
41
  ```
42
- gdown xxxxxxxxxxxxx -O my_file.txt -s http://host.docker.internal:3000
42
+ qdown xxxxxxxxxxxxx -O my_file.txt -s http://host.docker.internal:3000
43
43
  ```
44
44
 
45
45
 
@@ -0,0 +1,83 @@
1
+ """
2
+
3
+ Copyright (c) 2023 Qualiteg Inc. all rights reserved.
4
+
5
+ This program is dual-licensed under the terms of the:
6
+ 1) GNU Affero General Public License, version 3, or any later version.
7
+ 2) A commercial license agreement provided by Qualiteg Inc.
8
+
9
+ If you choose to use or redistribute this program under the terms of AGPLv3:
10
+ This program is free software: you can redistribute it and/or modify
11
+ it under the terms of the GNU Affero General Public License as
12
+ published by the Free Software Foundation, either version 3 of the
13
+ License, or (at your option) any later version.
14
+ This program is distributed in the hope that it will be useful,
15
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ GNU Affero General Public License for more details.
18
+ You should have received a copy of the GNU Affero General Public License
19
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
20
+
21
+ If you wish to use or redistribute this program under a commercial license:
22
+ Please contact Qualiteg Inc.(https://qualiteg.com/contact) directly to obtain the terms and pricing.
23
+
24
+ """
25
+
26
+ import asyncio
27
+ import re
28
+ from .qdown import QDown
29
+
30
+
31
+ def extract_file_id(url):
32
+ """
33
+ URLからファイルIDを抽出する
34
+
35
+ Args:
36
+ url (str): ファイルURL
37
+ 例1: https://drive.qualiteg.com/file/3kMM-X9S6-bMioFU0Fn8nHjAgQgWmG
38
+ 例2: https://drive.qualiteg.com/download/1Lki-o8QO-DCUmg60JRxGdXfif
39
+
40
+ Returns:
41
+ str: ファイルID
42
+ """
43
+ # /file/XXX 形式のURL
44
+ file_pattern = r'https://drive\.qualiteg\.com/file/([a-zA-Z0-9_-]+)'
45
+ file_match = re.search(file_pattern, url)
46
+ if file_match:
47
+ return file_match.group(1)
48
+
49
+ # /download/XXX 形式のURL
50
+ download_pattern = r'https://drive\.qualiteg\.com/download/([a-zA-Z0-9_-]+)'
51
+ download_match = re.search(download_pattern, url)
52
+ if download_match:
53
+ return download_match.group(1)
54
+
55
+ return url # IDと思われる場合はそのまま返す
56
+
57
+
58
+ def download(download_url, output_path=None, output_dir=None, server_url="https://drive.qualiteg.com", quiet=False):
59
+ """
60
+ URLを指定してファイルをダウンロード
61
+
62
+ Args:
63
+ download_url (str): ダウンロードURL or ファイルID
64
+ output_path (str, optional): 出力ファイルパス
65
+ output_dir (str, optional): 出力ディレクトリ
66
+ server_url (str, optional): サーバーURL
67
+ quiet (bool, optional): 進捗表示を非表示にするかどうか
68
+
69
+ Returns:
70
+ str: ダウンロードしたファイルのパス
71
+ """
72
+ # URLからファイルIDを抽出
73
+ file_id = extract_file_id(download_url)
74
+
75
+ # QDownクライアントの初期化
76
+ client = QDown(server_url=server_url, quiet=quiet)
77
+
78
+ # 非同期ダウンロードを実行
79
+ return asyncio.run(client.download_by_file_id(
80
+ file_id=file_id,
81
+ output=output_path,
82
+ output_dir=output_dir
83
+ ))
@@ -1,4 +1,3 @@
1
-
2
1
  """
3
2
  qdown - Client for QualitegDrive
4
3
 
@@ -18,6 +17,7 @@ import os
18
17
  import sys
19
18
  import argparse
20
19
  import asyncio
20
+ import urllib.parse
21
21
  from pathlib import Path
22
22
  from tqdm import tqdm
23
23
 
@@ -30,7 +30,7 @@ class QDown:
30
30
  def __init__(self, server_url="https://drive.qualiteg.com", quiet=False):
31
31
  """
32
32
  クライアントの初期化
33
-
33
+
34
34
  Args:
35
35
  server_url (str): ファイルサーバーのベースURL
36
36
  quiet (bool): 進捗表示を非表示にするかどうか
@@ -38,91 +38,108 @@ class QDown:
38
38
  self.server_url = server_url.rstrip('/')
39
39
  self.quiet = quiet
40
40
  self.timeout = httpx.Timeout(10.0, connect=60.0)
41
-
42
- async def download(self, file_id, output=None, output_dir=None):
41
+
42
+ async def download_by_file_id(self, file_id, output=None, output_dir=None):
43
43
  """
44
44
  ファイルIDを指定してファイルをダウンロード
45
-
45
+
46
46
  Args:
47
47
  file_id (str): ダウンロードするファイルのID (qd_id)
48
48
  output (str, optional): 出力ファイル名
49
49
  output_dir (str, optional): 出力ディレクトリ
50
-
50
+
51
51
  Returns:
52
52
  str: ダウンロードしたファイルのパス
53
53
  """
54
54
  url = f"{self.server_url}/download/{file_id}"
55
-
55
+
56
56
  # 出力ディレクトリの設定
57
57
  if output_dir:
58
58
  os.makedirs(output_dir, exist_ok=True)
59
59
  else:
60
60
  output_dir = "."
61
-
61
+
62
62
  async with httpx.AsyncClient(timeout=self.timeout) as client:
63
63
  # まず、ヘッド要求を送信してファイル情報を取得
64
64
  try:
65
65
  head_response = await client.head(url)
66
-
66
+
67
67
  if head_response.status_code == 404:
68
68
  print(f"エラー: ID '{file_id}' のファイルが見つかりませんでした", file=sys.stderr)
69
69
  return None
70
-
70
+
71
71
  if head_response.status_code != 200:
72
72
  print(f"エラー: ステータスコード {head_response.status_code}", file=sys.stderr)
73
73
  return None
74
-
74
+
75
75
  # Content-Dispositionヘッダーからファイル名を取得
76
76
  original_filename = None
77
77
  if "content-disposition" in head_response.headers:
78
78
  cd = head_response.headers["content-disposition"]
79
79
  if "filename=" in cd:
80
- original_filename = cd.split("filename=")[1].strip('"')
81
-
80
+ # 安全なファイル名を抽出(URLエンコードの解除)
81
+ filename_part = cd.split("filename=")[1].strip('"')
82
+
83
+ # filename*=UTF-8 形式のエンコードがある場合
84
+ if "filename*=UTF-8''" in cd:
85
+ encoded_part = cd.split("filename*=UTF-8''")[1]
86
+ # セミコロンやダブルクォートがあれば処理
87
+ if '"' in encoded_part:
88
+ encoded_part = encoded_part.split('"')[0]
89
+ if ';' in encoded_part:
90
+ encoded_part = encoded_part.split(';')[0]
91
+ # URLデコードして正しいファイル名を取得
92
+ original_filename = urllib.parse.unquote(encoded_part)
93
+ else:
94
+ # 通常のファイル名(エスケープ処理)
95
+ original_filename = filename_part.replace('"', '').split(';')[0]
96
+
82
97
  # 保存用のファイル名を決定
83
98
  if not output:
84
99
  if original_filename:
85
- output_filename = original_filename
100
+ # パスとして安全なファイル名に変換
101
+ safe_filename = os.path.basename(original_filename)
102
+ output_filename = safe_filename
86
103
  else:
87
104
  output_filename = f"download_{file_id}"
88
105
  else:
89
106
  output_filename = output
90
-
107
+
91
108
  file_path = os.path.join(output_dir, output_filename)
92
-
109
+
93
110
  # ファイルサイズを取得(プログレスバー用)
94
111
  total_size = int(head_response.headers.get("content-length", 0))
95
-
112
+
96
113
  # ストリーミングダウンロードを開始
97
114
  async with client.stream("GET", url) as response:
98
115
  if response.status_code != 200:
99
116
  print(f"エラー: ダウンロード中にエラーが発生しました。ステータスコード: {response.status_code}", file=sys.stderr)
100
117
  return None
101
-
118
+
102
119
  with open(file_path, "wb") as f:
103
120
  if not self.quiet and total_size > 0:
104
121
  progress_bar = tqdm(
105
- total=total_size,
106
- unit="B",
107
- unit_scale=True,
122
+ total=total_size,
123
+ unit="B",
124
+ unit_scale=True,
108
125
  desc=f"ダウンロード中: {output_filename}"
109
126
  )
110
-
127
+
111
128
  downloaded = 0
112
-
129
+
113
130
  async for chunk in response.aiter_bytes():
114
131
  f.write(chunk)
115
132
  if not self.quiet and total_size > 0:
116
133
  downloaded += len(chunk)
117
134
  progress_bar.update(len(chunk))
118
-
135
+
119
136
  if not self.quiet and total_size > 0:
120
137
  progress_bar.close()
121
-
138
+
122
139
  if not self.quiet:
123
- print(f"\nファイルを保存しました: {file_path}")
140
+ print(f"[qdown] ファイルを保存しました: {file_path}")
124
141
  return file_path
125
-
142
+
126
143
  except httpx.RequestError as e:
127
144
  print(f"エラー: リクエストに失敗しました - {e}", file=sys.stderr)
128
145
  return None
@@ -136,28 +153,28 @@ def main():
136
153
  description="qdown - IDベースファイルダウンロードツール",
137
154
  add_help=False
138
155
  )
139
-
156
+
140
157
  parser.add_argument("id", nargs="?", help="ダウンロードするファイルのID")
141
158
  parser.add_argument("-O", dest="output", help="出力ファイル名")
142
159
  parser.add_argument("-o", dest="output_dir", help="出力ディレクトリ")
143
160
  parser.add_argument("-s", dest="server", default="https://drive.qualiteg.com", help="サーバーURL")
144
161
  parser.add_argument("-q", "--quiet", action="store_true", help="進捗表示を非表示")
145
162
  parser.add_argument("-h", "--help", action="store_true", help="ヘルプを表示")
146
-
163
+
147
164
  args = parser.parse_args()
148
-
165
+
149
166
  if args.help or not args.id:
150
167
  print(__doc__)
151
168
  sys.exit(0)
152
-
169
+
153
170
  client = QDown(server_url=args.server, quiet=args.quiet)
154
-
155
- result = asyncio.run(client.download(
171
+
172
+ result = asyncio.run(client.download_by_file_id(
156
173
  file_id=args.id,
157
174
  output=args.output,
158
175
  output_dir=args.output_dir
159
176
  ))
160
-
177
+
161
178
  if result:
162
179
  sys.exit(0)
163
180
  else:
@@ -0,0 +1,68 @@
1
+ Metadata-Version: 2.1
2
+ Name: qdown
3
+ Version: 1.0.3
4
+ Summary: Client for QualitegDrive
5
+ Home-page: https://github.com/qualiteg/qdown
6
+ Author: Qualiteg Inc.
7
+ Author-email: qualiteger@qualiteg.com
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.7
13
+ Classifier: Programming Language :: Python :: 3.8
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Requires-Python: >=3.7
17
+ Description-Content-Type: text/markdown
18
+
19
+ # qdown
20
+
21
+ A Python client for downloading files from QualitegDrive operated by Qualiteg Inc.
22
+
23
+ # install
24
+
25
+ ```
26
+ pip install qdown
27
+ ```
28
+
29
+ or
30
+
31
+ ```
32
+ pip install git+https://github.com/qualiteg/qdown.git
33
+ ```
34
+
35
+ # usage
36
+
37
+ ```
38
+
39
+ qdown ID [options]
40
+
41
+ Options:
42
+ -O FILENAME Specify output filename
43
+ -o DIR Specify output directory
44
+ -s SERVER Specify server URL (default: https://drive.qualiteg.com)
45
+ -q, --quiet Hide progress display
46
+ -h, --help Display help
47
+ ```
48
+
49
+ ## download example1
50
+
51
+ ```
52
+ qdown xxxxxxxxxxxxx -O my_file.txt
53
+ ```
54
+
55
+ ## download example2
56
+
57
+ From Your Original HTTP Server
58
+
59
+ ```
60
+ qdown xxxxxxxxxxxxx -O my_file.txt -s http://host.docker.internal:3000
61
+ ```
62
+
63
+
64
+ # uninstall
65
+
66
+ ```
67
+ pip uninstall qdown -y
68
+ ```
@@ -2,11 +2,12 @@ MANIFEST.in
2
2
  README.md
3
3
  setup.py
4
4
  qdown/__init__.py
5
- qdown/gdown.py
5
+ qdown/qdown.py
6
6
  qdown.egg-info/PKG-INFO
7
7
  qdown.egg-info/SOURCES.txt
8
8
  qdown.egg-info/dependency_links.txt
9
9
  qdown.egg-info/entry_points.txt
10
10
  qdown.egg-info/requires.txt
11
11
  qdown.egg-info/top_level.txt
12
- z_examples/__init__.py
12
+ z_examples/__init__.py
13
+ z_examples/example.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ qdown = qdown.qdown:main
@@ -2,11 +2,18 @@
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
4
  from setuptools import setup, find_packages
5
+ import os
6
+
7
+ # README.mdの内容を読み込む
8
+ with open("README.md", "r", encoding="utf-8") as fh:
9
+ long_description = fh.read()
5
10
 
6
11
  setup(
7
12
  name="qdown",
8
- version="1.0.0",
13
+ version="1.0.3", # バージョン更新
9
14
  description="Client for QualitegDrive",
15
+ long_description=long_description,
16
+ long_description_content_type="text/markdown",
10
17
  author="Qualiteg Inc.",
11
18
  author_email="qualiteger@qualiteg.com",
12
19
  url="https://github.com/qualiteg/qdown",
@@ -17,7 +24,7 @@ setup(
17
24
  ],
18
25
  entry_points={
19
26
  "console_scripts": [
20
- "qdown=qdown.gdown:main", # ファイル名をgdown.pyに修正
27
+ "qdown=qdown.qdown:main",
21
28
  ],
22
29
  },
23
30
  classifiers=[
@@ -0,0 +1,4 @@
1
+ import qdown
2
+
3
+ # ファイル共有リンクからダウンロード
4
+ file_path = qdown.download("https://drive.qualiteg.com/file/xxxxxx")
qdown-1.0.0/PKG-INFO DELETED
@@ -1,16 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: qdown
3
- Version: 1.0.0
4
- Summary: Client for QualitegDrive
5
- Home-page: https://github.com/qualiteg/qdown
6
- Author: Qualiteg Inc.
7
- Author-email: qualiteger@qualiteg.com
8
- Classifier: Development Status :: 3 - Alpha
9
- Classifier: Intended Audience :: Developers
10
- Classifier: License :: OSI Approved :: MIT License
11
- Classifier: Programming Language :: Python :: 3
12
- Classifier: Programming Language :: Python :: 3.7
13
- Classifier: Programming Language :: Python :: 3.8
14
- Classifier: Programming Language :: Python :: 3.9
15
- Classifier: Programming Language :: Python :: 3.10
16
- Requires-Python: >=3.7
@@ -1,24 +0,0 @@
1
- """
2
-
3
- Copyright (c) 2023 Qualiteg Inc. all rights reserved.
4
-
5
- This program is dual-licensed under the terms of the:
6
- 1) GNU Affero General Public License, version 3, or any later version.
7
- 2) A commercial license agreement provided by Qualiteg Inc.
8
-
9
- If you choose to use or redistribute this program under the terms of AGPLv3:
10
- This program is free software: you can redistribute it and/or modify
11
- it under the terms of the GNU Affero General Public License as
12
- published by the Free Software Foundation, either version 3 of the
13
- License, or (at your option) any later version.
14
- This program is distributed in the hope that it will be useful,
15
- but WITHOUT ANY WARRANTY; without even the implied warranty of
16
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
- GNU Affero General Public License for more details.
18
- You should have received a copy of the GNU Affero General Public License
19
- along with this program. If not, see <https://www.gnu.org/licenses/>.
20
-
21
- If you wish to use or redistribute this program under a commercial license:
22
- Please contact Qualiteg Inc.(https://qualiteg.com/contact) directly to obtain the terms and pricing.
23
-
24
- """
@@ -1,16 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: qdown
3
- Version: 1.0.0
4
- Summary: Client for QualitegDrive
5
- Home-page: https://github.com/qualiteg/qdown
6
- Author: Qualiteg Inc.
7
- Author-email: qualiteger@qualiteg.com
8
- Classifier: Development Status :: 3 - Alpha
9
- Classifier: Intended Audience :: Developers
10
- Classifier: License :: OSI Approved :: MIT License
11
- Classifier: Programming Language :: Python :: 3
12
- Classifier: Programming Language :: Python :: 3.7
13
- Classifier: Programming Language :: Python :: 3.8
14
- Classifier: Programming Language :: Python :: 3.9
15
- Classifier: Programming Language :: Python :: 3.10
16
- Requires-Python: >=3.7
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- qdown = qdown.gdown:main
File without changes
File without changes
File without changes
File without changes