1 /**
2  * download groonga lib
3  *
4  * Author: dokutoku
5  * License: CC0 Universal
6  */
7 module hello;
8 
9 
10 private static import std.algorithm.searching;
11 private static import std.ascii;
12 private static import std.digest;
13 private static import std.digest.sha;
14 private static import std.file;
15 private static import std.stdio;
16 private static import std.path;
17 private static import std.net.curl;
18 private static import std.zip;
19 
20 struct download_info
21 {
22 	string uri;
23 	string sha512_hash;
24 
25 	private bool verify(string file_path) const
26 
27 		do
28 		{
29 			return std.file.exists(file_path) && std.file.isFile(file_path) && std.digest.secureEqual(this.sha512_hash, std.digest.toHexString!(std.ascii.LetterCase.lower)(std.digest.sha.sha512Of(std.file.read(file_path))).idup);
30 		}
31 
32 	private void download(string dir_path) const
33 
34 		in
35 		{
36 			assert(dir_path.length != 0);
37 			assert(std.path.isValidPath(dir_path));
38 		}
39 
40 		do
41 		{
42 			string file_path = std.path.buildNormalizedPath(dir_path, std.path.baseName(this.uri));
43 
44 			if (this.verify(file_path)) {
45 				return;
46 			}
47 
48 			std.net.curl.download(this.uri, file_path);
49 
50 			if (!this.verify(file_path)) {
51 				throw new Exception(`The hash value of the downloaded file is invalid.`);
52 			}
53 		}
54 
55 	void extract_lib(string dir_path) const
56 
57 		in
58 		{
59 			assert(std.path.extension(this.uri) == `.zip`);
60 		}
61 
62 		do
63 		{
64 			this.download(dir_path);
65 			string zip_file = std.path.baseName(this.uri);
66 			string base_dir = std.path.buildNormalizedPath(dir_path, std.path.baseName(zip_file, `.zip`));
67 			auto zip = new std.zip.ZipArchive(std.file.read(std.path.buildNormalizedPath(dir_path, zip_file)));
68 
69 			foreach (name, am; zip.directory) {
70 				if (!std.algorithm.searching.endsWith(name, `.dll`, `.exe`, `.lib`, `.pdb`)) {
71 					continue;
72 				}
73 
74 				string out_filename = std.path.buildPath(base_dir, name);
75 				std.file.mkdirRecurse(std.path.dirName(out_filename));
76 				std.file.write(out_filename, zip.expand(am));
77 			}
78 	}
79 }
80 
81 static immutable download_info windows_x86 =
82 {
83 	uri: `https://github.com/groonga/groonga/releases/download/v11.0.7/groonga-11.0.7-x86-vs2019-with-vcruntime.zip`,
84 	sha512_hash: `9f38fc65f245b91e666706b2b6c59236e09fc8553685c9c5c4b2f8a906c2a63337ea699a8ad2eebaac3928a192c11cf8411576eb8109e89cae5918b52816a800`,
85 };
86 
87 static immutable download_info windows_x86_64 =
88 {
89 	uri: `https://github.com/groonga/groonga/releases/download/v11.0.7/groonga-11.0.7-x64-vs2019-with-vcruntime.zip`,
90 	sha512_hash: `6739f35f1de1f93d92a7d3f1be79eae12f6e9e57a8242fc5793779280b571e70e8c91d2b86007a100c4c3b26ac0434d023f81519eb58efc5397171d0e9f1b2c4`,
91 };
92 
93 /**
94  * ?
95  */
96 void main()
97 
98 	do
99 	{
100 		windows_x86.extract_lib(`./`);
101 		windows_x86_64.extract_lib(`./`);
102 	}