appcask 0.4.0 → 0.6.0

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.
data/README.md CHANGED
@@ -1,159 +1,159 @@
1
- # AppCask - App Store 资源下载工具
1
+ # AppCask - App Store Resources Downloader
2
2
 
3
3
  <div align="center">
4
4
 
5
- ![Version](https://img.shields.io/badge/version-0.3.0-blue.svg)
5
+ ![Version](https://img.shields.io/badge/version-0.6.0-blue.svg)
6
6
  ![Ruby](https://img.shields.io/badge/ruby-%3E%3D%203.2.0-red.svg)
7
7
  ![License](https://img.shields.io/badge/license-MIT-green.svg)
8
8
 
9
- 一个全能的命令行工具,用于下载 iOS App Store 的应用资源
10
- **图标 · 截图 · 应用简介 · 一键打包**
9
+ An all-in-one command-line tool for downloading resources of iOS App Store apps
10
+ **Icons Screenshots App Description • One-click Packaging**
11
11
 
12
- [功能特性](#-功能特性) • [安装](#-安装) • [使用指南](#-使用指南) • [示例](#-使用示例)
12
+ [Features](#-features) • [Installation](#-installation) • [Usage Guide](#-usage-guide) • [Examples](#-usage-examples)
13
13
 
14
14
  </div>
15
15
 
16
16
  ---
17
17
 
18
- ## ✨ 功能特性
19
-
20
- ### 🎨 图标下载
21
- - 支持 4 种尺寸:60x60100x100512x5121024x1024
22
- - 自动检测图片格式 (PNG/JPG/GIF/WEBP)
23
- - 智能文件命名
24
-
25
- ### 📸 截图下载
26
- - iPhone 截图
27
- - iPad 截图
28
- - 批量下载所有截图
29
- - 自动分类保存
30
-
31
- ### 📝 应用信息导出
32
- - **TXT 格式** - 易读的文本文件
33
- - **JSON 格式** - 结构化数据
34
- - **Markdown 格式** - 精美的文档
35
-
36
- 包含信息:
37
- - 基本信息(名称、开发者、Bundle ID
38
- - 版本信息(当前版本、文件大小、系统要求)
39
- - 评分统计(平均分、评分数量)
40
- - 价格信息
41
- - 应用描述
42
- - 版本更新说明
43
- - 相关链接
44
-
45
- ### 📦 一键完整包
46
- 下载应用的所有资源,包括:
47
- - 所有尺寸的图标
48
- - 所有设备的截图
49
- - 完整的应用信息(3种格式)
50
-
51
- ### 🌍 多区域支持
52
- - 🇺🇸 美国 (us)
53
- - 🇨🇳 中国 (cn)
54
- - 🇯🇵 日本 (jp)
55
- - 🇰🇷 韩国 (kr)
56
- - 🇭🇰 香港 (hk)
57
- - 🇹🇼 台湾 (tw)
58
- - 🇬🇧 英国 (gb)
59
- - 🇩🇪 德国 (de)
60
- - 🇫🇷 法国 (fr)
18
+ ## ✨ Features
19
+
20
+ ### 🎨 Icon Download
21
+ - Supports four sizes: 60x60, 100x100, 512x512, 1024x1024
22
+ - Auto-detect image formats (PNG/JPG/GIF/WEBP)
23
+ - Intelligent file naming
24
+
25
+ ### 📸 Screenshot Download
26
+ - iPhone screenshots
27
+ - iPad screenshots
28
+ - Batch download all screenshots
29
+ - Automatic organization and saving
30
+
31
+ ### 📝 Export App Information
32
+ - **TXT format** - Human-readable text
33
+ - **JSON format** - Structured data
34
+ - **Markdown format** - Elegant documentation
35
+
36
+ Included information:
37
+ - Basic information (name, developer, Bundle ID)
38
+ - Version information (current version, file size, system requirements)
39
+ - Rating statistics (average rating, number of ratings)
40
+ - Pricing information
41
+ - App description
42
+ - Version update notes
43
+ - Related links
44
+
45
+ ### 📦 One-click Full Package
46
+ Download all resources for the app, including:
47
+ - Icons in all sizes
48
+ - Screenshots for all devices
49
+ - Complete app information (in 3 formats)
50
+
51
+ ### 🌍 Multiregion Support
52
+ - 🇺🇸 United States (US)
53
+ - 🇨🇳 China (CN)
54
+ - 🇯🇵 Japan (JP)
55
+ - 🇰🇷 Korea (KR)
56
+ - 🇭🇰 Hong Kong (HK)
57
+ - 🇹🇼 Taiwan (TW)
58
+ - 🇬🇧 United Kingdom (GB)
59
+ - 🇩🇪 Germany (DE)
60
+ - 🇫🇷 France (FR)
61
61
 
62
62
  ---
63
63
 
64
- ## 📦 安装
64
+ ## 📦 Installation
65
65
 
66
66
  ```bash
67
67
  gem install appcask
68
68
  ```
69
69
 
70
- 或从源码安装:
70
+ Or from source:
71
71
 
72
72
  ```bash
73
73
  git clone https://github.com/yourusername/appcask.git
74
74
  cd appcask
75
75
  bundle install
76
76
  rake build
77
- gem install pkg/appcask-1.0.0.gem
77
+ gem install pkg/appcask-0.6.0.gem
78
78
  ```
79
79
 
80
80
  ---
81
81
 
82
- ## 🚀 快速开始
82
+ ## 🚀 Quick Start
83
83
 
84
84
  ```bash
85
- # 交互模式
85
+ # Interactive mode
86
86
  appcask
87
87
 
88
- # 快速搜索
88
+ # Quick search
89
89
  appcask "Instagram"
90
90
 
91
- # 指定区域
92
- appcask "微信" cn
91
+ # Specify region
92
+ appcask "WeChat" cn
93
93
  ```
94
94
 
95
- ### 完整演示
95
+ ### Full Demo
96
96
 
97
97
  ```
98
98
  $ appcask "Twitter"
99
99
 
100
100
  ╔═══════════════════════════════════════════╗
101
- ║ AppCask - App 资源下载工具
102
- v1.0.0 ║
101
+ ║ AppCask - App Resources Downloader
102
+ v0.6.0 ║
103
103
  ╚═══════════════════════════════════════════╝
104
104
 
105
- 🔍 正在搜索 "Twitter"...
105
+ 🔍 Searching for "Twitter"...
106
106
 
107
- 📋 找到 3 个结果:
107
+ 📋 Found 3 results:
108
108
 
109
109
  [0] X
110
- 开发者: X Corp. | 版本: 10.31
111
- 价格: Free | 评分: ⭐ 4.2
110
+ Developer: X Corp. | Version: 10.31
111
+ Price: Free | Rating: ⭐ 4.2
112
112
 
113
- 请选择 (0-2, 或按q退出): 0
113
+ Please choose (0-2, or press q to quit): 0
114
114
 
115
- 已选择: X
115
+ Selected: X
116
116
 
117
- 📦 选择下载内容:
118
- [1] 图标
119
- [2] 截图
120
- [3] 简介信息
121
- [4] 完整包(图标+截图+简介)
117
+ 📦 Choose content to download:
118
+ [1] Icon
119
+ [2] Screenshots
120
+ [3] Description
121
+ [4] Full package (Icons + Screenshots + Description)
122
122
 
123
- 请选择 (1-4): 4
123
+ Please choose (1-4): 4
124
124
 
125
- 下载完成!
125
+ Download complete!
126
126
  📁 ~/Desktop/AppCask Downloads/X
127
- 📊 统计: 15 个文件, 总大小 8.45 MB
127
+ 📊 Stats: 15 files, total size 8.45 MB
128
128
  ```
129
129
 
130
130
  ---
131
131
 
132
- ## 📖 使用示例
132
+ ## 📖 Usage Examples
133
133
 
134
- ### 仅下载图标
134
+ ### Download Only Icons
135
135
 
136
136
  ```bash
137
137
  appcask "Instagram"
138
- # 选择: [1] 图标 → [3] 1024x1024
138
+ # Choose: [1] Icons → [3] 1024x1024
139
139
  ```
140
140
 
141
- ### 下载所有截图
141
+ ### Download All Screenshots
142
142
 
143
143
  ```bash
144
- appcask "王者荣耀" cn
145
- # 选择: [2] 截图 → all
144
+ appcask "Honor of Kings" cn
145
+ # Choose: [2] Screenshots → all
146
146
  ```
147
147
 
148
- ### 导出应用信息
148
+ ### Export App Information
149
149
 
150
150
  ```bash
151
151
  appcask "Notion"
152
- # 选择: [3] 简介信息
153
- # 输出: TXT + JSON + Markdown
152
+ # Choose: [3] Description
153
+ # Output: TXT + JSON + Markdown
154
154
  ```
155
155
 
156
- ### 批量下载
156
+ ### Batch Download
157
157
 
158
158
  ```ruby
159
159
  #!/usr/bin/env ruby
@@ -168,7 +168,7 @@ end
168
168
 
169
169
  ---
170
170
 
171
- ## 📂 文件结构
171
+ ## 📂 File Structure
172
172
 
173
173
  ```
174
174
  AppCask Downloads/
@@ -188,57 +188,57 @@ AppCask Downloads/
188
188
 
189
189
  ---
190
190
 
191
- ## 🔧 高级功能
191
+ ## 🔧 Advanced Features
192
192
 
193
- ### Debug 模式
193
+ ### Debug Mode
194
194
 
195
195
  ```bash
196
196
  DEBUG=1 appcask "AppName"
197
197
  ```
198
198
 
199
- ### 快捷操作
199
+ ### Quick Operations
200
200
 
201
- - **回车** - 默认选项
202
- - **q** - 退出
203
- - **Ctrl+C** - 中断
201
+ - **Enter** - Default option
202
+ - **q** - Quit
203
+ - **Ctrl+C** - Interrupt
204
204
 
205
205
  ---
206
206
 
207
- ## 🐛 故障排除
207
+ ## 🐛 Troubleshooting
208
208
 
209
- **Q: 搜索不到应用?**
210
- A: 确认拼写、尝试切换区域
209
+ **Q: Can't find the app?**
210
+ A: Check spelling and try switching regions
211
211
 
212
- **Q: 图标尺寸不对?**
213
- A: 部分应用不支持 1024x1024
212
+ **Q: Icon size is wrong?**
213
+ A: Some apps do not support 1024x1024
214
214
 
215
- **Q: 网络超时?**
216
- A: 检查网络、使用 VPN
215
+ **Q: Network timeout?**
216
+ A: Check network, use VPN
217
217
 
218
- **Q: 文件保存在哪?**
218
+ **Q: Where are files saved?**
219
219
  A: `~/Desktop/AppCask Downloads/`
220
220
 
221
221
  ---
222
222
 
223
- ## 🎯 路线图
223
+ ## 🎯 Roadmap
224
224
 
225
- - [ ] macOS App Store 支持
226
- - [ ] 应用评论下载
227
- - [ ] 批量下载模式
228
- - [ ] Web 界面
225
+ - [ ] macOS App Store support
226
+ - [ ] App reviews download
227
+ - [ ] Batch download mode
228
+ - [ ] Web interface
229
229
 
230
230
  ---
231
231
 
232
- ## 📄 许可证
232
+ ## 📄 License
233
233
 
234
234
  MIT License
235
235
 
236
236
  ---
237
237
 
238
- ## 📮 联系
238
+ ## 📮 Contact
239
239
 
240
240
  - GitHub: [@yourusername](https://github.com/yourusername)
241
- - Issues: [反馈问题](https://github.com/yourusername/appcask/issues)
241
+ - Issues: [Feedback issues](https://github.com/yourusername/appcask/issues)
242
242
 
243
243
  ---
244
244
 
@@ -1,26 +1,28 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
2
4
  # AppCask batch download example
3
5
  # Usage: ruby examples/batch_download.rb
4
6
 
5
- require 'appcask'
7
+ require "appcask"
6
8
 
7
9
  # Define the list of apps to download
8
10
  apps = [
9
- { name: 'Instagram', region: 'us', description: 'Social media app' },
10
- { name: 'Twitter', region: 'us', description: 'Microblogging platform' },
11
- { name: 'WeChat', region: 'cn', description: 'Instant messaging app' },
12
- { name: 'LINE', region: 'jp', description: 'Messaging app popular in Japan' },
13
- { name: 'KakaoTalk', region: 'kr', description: 'Messaging app popular in Korea' }
11
+ { name: "Instagram", region: "us", description: "Social media app" },
12
+ { name: "Twitter", region: "us", description: "Microblogging platform" },
13
+ { name: "WeChat", region: "cn", description: "Instant messaging app" },
14
+ { name: "LINE", region: "jp", description: "Messaging app popular in Japan" },
15
+ { name: "KakaoTalk", region: "kr", description: "Messaging app popular in Korea" }
14
16
  ]
15
17
 
16
- puts '=' * 50
17
- puts 'AppCask Batch Download Script'
18
- puts '=' * 50
18
+ puts "=" * 50
19
+ puts "AppCask Batch Download Script"
20
+ puts "=" * 50
19
21
  puts "\nPreparing to download resources for #{apps.size} apps...\n\n"
20
22
 
21
23
  apps.each_with_index do |app, index|
22
24
  puts "\n[#{index + 1}/#{apps.size}] Processing: #{app[:name]} (#{app[:description]})"
23
- puts '-' * 50
25
+ puts "-" * 50
24
26
 
25
27
  # Set command-line arguments
26
28
  ARGV.clear
@@ -38,6 +40,6 @@ apps.each_with_index do |app, index|
38
40
  sleep 2 unless index == apps.size - 1
39
41
  end
40
42
 
41
- puts "\n" + '=' * 50
42
- puts 'Batch download completed!'
43
- puts '=' * 50
43
+ puts "\n#{"=" * 50}"
44
+ puts "Batch download completed!"
45
+ puts "=" * 50
data/exe/appcask CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require "appcask"
4
5
 
5
- AppCask.main
6
+ AppCask.main
@@ -0,0 +1,139 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cfpropertylist"
4
+ require "icns"
5
+ require "mini_magick"
6
+ require "fileutils"
7
+
8
+ module AppCask
9
+ class LocalApp
10
+ APPS_DIR = "/Applications"
11
+ OUTPUT_BASE = File.join(Dir.home, "Desktop", "AppCask Downloads", "Local Apps")
12
+
13
+ class << self
14
+ def fetch_all
15
+ puts "\nFetching local app icons..."
16
+ puts "Source: #{APPS_DIR}"
17
+ puts "Output: #{OUTPUT_BASE}\n\n"
18
+
19
+ FileUtils.mkdir_p(OUTPUT_BASE)
20
+
21
+ apps = Dir.glob(File.join(APPS_DIR, "*.app"))
22
+ total = apps.count
23
+ success = 0
24
+ skipped = 0
25
+
26
+ apps.each_with_index do |app_path, index|
27
+ app_name = File.basename(app_path, ".app")
28
+ print "\r[#{index + 1}/#{total}] Processing: #{app_name.ljust(30)}"
29
+
30
+ result = extract_icon(app_path)
31
+ if result
32
+ success += 1
33
+ else
34
+ skipped += 1
35
+ end
36
+ end
37
+
38
+ puts "\n\n#{"=" * 50}"
39
+ puts "Done!"
40
+ puts " Total apps: #{total}"
41
+ puts " Extracted: #{success}"
42
+ puts " Skipped: #{skipped}"
43
+ puts " Output: #{OUTPUT_BASE}"
44
+ puts "=" * 50
45
+
46
+ # Open folder on macOS
47
+ return unless RUBY_PLATFORM.include?("darwin")
48
+
49
+ print "\nOpen the folder? (y/n): "
50
+ response = $stdin.gets
51
+ system("open '#{OUTPUT_BASE}'") if response&.strip&.downcase == "y"
52
+ end
53
+
54
+ private
55
+
56
+ def extract_icon(app_path)
57
+ # 1. Read Info.plist
58
+ plist_path = File.join(app_path, "Contents", "Info.plist")
59
+ return nil unless File.exist?(plist_path)
60
+
61
+ plist = CFPropertyList::List.new(file: plist_path)
62
+ info = CFPropertyList.native_types(plist.value)
63
+
64
+ # 2. Get icon file name
65
+ icon_name = info["CFBundleTypeIconFile"] || info["CFBundleIconFile"] || info["CFBundleIconName"]
66
+ return nil unless icon_name
67
+
68
+ icon_name += ".icns" unless icon_name.end_with?(".icns")
69
+
70
+ # 3. Find .icns file
71
+ icns_path = File.join(app_path, "Contents", "Resources", icon_name)
72
+ return nil unless File.exist?(icns_path)
73
+
74
+ # 4. Parse .icns and extract largest PNG
75
+ reader = Icns::Reader.new(icns_path)
76
+
77
+ # Priority: 1024 → 512 → 256 → 128
78
+ [1024, 512, 256, 128].each do |size|
79
+ data = reader.image(size: size)
80
+ next unless data
81
+ next unless png?(data)
82
+
83
+ # 5. Save as 512x512 PNG
84
+ output_path = output_path(app_path)
85
+ save_as_512(data, size, output_path)
86
+ return output_path
87
+ end
88
+
89
+ nil
90
+ rescue StandardError
91
+ nil
92
+ end
93
+
94
+ def png?(data)
95
+ png_magic = [0x89, 0x50, 0x4e, 0x47].pack("C4")
96
+ data[0..3] == png_magic
97
+ end
98
+
99
+ def save_as_512(data, original_size, output_path)
100
+ if original_size == 512
101
+ # Direct write
102
+ File.write(output_path, data)
103
+ else
104
+ # Need to resize - use mini_magick
105
+ resize_with_mini_magick(data, output_path)
106
+ end
107
+ end
108
+
109
+ def resize_with_mini_magick(data, output_path)
110
+ # Write to temp file, resize, then save
111
+ tmp_input = File.join(Dir.tmpdir, "appcask_input_#{Process.pid}.png")
112
+ tmp_output = File.join(Dir.tmpdir, "appcask_output_#{Process.pid}.png")
113
+
114
+ File.write(tmp_input, data)
115
+
116
+ image = MiniMagick::Image.new(tmp_input)
117
+ image.resize "512x512"
118
+ image.format "png"
119
+ image.write(tmp_output)
120
+
121
+ FileUtils.cp(tmp_output, output_path)
122
+ ensure
123
+ FileUtils.rm_f(tmp_input) if tmp_input
124
+ FileUtils.rm_f(tmp_output) if tmp_output
125
+ end
126
+
127
+ def output_path(app_path)
128
+ app_name = File.basename(app_path, ".app")
129
+ filename = "#{sanitize_app_name(app_name)}.png"
130
+ File.join(OUTPUT_BASE, filename)
131
+ end
132
+
133
+ def sanitize_app_name(name)
134
+ # Keep Chinese characters, convert to lowercase, replace spaces with hyphens
135
+ name.downcase.gsub(/\s+/, "-").gsub(/[^a-z0-9\u4e00-\u9fff-]/, "").gsub(/^-|-$/, "")
136
+ end
137
+ end
138
+ end
139
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AppCask
4
- VERSION = "0.4.0"
4
+ VERSION = "0.6.0"
5
5
  end