feat: image thumbnails
This commit is contained in:
		
							parent
							
								
									61f4f2c716
								
							
						
					
					
						commit
						d544d28b6e
					
				
					 6 changed files with 365 additions and 112 deletions
				
			
		
							
								
								
									
										294
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										294
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							|  | @ -1,5 +1,11 @@ | |||
| # This file is automatically @generated by Cargo. | ||||
| # It is not intended for manual editing. | ||||
| [[package]] | ||||
| name = "adler32" | ||||
| version = "1.0.4" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "arc-swap" | ||||
| version = "0.4.6" | ||||
|  | @ -24,9 +30,9 @@ version = "0.1.31" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "26c4f3195085c36ea8d24d32b2f828d23296a9370a28aa39d111f6f16bef9f3b" | ||||
| dependencies = [ | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.5", | ||||
|  "syn 1.0.21", | ||||
|  "proc-macro2 1.0.13", | ||||
|  "quote 1.0.6", | ||||
|  "syn 1.0.22", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
|  | @ -96,6 +102,12 @@ version = "3.3.0" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "5356f1d23ee24a1f785a56d1d1a5f0fd5b0f6a0c0fb2412ce11da71649ab78f6" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "bytemuck" | ||||
| version = "1.2.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "37fa13df2292ecb479ec23aa06f4507928bef07839be9ef15281411076629431" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "byteorder" | ||||
| version = "1.3.4" | ||||
|  | @ -110,9 +122,9 @@ checksum = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1" | |||
| 
 | ||||
| [[package]] | ||||
| name = "cc" | ||||
| version = "1.0.52" | ||||
| version = "1.0.53" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "c3d87b23d6a92cd03af510a5ade527033f6aa6fa92161e2d5863a907d4c5e31d" | ||||
| checksum = "404b1fe4f65288577753b17e3b36a04596ee784493ec249bf81c7f2d2acd751c" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "cfg-if" | ||||
|  | @ -129,6 +141,12 @@ dependencies = [ | |||
|  "bitflags", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "color_quant" | ||||
| version = "1.0.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "conduit" | ||||
| version = "0.1.0" | ||||
|  | @ -136,6 +154,7 @@ dependencies = [ | |||
|  "base64 0.12.1", | ||||
|  "directories", | ||||
|  "http", | ||||
|  "image", | ||||
|  "js_int", | ||||
|  "log", | ||||
|  "rand", | ||||
|  | @ -224,6 +243,16 @@ dependencies = [ | |||
|  "lazy_static", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "deflate" | ||||
| version = "0.8.4" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "e7e5d2a2273fed52a7f947ee55b092c4057025d7a3e04e5ecdbd25d6c3fb1bd7" | ||||
| dependencies = [ | ||||
|  "adler32", | ||||
|  "byteorder", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "devise" | ||||
| version = "0.3.0" | ||||
|  | @ -239,7 +268,7 @@ version = "0.3.0" | |||
| source = "git+https://github.com/SergioBenitez/Devise.git?rev=e58b3ac9a#e58b3ac9afc3b6ff10a8aaf02a3e768a8f530089" | ||||
| dependencies = [ | ||||
|  "devise_core", | ||||
|  "quote 1.0.5", | ||||
|  "quote 1.0.6", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
|  | @ -248,9 +277,9 @@ version = "0.3.0" | |||
| source = "git+https://github.com/SergioBenitez/Devise.git?rev=e58b3ac9a#e58b3ac9afc3b6ff10a8aaf02a3e768a8f530089" | ||||
| dependencies = [ | ||||
|  "bitflags", | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.5", | ||||
|  "syn 1.0.21", | ||||
|  "proc-macro2 1.0.13", | ||||
|  "quote 1.0.6", | ||||
|  "syn 1.0.22", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
|  | @ -292,9 +321,9 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "fnv" | ||||
| version = "1.0.6" | ||||
| version = "1.0.7" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" | ||||
| checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "foreign-types" | ||||
|  | @ -392,9 +421,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39" | ||||
| dependencies = [ | ||||
|  "proc-macro-hack", | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.5", | ||||
|  "syn 1.0.21", | ||||
|  "proc-macro2 1.0.13", | ||||
|  "quote 1.0.6", | ||||
|  "syn 1.0.22", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
|  | @ -452,6 +481,16 @@ dependencies = [ | |||
|  "wasi", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "gif" | ||||
| version = "0.10.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "471d90201b3b223f3451cd4ad53e34295f16a1df17b1edf3736d47761c3981af" | ||||
| dependencies = [ | ||||
|  "color_quant", | ||||
|  "lzw", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "h2" | ||||
| version = "0.2.5" | ||||
|  | @ -482,9 +521,9 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "hermit-abi" | ||||
| version = "0.1.12" | ||||
| version = "0.1.13" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "61565ff7aaace3525556587bd2dc31d4a07071957be715e63ce7b1eccf51a8f4" | ||||
| checksum = "91780f809e750b0a89f5544be56617ff6b1227ee485bcb06ebe10cdf89bd3b71" | ||||
| dependencies = [ | ||||
|  "libc", | ||||
| ] | ||||
|  | @ -564,6 +603,22 @@ dependencies = [ | |||
|  "unicode-normalization", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "image" | ||||
| version = "0.23.4" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "9117f4167a8f21fa2bb3f17a652a760acd7572645281c98e3b612a26242c96ee" | ||||
| dependencies = [ | ||||
|  "bytemuck", | ||||
|  "byteorder", | ||||
|  "gif", | ||||
|  "jpeg-decoder", | ||||
|  "num-iter", | ||||
|  "num-rational", | ||||
|  "num-traits", | ||||
|  "png", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "indexmap" | ||||
| version = "1.3.2" | ||||
|  | @ -573,6 +628,15 @@ dependencies = [ | |||
|  "autocfg", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "inflate" | ||||
| version = "0.4.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff" | ||||
| dependencies = [ | ||||
|  "adler32", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "iovec" | ||||
| version = "0.1.4" | ||||
|  | @ -588,6 +652,15 @@ version = "0.4.5" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "jpeg-decoder" | ||||
| version = "0.1.19" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "5b47b4c4e017b01abdc5bcc126d2d1002e5a75bbe3ce73f9f4f311a916363704" | ||||
| dependencies = [ | ||||
|  "byteorder", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "js-sys" | ||||
| version = "0.3.39" | ||||
|  | @ -646,6 +719,12 @@ dependencies = [ | |||
|  "cfg-if", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "lzw" | ||||
| version = "0.10.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "matches" | ||||
| version = "0.1.8" | ||||
|  | @ -760,6 +839,47 @@ dependencies = [ | |||
|  "winapi 0.3.8", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "num-integer" | ||||
| version = "0.1.42" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" | ||||
| dependencies = [ | ||||
|  "autocfg", | ||||
|  "num-traits", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "num-iter" | ||||
| version = "0.1.40" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "dfb0800a0291891dd9f4fe7bd9c19384f98f7fbe0cd0f39a2c6b88b9868bbc00" | ||||
| dependencies = [ | ||||
|  "autocfg", | ||||
|  "num-integer", | ||||
|  "num-traits", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "num-rational" | ||||
| version = "0.2.4" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" | ||||
| dependencies = [ | ||||
|  "autocfg", | ||||
|  "num-integer", | ||||
|  "num-traits", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "num-traits" | ||||
| version = "0.2.11" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" | ||||
| dependencies = [ | ||||
|  "autocfg", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "num_cpus" | ||||
| version = "1.13.0" | ||||
|  | @ -869,22 +989,22 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" | |||
| 
 | ||||
| [[package]] | ||||
| name = "pin-project" | ||||
| version = "0.4.16" | ||||
| version = "0.4.17" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "81d480cb4e89522ccda96d0eed9af94180b7a5f93fb28f66e1fd7d68431663d1" | ||||
| checksum = "edc93aeee735e60ecb40cf740eb319ff23eab1c5748abfdb5c180e4ce49f7791" | ||||
| dependencies = [ | ||||
|  "pin-project-internal", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "pin-project-internal" | ||||
| version = "0.4.16" | ||||
| version = "0.4.17" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "a82996f11efccb19b685b14b5df818de31c1edcee3daa256ab5775dd98e72feb" | ||||
| checksum = "e58db2081ba5b4c93bd6be09c40fd36cb9193a8336c384f3b40012e531aa7e40" | ||||
| dependencies = [ | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.5", | ||||
|  "syn 1.0.21", | ||||
|  "proc-macro2 1.0.13", | ||||
|  "quote 1.0.6", | ||||
|  "syn 1.0.22", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
|  | @ -906,10 +1026,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "ppv-lite86" | ||||
| version = "0.2.6" | ||||
| name = "png" | ||||
| version = "0.16.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" | ||||
| checksum = "2c68a431ed29933a4eb5709aca9800989758c97759345860fa5db3cfced0b65d" | ||||
| dependencies = [ | ||||
|  "bitflags", | ||||
|  "crc32fast", | ||||
|  "deflate", | ||||
|  "inflate", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "ppv-lite86" | ||||
| version = "0.2.8" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "proc-macro-hack" | ||||
|  | @ -934,9 +1066,9 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "proc-macro2" | ||||
| version = "1.0.12" | ||||
| version = "1.0.13" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "8872cf6f48eee44265156c111456a700ab3483686b3f96df4cf5481c89157319" | ||||
| checksum = "53f5ffe53a6b28e37c9c1ce74893477864d64f74778a93a4beb43c8fa167f639" | ||||
| dependencies = [ | ||||
|  "unicode-xid 0.2.0", | ||||
| ] | ||||
|  | @ -952,11 +1084,11 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "quote" | ||||
| version = "1.0.5" | ||||
| version = "1.0.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "42934bc9c8ab0d3b273a16d8551c8f0fcff46be73276ca083ec2414c15c4ba5e" | ||||
| checksum = "54a21852a652ad6f610c9510194f398ff6f8692e334fd1145fed931f7fbe44ea" | ||||
| dependencies = [ | ||||
|  "proc-macro2 1.0.12", | ||||
|  "proc-macro2 1.0.13", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
|  | @ -1108,7 +1240,7 @@ source = "git+https://github.com/SergioBenitez/Rocket.git?branch=async#78c8ac8cc | |||
| dependencies = [ | ||||
|  "devise", | ||||
|  "indexmap", | ||||
|  "quote 1.0.5", | ||||
|  "quote 1.0.6", | ||||
|  "rocket_http", | ||||
|  "version_check 0.9.1", | ||||
|  "yansi 0.5.0", | ||||
|  | @ -1145,7 +1277,7 @@ dependencies = [ | |||
|  "percent-encoding 2.1.0", | ||||
|  "ruma-api-macros", | ||||
|  "ruma-identifiers", | ||||
|  "ruma-serde 0.2.0", | ||||
|  "ruma-serde 0.2.1", | ||||
|  "serde", | ||||
|  "serde_json", | ||||
|  "strum", | ||||
|  | @ -1157,16 +1289,15 @@ version = "0.16.1" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "52b82b4567b9af9b40a86f7778821c016ea961f55e4fee255f8f24bb28ee7452" | ||||
| dependencies = [ | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.5", | ||||
|  "syn 1.0.21", | ||||
|  "proc-macro2 1.0.13", | ||||
|  "quote 1.0.6", | ||||
|  "syn 1.0.22", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "ruma-client-api" | ||||
| version = "0.8.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "84a57433fc6dded259aef2b12ceb91d78d3607b182278f648edd5c19c23d81cd" | ||||
| source = "git+https://github.com/ruma/ruma-client-api.git#3a3ccabbf22c34da5c9de7cac54d9fbd3e571dcf" | ||||
| dependencies = [ | ||||
|  "http", | ||||
|  "js_int", | ||||
|  | @ -1174,7 +1305,7 @@ dependencies = [ | |||
|  "ruma-common", | ||||
|  "ruma-events", | ||||
|  "ruma-identifiers", | ||||
|  "ruma-serde 0.1.3", | ||||
|  "ruma-serde 0.2.1", | ||||
|  "serde", | ||||
|  "serde_json", | ||||
|  "strum", | ||||
|  | @ -1182,39 +1313,40 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "ruma-common" | ||||
| version = "0.1.1" | ||||
| version = "0.1.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "235f2fed35114ef3fbff1b7d5350f22ac712cffff55cc7b7732d39ae4adf6966" | ||||
| checksum = "253416d67b4bde281f2781424232a58a946a4f1c451d5f857a8d0705d58eaf2a" | ||||
| dependencies = [ | ||||
|  "ruma-serde 0.1.3", | ||||
|  "matches", | ||||
|  "ruma-serde 0.2.1", | ||||
|  "serde", | ||||
|  "serde_json", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "ruma-events" | ||||
| version = "0.21.1" | ||||
| version = "0.21.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "e952b80bddd83666a84db842d3e4d2ea43f8b4df8134864835c1807bd843fe21" | ||||
| checksum = "0afc6d4da07d10213478d32dc42b6222df0a1ea319e9ced9f8a341617952d909" | ||||
| dependencies = [ | ||||
|  "js_int", | ||||
|  "ruma-common", | ||||
|  "ruma-events-macros", | ||||
|  "ruma-identifiers", | ||||
|  "ruma-serde 0.1.3", | ||||
|  "ruma-serde 0.2.1", | ||||
|  "serde", | ||||
|  "serde_json", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "ruma-events-macros" | ||||
| version = "0.21.1" | ||||
| version = "0.21.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "60256afd4cb1bcdbcd9676e88cbbd09afc2541bd7b0858a559ce9ad7c6cfbb2a" | ||||
| checksum = "fc706c4a53cc54c3a198cfbcd7dfff20448599d84f90e636d96034d0df5a9ac9" | ||||
| dependencies = [ | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.5", | ||||
|  "syn 1.0.21", | ||||
|  "proc-macro2 1.0.13", | ||||
|  "quote 1.0.6", | ||||
|  "syn 1.0.22", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
|  | @ -1257,9 +1389,9 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "ruma-serde" | ||||
| version = "0.2.0" | ||||
| version = "0.2.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "fb00252245980b8f8d9833632e611aba8e1657c9fbefefe2b35c2817fc2b58a4" | ||||
| checksum = "0dd3d04c6755bae23101dec7426d044b773ef517932f23d5a6254c4caa1cfce3" | ||||
| dependencies = [ | ||||
|  "dtoa", | ||||
|  "itoa", | ||||
|  | @ -1387,9 +1519,9 @@ version = "1.0.110" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "818fbf6bfa9a42d3bfcaca148547aa00c7b915bec71d1757aa2d44ca68771984" | ||||
| dependencies = [ | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.5", | ||||
|  "syn 1.0.21", | ||||
|  "proc-macro2 1.0.13", | ||||
|  "quote 1.0.6", | ||||
|  "syn 1.0.22", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
|  | @ -1481,9 +1613,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| checksum = "87c85aa3f8ea653bfd3ddf25f7ee357ee4d204731f6aa9ad04002306f6e2774c" | ||||
| dependencies = [ | ||||
|  "heck", | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.5", | ||||
|  "syn 1.0.21", | ||||
|  "proc-macro2 1.0.13", | ||||
|  "quote 1.0.6", | ||||
|  "syn 1.0.22", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
|  | @ -1499,12 +1631,12 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "syn" | ||||
| version = "1.0.21" | ||||
| version = "1.0.22" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "4696caa4048ac7ce2bcd2e484b3cef88c1004e41b8e945a277e2c25dc0b72060" | ||||
| checksum = "1425de3c33b0941002740a420b1a906a350b88d08b82b2c8a01035a3f9447bac" | ||||
| dependencies = [ | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.5", | ||||
|  "proc-macro2 1.0.13", | ||||
|  "quote 1.0.6", | ||||
|  "unicode-xid 0.2.0", | ||||
| ] | ||||
| 
 | ||||
|  | @ -1524,22 +1656,22 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "thiserror" | ||||
| version = "1.0.17" | ||||
| version = "1.0.18" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "467e5ff447618a916519a4e0d62772ab14f434897f3d63f05d8700ef1e9b22c1" | ||||
| checksum = "5976891d6950b4f68477850b5b9e5aa64d955961466f9e174363f573e54e8ca7" | ||||
| dependencies = [ | ||||
|  "thiserror-impl", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "thiserror-impl" | ||||
| version = "1.0.17" | ||||
| version = "1.0.18" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "e63c1091225b9834089b429bc4a2e01223470e3183e891582909e9d1c4cb55d9" | ||||
| checksum = "ab81dbd1cd69cd2ce22ecfbdd3bdb73334ba25350649408cc6c085f46d89573d" | ||||
| dependencies = [ | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.5", | ||||
|  "syn 1.0.21", | ||||
|  "proc-macro2 1.0.13", | ||||
|  "quote 1.0.6", | ||||
|  "syn 1.0.22", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
|  | @ -1581,16 +1713,16 @@ version = "0.2.5" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" | ||||
| dependencies = [ | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.5", | ||||
|  "syn 1.0.21", | ||||
|  "proc-macro2 1.0.13", | ||||
|  "quote 1.0.6", | ||||
|  "syn 1.0.22", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "tokio-rustls" | ||||
| version = "0.12.2" | ||||
| version = "0.12.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "141afec0978abae6573065a48882c6bae44c5cc61db9b511ac4abf6a09bfd9cc" | ||||
| checksum = "3068d891551949b37681724d6b73666787cc63fa8e255c812a41d2513aff9775" | ||||
| dependencies = [ | ||||
|  "futures-core", | ||||
|  "rustls", | ||||
|  | @ -1760,9 +1892,9 @@ dependencies = [ | |||
|  "bumpalo", | ||||
|  "lazy_static", | ||||
|  "log", | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.5", | ||||
|  "syn 1.0.21", | ||||
|  "proc-macro2 1.0.13", | ||||
|  "quote 1.0.6", | ||||
|  "syn 1.0.22", | ||||
|  "wasm-bindgen-shared", | ||||
| ] | ||||
| 
 | ||||
|  | @ -1784,7 +1916,7 @@ version = "0.2.62" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "2cd85aa2c579e8892442954685f0d801f9129de24fa2136b2c6a539c76b65776" | ||||
| dependencies = [ | ||||
|  "quote 1.0.5", | ||||
|  "quote 1.0.6", | ||||
|  "wasm-bindgen-macro-support", | ||||
| ] | ||||
| 
 | ||||
|  | @ -1794,9 +1926,9 @@ version = "0.2.62" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "8eb197bd3a47553334907ffd2f16507b4f4f01bbec3ac921a7719e0decdfe72a" | ||||
| dependencies = [ | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.5", | ||||
|  "syn 1.0.21", | ||||
|  "proc-macro2 1.0.13", | ||||
|  "quote 1.0.6", | ||||
|  "syn 1.0.22", | ||||
|  "wasm-bindgen-backend", | ||||
|  "wasm-bindgen-shared", | ||||
| ] | ||||
|  |  | |||
|  | @ -14,10 +14,10 @@ edition = "2018" | |||
| [dependencies] | ||||
| rocket = { git = "https://github.com/SergioBenitez/Rocket.git", branch = "async", features = ["tls"] } | ||||
| http = "0.2.1" | ||||
| ruma-client-api = "0.8.0" | ||||
| ruma-client-api = { git = "https://github.com/ruma/ruma-client-api.git" } | ||||
| ruma-identifiers = { version = "0.16.1", features = ["rand"] } | ||||
| ruma-api = "0.16.1" | ||||
| ruma-events = "0.21.1" | ||||
| ruma-events = "0.21.2" | ||||
| ruma-signatures = { git = "https://github.com/ruma/ruma-signatures.git", rev = "1ca545cba8dfd43e0fc8e3c18e1311fb73390a97" } | ||||
| ruma-federation-api = { git = "https://github.com/ruma/ruma-federation-api.git", rev = "ccbf216f39bbbaa59131cc200eae5bd18aa1947c" } | ||||
| log = "0.4.8" | ||||
|  | @ -31,5 +31,6 @@ rand = "0.7.3" | |||
| rust-argon2 = "0.8.2" | ||||
| reqwest = "0.10.4" | ||||
| base64 = "0.12.1" | ||||
| thiserror = "1.0.17" | ||||
| ruma-common = "0.1.1" | ||||
| thiserror = "1.0.18" | ||||
| ruma-common = "0.1.2" | ||||
| image = { version = "0.23.4", default-features = false, features = ["jpeg", "png", "gif"] } | ||||
|  |  | |||
|  | @ -26,13 +26,14 @@ A fast Matrix homeserver that's optimized for smaller, personal servers, instead | |||
| - [x] Typing indications | ||||
| - [x] Invites, user search | ||||
| - [x] Password hashing | ||||
| - [x] Riot E2EE | ||||
| - [x] Media | ||||
| - [ ] Basic federation | ||||
| - [ ] State resolution | ||||
| - [ ] Permission system | ||||
| - [ ] Notifications (push rules) | ||||
| - [ ] Riot presence | ||||
| - [ ] Proper room creation | ||||
| - [ ] Riot E2EE | ||||
| 
 | ||||
| #### How can I contribute? | ||||
| 
 | ||||
|  |  | |||
|  | @ -16,7 +16,7 @@ use ruma_client_api::{ | |||
|         directory::{self, get_public_rooms, get_public_rooms_filtered}, | ||||
|         filter::{self, create_filter, get_filter}, | ||||
|         keys::{claim_keys, get_keys, upload_keys}, | ||||
|         media::{create_content, get_content_thumbnail, get_content, get_media_config}, | ||||
|         media::{create_content, get_content, get_content_thumbnail, get_media_config}, | ||||
|         membership::{ | ||||
|             forget_room, get_member_events, invite_user, join_room_by_id, join_room_by_id_or_alias, | ||||
|             leave_room, | ||||
|  | @ -1307,9 +1307,7 @@ pub fn create_message_event_route( | |||
|         ) | ||||
|         .expect("message events are always okay"); | ||||
| 
 | ||||
|     MatrixResult(Ok(create_message_event::Response { | ||||
|         event_id: Some(event_id), | ||||
|     })) | ||||
|     MatrixResult(Ok(create_message_event::Response { event_id })) | ||||
| } | ||||
| 
 | ||||
| #[put(
 | ||||
|  | @ -1339,9 +1337,7 @@ pub fn create_state_event_for_key_route( | |||
|         ) | ||||
|         .unwrap(); | ||||
| 
 | ||||
|     MatrixResult(Ok(create_state_event_for_key::Response { | ||||
|         event_id: Some(event_id), | ||||
|     })) | ||||
|     MatrixResult(Ok(create_state_event_for_key::Response { event_id })) | ||||
| } | ||||
| 
 | ||||
| #[put(
 | ||||
|  | @ -1370,9 +1366,7 @@ pub fn create_state_event_for_empty_key_route( | |||
|         ) | ||||
|         .unwrap(); | ||||
| 
 | ||||
|     MatrixResult(Ok(create_state_event_for_empty_key::Response { | ||||
|         event_id: Some(event_id), | ||||
|     })) | ||||
|     MatrixResult(Ok(create_state_event_for_empty_key::Response { event_id })) | ||||
| } | ||||
| 
 | ||||
| #[get("/_matrix/client/r0/rooms/<_room_id>/state", data = "<body>")] | ||||
|  | @ -1805,7 +1799,6 @@ pub fn send_event_to_device_route( | |||
| 
 | ||||
| #[get("/_matrix/media/r0/config")] | ||||
| pub fn get_media_config_route() -> MatrixResult<get_media_config::Response> { | ||||
|     warn!("TODO: get_media_config_route"); | ||||
|     MatrixResult(Ok(get_media_config::Response { | ||||
|         upload_size: (20_u32 * 1024 * 1024).into(), // 20 MB
 | ||||
|     })) | ||||
|  | @ -1816,24 +1809,38 @@ pub fn create_content_route( | |||
|     db: State<'_, Database>, | ||||
|     body: Ruma<create_content::Request>, | ||||
| ) -> MatrixResult<create_content::Response> { | ||||
|     let mxc = format!("mxc://{}/{}", db.globals.server_name(), utils::random_string(MXC_LENGTH)); | ||||
|     let mxc = format!( | ||||
|         "mxc://{}/{}", | ||||
|         db.globals.server_name(), | ||||
|         utils::random_string(MXC_LENGTH) | ||||
|     ); | ||||
|     db.media | ||||
|         .create(mxc.clone(), body.filename.as_ref(), &body.content_type, &body.file) | ||||
|         .create( | ||||
|             mxc.clone(), | ||||
|             body.filename.as_ref(), | ||||
|             &body.content_type, | ||||
|             &body.file, | ||||
|         ) | ||||
|         .unwrap(); | ||||
| 
 | ||||
|     MatrixResult(Ok(create_content::Response { | ||||
|         content_uri: mxc, | ||||
|     })) | ||||
|     MatrixResult(Ok(create_content::Response { content_uri: mxc })) | ||||
| } | ||||
| 
 | ||||
| #[get("/_matrix/media/r0/download/<_server_name>/<_media_id>", data = "<body>")] | ||||
| #[get(
 | ||||
|     "/_matrix/media/r0/download/<_server_name>/<_media_id>", | ||||
|     data = "<body>" | ||||
| )] | ||||
| pub fn get_content_route( | ||||
|     db: State<'_, Database>, | ||||
|     body: Ruma<get_content::Request>, | ||||
|     _server_name: String, | ||||
|     _media_id: String, | ||||
| ) -> MatrixResult<get_content::Response> { | ||||
|     if let Some((filename, content_type, file)) = db.media.get(format!("mxc://{}/{}", body.server_name, body.media_id)).unwrap() { | ||||
|     if let Some((filename, content_type, file)) = db | ||||
|         .media | ||||
|         .get(format!("mxc://{}/{}", body.server_name, body.media_id)) | ||||
|         .unwrap() | ||||
|     { | ||||
|         MatrixResult(Ok(get_content::Response { | ||||
|             file, | ||||
|             content_type, | ||||
|  | @ -1848,18 +1855,26 @@ pub fn get_content_route( | |||
|     } | ||||
| } | ||||
| 
 | ||||
| #[get("/_matrix/media/r0/thumbnail/<_server_name>/<_media_id>", data = "<body>")] | ||||
| #[get(
 | ||||
|     "/_matrix/media/r0/thumbnail/<_server_name>/<_media_id>", | ||||
|     data = "<body>" | ||||
| )] | ||||
| pub fn get_content_thumbnail_route( | ||||
|     db: State<'_, Database>, | ||||
|     body: Ruma<get_content_thumbnail::Request>, | ||||
|     _server_name: String, | ||||
|     _media_id: String, | ||||
| ) -> MatrixResult<get_content_thumbnail::Response> { | ||||
|     if let Some((_, content_type, file)) = db.media.get(format!("mxc://{}/{}", body.server_name, body.media_id)).unwrap() { | ||||
|         MatrixResult(Ok(get_content_thumbnail::Response { | ||||
|             file, | ||||
|             content_type, | ||||
|         })) | ||||
|     if let Some((_, content_type, file)) = db | ||||
|         .media | ||||
|         .get_thumbnail( | ||||
|             format!("mxc://{}/{}", body.server_name, body.media_id), | ||||
|             body.width.try_into().unwrap(), | ||||
|             body.height.try_into().unwrap(), | ||||
|         ) | ||||
|         .unwrap() | ||||
|     { | ||||
|         MatrixResult(Ok(get_content_thumbnail::Response { file, content_type })) | ||||
|     } else { | ||||
|         MatrixResult(Err(Error { | ||||
|             kind: ErrorKind::NotFound, | ||||
|  |  | |||
|  | @ -1,7 +1,8 @@ | |||
| use crate::{utils, Error, Result}; | ||||
| use std::mem; | ||||
| 
 | ||||
| pub struct Media { | ||||
|     pub(super) mediaid_file: sled::Tree, // MediaId = MXC + Filename + ContentType
 | ||||
|     pub(super) mediaid_file: sled::Tree, // MediaId = MXC + WidthHeight + Filename + ContentType
 | ||||
| } | ||||
| 
 | ||||
| impl Media { | ||||
|  | @ -15,6 +16,9 @@ impl Media { | |||
|     ) -> Result<()> { | ||||
|         let mut key = mxc.as_bytes().to_vec(); | ||||
|         key.push(0xff); | ||||
|         key.extend_from_slice(&0_u32.to_be_bytes()); // Width = 0 if it's not a thumbnail
 | ||||
|         key.extend_from_slice(&0_u32.to_be_bytes()); // Height = 0 if it's not a thumbnail
 | ||||
|         key.push(0xff); | ||||
|         key.extend_from_slice(filename.map(|f| f.as_bytes()).unwrap_or_default()); | ||||
|         key.push(0xff); | ||||
|         key.extend_from_slice(content_type.as_bytes()); | ||||
|  | @ -28,10 +32,19 @@ impl Media { | |||
|     pub fn get(&self, mxc: String) -> Result<Option<(Option<String>, String, Vec<u8>)>> { | ||||
|         let mut prefix = mxc.as_bytes().to_vec(); | ||||
|         prefix.push(0xff); | ||||
|         prefix.extend_from_slice(&0_u32.to_be_bytes()); // Width = 0 if it's not a thumbnail
 | ||||
|         prefix.extend_from_slice(&0_u32.to_be_bytes()); // Height = 0 if it's not a thumbnail
 | ||||
|         prefix.push(0xff); | ||||
| 
 | ||||
|         if let Some(r) = self.mediaid_file.scan_prefix(&prefix).next() { | ||||
|             let (key, file) = r?; | ||||
|             let mut parts = key.split(|&b| b == 0xff).skip(1); | ||||
|             let mut parts = key.rsplit(|&b| b == 0xff); | ||||
| 
 | ||||
|             let content_type = utils::string_from_bytes( | ||||
|                 parts | ||||
|                     .next() | ||||
|                     .ok_or(Error::BadDatabase("mediaid is invalid"))?, | ||||
|             )?; | ||||
| 
 | ||||
|             let filename_bytes = parts | ||||
|                 .next() | ||||
|  | @ -42,13 +55,99 @@ impl Media { | |||
|                 Some(utils::string_from_bytes(filename_bytes)?) | ||||
|             }; | ||||
| 
 | ||||
|             Ok(Some((filename, content_type, file.to_vec()))) | ||||
|         } else { | ||||
|             Ok(None) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Downloads a file's thumbnail.
 | ||||
|     pub fn get_thumbnail( | ||||
|         &self, | ||||
|         mxc: String, | ||||
|         width: u32, | ||||
|         height: u32, | ||||
|     ) -> Result<Option<(Option<String>, String, Vec<u8>)>> { | ||||
|         let mut main_prefix = mxc.as_bytes().to_vec(); | ||||
|         main_prefix.push(0xff); | ||||
| 
 | ||||
|         let mut thumbnail_prefix = main_prefix.clone(); | ||||
|         thumbnail_prefix.extend_from_slice(&width.to_be_bytes()); | ||||
|         thumbnail_prefix.extend_from_slice(&height.to_be_bytes()); | ||||
|         thumbnail_prefix.push(0xff); | ||||
| 
 | ||||
|         let mut original_prefix = main_prefix; | ||||
|         original_prefix.extend_from_slice(&0_u32.to_be_bytes()); // Width = 0 if it's not a thumbnail
 | ||||
|         original_prefix.extend_from_slice(&0_u32.to_be_bytes()); // Height = 0 if it's not a thumbnail
 | ||||
|         original_prefix.push(0xff); | ||||
| 
 | ||||
|         if let Some(r) = self.mediaid_file.scan_prefix(&thumbnail_prefix).next() { | ||||
|             // Using saved thumbnail
 | ||||
|             let (key, file) = r?; | ||||
|             let mut parts = key.rsplit(|&b| b == 0xff); | ||||
| 
 | ||||
|             let content_type = utils::string_from_bytes( | ||||
|                 parts | ||||
|                     .next() | ||||
|                     .ok_or(Error::BadDatabase("mediaid is invalid"))?, | ||||
|             )?; | ||||
| 
 | ||||
|             let filename_bytes = parts | ||||
|                 .next() | ||||
|                 .ok_or(Error::BadDatabase("mediaid is invalid"))?; | ||||
|             let filename = if filename_bytes.is_empty() { | ||||
|                 None | ||||
|             } else { | ||||
|                 Some(utils::string_from_bytes(filename_bytes)?) | ||||
|             }; | ||||
| 
 | ||||
|             Ok(Some((filename, content_type, file.to_vec()))) | ||||
|         } else if let Some(r) = self.mediaid_file.scan_prefix(&original_prefix).next() { | ||||
|             // Generate a thumbnail
 | ||||
|             let (key, file) = r?; | ||||
|             let mut parts = key.rsplit(|&b| b == 0xff); | ||||
| 
 | ||||
|             let content_type = utils::string_from_bytes( | ||||
|                 parts | ||||
|                     .next() | ||||
|                     .ok_or(Error::BadDatabase("mediaid is invalid"))?, | ||||
|             )?; | ||||
| 
 | ||||
|             let filename_bytes = parts | ||||
|                 .next() | ||||
|                 .ok_or(Error::BadDatabase("mediaid is invalid"))?; | ||||
|             let filename = if filename_bytes.is_empty() { | ||||
|                 None | ||||
|             } else { | ||||
|                 Some(utils::string_from_bytes(filename_bytes)?) | ||||
|             }; | ||||
| 
 | ||||
|             if let Ok(image) = image::load_from_memory(&file) { | ||||
|                 let thumbnail = image.thumbnail(width, height); | ||||
|                 let mut thumbnail_bytes = Vec::new(); | ||||
|                 thumbnail.write_to(&mut thumbnail_bytes, image::ImageOutputFormat::Jpeg(75))?; | ||||
| 
 | ||||
|                 // Save thumbnail in database so we don't have to generate it again next time
 | ||||
|                 let mut thumbnail_key = key.to_vec(); | ||||
|                 let width_index = thumbnail_key | ||||
|                     .iter() | ||||
|                     .position(|&b| b == 0xff) | ||||
|                     .ok_or(Error::BadDatabase("mediaid is invalid"))? | ||||
|                     + 1; | ||||
|                 let mut widthheight = width.to_be_bytes().to_vec(); | ||||
|                 widthheight.extend_from_slice(&height.to_be_bytes()); | ||||
| 
 | ||||
|                 thumbnail_key.splice( | ||||
|                     width_index..width_index + 2 * mem::size_of::<u32>(), | ||||
|                     widthheight, | ||||
|                 ); | ||||
| 
 | ||||
|                 self.mediaid_file.insert(thumbnail_key, &*thumbnail_bytes)?; | ||||
| 
 | ||||
|                 Ok(Some((filename, content_type, thumbnail_bytes))) | ||||
|             } else { | ||||
|                 Ok(None) | ||||
|             } | ||||
|         } else { | ||||
|             Ok(None) | ||||
|         } | ||||
|  |  | |||
|  | @ -29,6 +29,11 @@ pub enum Error { | |||
|         #[from] | ||||
|         source: ruma_events::InvalidEvent, | ||||
|     }, | ||||
|     #[error("could not generate image")] | ||||
|     ImageError { | ||||
|         #[from] | ||||
|         source: image::error::ImageError, | ||||
|     }, | ||||
|     #[error("bad request")] | ||||
|     BadRequest(&'static str), | ||||
|     #[error("problem in that database")] | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue