diff --git a/db/main_images.sql b/db/main_images.sql deleted file mode 100644 index bc7179dd7f..0000000000 --- a/db/main_images.sql +++ /dev/null @@ -1,2 +0,0 @@ -INSERT INTO images VALUES('ed64aET6i379','png','z/dTlU0FQqgnmsIBRcLU5mU8OXg=','trilium-small.png',X'89504e470d0a1a0a0000000d49484452000000c8000000d30403000000366741f50000001d69545874436f6d6d656e7400000000004372656174656420776974682047494d50642e6507000000097048597300000b1300000b1301009a9c1800000024504c544547704c000000000000000000000000000000000000000000000000000000000000000000062bd2c90000000b74524e5300f02b14ca6145dfb37d989fbd378100000a8a4944415478daed5ccf7fd3461657adb5897d5ab70959e28b124402e522d2049270490a29747d5108d0b0b9b881241fca656143bdc117b30b14f02585ee872dbe00093fb63ea9756227f3cf55d248a39134bfb23bc36533177012e9ab9979effbbeefbd9135ed601c8cffb3617d048cfc918f00d200ff548e310140c7508ca1970100871583982e06702a4a3132de4400e8533f11772ab6ca89342008b8abd6b4e0e828dc95560802eea873768401baca7c653102019b8a30721806d85504328883005b1da344e3532520851806682b892b7371105057b1edb504c8ae4a6f0f870a2e6e2641c039f9ab554a81eca95f2d15849f5e2d00be941d494a0410d9ebf507028674fb5a248148b62fbd4404d953c95b68485daf6fb11bf763ffffab4c108ce5f7ac3935fc958db6c4d529190cd25062c09ea42f9454f07db4403039f9117dde9167c00db4587662f9da0ab6e46e726af248722231111cf69c742fe94bef92ac2c4247127823ad58bbb268be46b8614bb2becf9348642cfce12b3920e1fd1c83343d49e1f11691a8c2addf96551e80639ac8fe5d29725527ad56c4cc7262709642eb8329bbfe1fc6214a9a9895e9f32729594f489bbf4a94756d83927949898e35dabd26039f97412a54a70bfdd190472a1bd485fc6fcc4b1f1d1a1a3a9a8cef242234494e2ab43acb2f1f5ca8ae3dfecfd5c0934fd1293d98e46ffbc538b615125fffd3799ca3fae849f77ed96be136260fd7de6181639a6eddd8247577a5795cf6535c577766114539c4b031027f177e5cdeaa56fbab6b4f2fb130be4925205f8576ea180c1d0e7f37fe4331b8ac788f419a3752aabd630509699b957ff9367c1c5f05e7f93ea6d2d5f2251677949156bd9cb8f21fb42cdad2dfa7aa0e3d4c338509d81f353dbdd214173dfb46cbfc10ffd3c3a12f521cee93a060944ec0ef51c8e654e79996bb9fa837994cea28048ed293c418a8e864533e03dacfb5f106886552abf03f16ab98b7875727e15edadae7364dfaf4dada385e0d9a0e1c9e4ae725687ad98483cd6b933532c894fbeb3f55b41325bca6d56407a61634f44cbc4ee52efb0ca57ee8cf79c0d23e8ffe7a2360951d667eef0a9672dc7cf5fbb4cc381732a18981c02dfa8c0672364852f09dec83a998c1f2dfaf30a7b403b550676793afb0dab7b71637a84484caa56f343d4c0a2b41a66bb3ab08752cabec35fccd25080f08d244fb163a6525d851835d903e17e549fda17dd2e4ebadc80203a7346079b363b165c697484e769e6bb906d320d18677e7b56c0382946015822a08fc87f83e0471de69b9d7ece43bf25bd75dc6bddd30a0976d73b2efbe50093cb2f4179cbc052bfd0e18be5356b2bc92400b8240a6bc6b4594bfc9cb44dcb1ae794e1980dce188d85da8ca772d2c74d92295f2bbde1e55f2a8a0c24ac3f67c90ae118638ba05bba327512bfdc6cef3346204d2b1f1f5de13ac30bbab6ae47905ba4118a50f0167134bf83d83636f2346d8d0e058b9fa4800e20a1b7d4eac277126de22a94090b6c103b10ecd6afa0dc16a6e7cbdda361fc40c448da57d17973982d5f2f63c0c64ccdef858b8cb93b1b87547b036eb3c735d658637773300c997c5db6a5191ce9367f91af79289204cc5a33ca7766462f10d99fd2607c42bb64de2287fe32441e5c8635f33db7de31f6e03e7e27bf4d7c7817825d7441526935563d67f8aeb593718aca24fdcb42824ef58c539f564995642ce7d6f6133e7a7aa5325dfc775dc9a9357657e4c89df37ee1e96c5cb07977d72444bdc29a5034a3a93f14968aac412f471b76fb9a41d3e951b511ba91e6c9ed44e71e31cd4526205d67177ea6114058f7c36af1379c1593b7f21c273059b2722444b9f5654f37723ea587299035a68bf5d1a1a1d1a7e81e73d13f41c8b1e88bd630ad9e43afbbbee3c3c0ad7f00b64baaed4d25bdbc2e5c209dcac7ca3ee4be88dee7542147269312f5cce41e7530e23e9deb1634fb06e116a78fbab479a71355088db4c1338b31401b28f0a08ea27d5b1cfa8899129771e517b1fcff73d9181d893ee062b944f6160b9c69ee8b6870c1f59541627fca9472ced297a9e6535dd1a6906bac25f2e8b718d68c11b4dc44edacfba40fb43f0449e49eaf1f84fea6c72a491702b0d99d646ba1bc4a0a5682ad3fb70f6849885acbc6bf1a722d080427a36a933733301d372a7c2ef0d4d5297565fa8de2e160dae510a04c64586a8d1875796bc7f87d9791ab7c19915a1bad7063b85e21dc61c1461ba26392f400cc639578ace7031d9a1b5cd51eb6c87ece1667c3e4887a3d6f7441a329cb8d0a029f0b288a84739109b4bcb34af3e1582b05a5063620ddd32edc05d06293d8d9f970eb0ada3068e70bc8ce1f5c89dd85d3d9740ba3c95b3c3e5468e9875778e7674101118bd78b52816125ca7a3badb1c6fbdd06370ce891418ac33c13bd690170c3b3d0c0e44db4a73e741c1b34e632ca26d71b2ad9660941e61819c61970b7451ad39c78a04283f22cbbc82e8a1ad1693126acc453f2998bbea0de6115b36df3704337dcf8018dbf609cbe933a24233cb26b73c4be5f588eefb143b8aebac4ad1b7a247e64738b6d16018504354fc3739b6b1485f924800725493a7351cd6b69da547ae82687299e509851efaa698a22f189c61759f62b9709a689ba2e74d9bbc15cd011add47b5478e5cce7019343a2cdba51684fbf806fca9980a4d315c01aff570888ba3dab18afd2b4a9ec43979765c20ff68d10e2d2f0221b19cf5bca9b3c1370dd2d2633567164816f6ec7a6da13c2a69a9192002b2508ada114220713581f5d38fd02803efd43351162925fb31ac60394b42d14fbf88b756e6e915cc12e5cda193f80d668fa633d28564fdb4f38e32e3e132adc3117fc960e052ec06a3cbffae114ab45f2f9108e166acc5b1439418c1633eb91ace6674e5da568d7cdebdfd3609a32f6f250ede5b44e30a9bd1177ff9f9ca956b2f3f3cb80de863edc955cc7e4e5ffb907c1c5cd56489b728168b849faec76ed47ffee9cf5757965656aebc7c708150f7364871863b76add5e4599b627f7f7fb1487e516183a095b8c35de44c43fc91f032d049d16bfcb0992b8b837c46f451e6e8858e9e9d1106f99544ceccf1771763dc3851499e38628c6d42258139bcf367b986611e31b4dc5649707da9be481cce13c36f33192678e8eefe424d0804d35e028fd5f6b8ca6bc9b920e0a17bcdcdfbfb9cc977dcc7bab714b6fd2aa6d73bf11c7c81ff6cdd4b38cbbe674ffa9d4765fa0befaede4c60db413fc69bccfaf538b59d606cfe139f2d0393aac037a5fde36e5f3097a0fd2c150df49b14ebff1a3a47d80aaf9878d8d2a96bd6a6049c635b4906727adf1a892e6c05a966d8a9d1ff3293c2718a7f669cead4975f3ea8568bfea8569ffeeb7a9aa70d336539cb1faa21613bee756be8842e03687478c51d4b47c92aba6212cc531fbef6cbe3f3171fbb416849b83b474f5b3110e9ef33ea0490dd8f0122fd557cbd960691fed50591588e40e4bfbede4c834c4b07b99506a94b07194c83d8d2412652208e211d249f02694bc7887805812878e11b493a04f29b7c1064c308a4ae0064350952510052488028d8f7a8401e82eca80009b56c08525702321207319480e46320aabe112338696d2afac2029c23e14c947de14a0e9b89aad50a1232389357ca4026d14ce4bc29492ffcf920e73475632a00692bc4f0a7e281d45582781d2b1744f5976b5d06f648c7560c92796d9b6f34d5236b9cb6b48371300e86fcf13bd6f24b588e3a21ed0000000049454e44ae426082',0,'2018-01-08T04:41:30.663Z','2018-01-08T04:41:30.663Z',''); -INSERT INTO images VALUES('0mLHhGv61RDM','jpg','6Q2t5HZtcbb5Srph1ZjpyH7V5gI=','codenames.jpg',X'ffd8ffe000104a46494600010100000100010000ffdb01041000100010001000100011001000120014001400120019001b0018001b001900250022001f001f0022002500380028002b0028002b0028003800550035003e00350035003e00350055004b005b004a0045004a005b004b0087006a005e005e006a0087009c0083007c0083009c00bd00a900a900bd00ee00e200ee0137013701a21100100010001000100011001000120014001400120019001b0018001b001900250022001f001f0022002500380028002b0028002b0028003800550035003e00350035003e00350055004b005b004a0045004a005b004b0087006a005e005e006a0087009c0083007c0083009c00bd00a900a900bd00ee00e200ee0137013701a2ffc2001108012c00d103012200021101031101ffc4001b00000105010100000000000000000000000300010204060507ffda0008010100000000cf45d4192949ddd268c5933cd33bc52825299251384a9e55a1183294a2e9a29e6eacd8b4902c382ad5668453c994741d1e0f76a0babcaed8288a6a8d9e6daed0f956f38f31975596d7667b5dbcbe87a1c5e906874f95d9e75d2e783632e929ed694c849d32f5f9165e4e7a94a1d8cf43b591a8a4ef66565ce64651694651ae34b9cc0684da76666b25794c8e9421143ae18560a517b363ae6a88a693a74a2214615823a90789ba3e820736593ca6e9462a00566973035a32b1dcd7d66bf9dae59a7494471b9d51b0311584529f4ddbb3c4e67327da79251e1f0fb7aeb74d757cc455cd3b67375e9f271cb79da7768f9bd2eaedfb172ae7f8821235c25999b918d5abd64926f36a1ded8169d4855acd0b364b6086ab95ad7b7f276064335e8170500041510ed9ac14cfceeb7131bea379f09c2e869b3fac90215874c4ae12d4ec67b9dc975eb275e3aac75389afee8235474c4d70b6a5cec99aaad26f675bc914ac591ebad42ac2989ae12d4f8f77235adfa65b9f3fca924968b4b0ac3a8285d25a99f21c55aed79659ef3c492e8f4b490ac3a818dc2d999f13cd5daf4224e8795a49bd28808d58530c6e16c90f85a297a7de9af34e4a4bd20d5e35474c51b560c726228a5b4d43bf1bcebb1c65e8c510801a91158b45b32c3554bbbbb93b79e51aabd25a35c75ab308970a72e4398969364e9797812f49842b42a0603259b24b39ce025a2d8bbb6178aadef156182a8811396d94b571a969b52e96238cbafb1006150200c6c10f6e46c78eaea34ee96039cb57d70b56ac3ab169d89d8b4fcbe15ea9bd92584a0b676a20ad0ac1498a7258b15f1fa7cc6e3a2ed83a4fb9902b8c359266731e663e2f678ad4f5d2c456bdac00602ad07834d239e44ccec71ba6e928e0d74bbe3886bc141929a463cf33a8e0772ea06455bd14001838d924f34a752b68383d3e820e5d59eed7141a2d223c129bc036cbc1e875d433095c2e93974dacd72c65064f376a4d78a973691edc7b94e8499cae9e314a527749d30e1319e334853766930d274e9d2664994e51525fffc4001a010002030101000000000000000000000002040103050006ffda0008010210000000e399e8eee98818b3a60223a4e7ba0a0442238a4c8ba429a290023b6fbac91aeb553a866cbd962f20a791554197add22eb2a516af77cc265eb72ee3beea535276f17136377045b76ea935f66df3d8fee7aac165db812a36eaf207ed3871e1dbc534f77bc707b53cccd71cbe144f6cfcce7ef6c66e7b8e5dcaa9a96f9e4353772d571aba565ae6f0947f6b2b9966c9a97a9a5b35ed3ccb59b8b86aa4a5169956eb8fa2440629bcc0ca784a60604a7aae60008a7bbbba06063fffc400190100020301000000000000000000000000010203040500ffda0008010310000000dc11927bb8066e4aeeca92866884cd0c3c248b886469c991bb958711c892256b53af7732109354a572661d17679d9499a3832349fb32fa59b1ccc9532ad5882a6a597e0e60c64b4f4b9b666e57306235e86a71d4b9c18c786ba29445cd172acc982b7e5a75ee6938e0e3121d09ead2bfa0405739d474a6ad9fab6808d6631e64d7e9e7edb746a924a28c7a546aec72c684b8ac2f50adad0f24af1b0eab7ea51b75a7abb5dd1862447d1192c7ffc4003b100002010303020404020a0103050000000102030004110512311021134151710620226114322334425272738191a1b13515246225638292c1ffda0008010100013f00acd62b20516f9315b6b6d6d15b456d15b456cadb583f20340d63e5c516f902d014b1b3ac8ca321065bec09c66a58668481226dc9c514906dc82370057ee0f151d95cca5c2c64946dac3201cfa77a31385dc5481b8ae7ee39150da4f3e7c28cb63d857e1272db7677d9bf1903e9f5afc2ce0484a91b0b83ee832451b1bb001f0c1054b0c32f0b4ea5199186181c1a2b457e40df293d40a000acd609ab694c12ac8003e454f047a1a69e29a1559848640eedb971825ce4d3dec32bc0e606cc24ecee38f207da9eea2943e61901668dce1b968c11535d89a0788c27b9de1b3c3e724e2a368bc1f0668dd9449bd76100e7823bd35f3988c41088cdaf858edcfae6a3d4990ab3c5bc8014f7da08f3cfdcd25d24662db1b6d8e29507b393574f0cd2b488b202ecccc1b1c93e58ac566881457a83d30689e9a768325d46279e4f0a23dc7a9143e1fd367045b5f12feead4da75d2defe0f6665fb718f5affa0595baa9bcbdc13e84255de8612212dacde2ad691a7437cd3894b8080636d0d1b4b72c91de36f0718dca6af34e92c986ec321fcae3834ba3592c114b2dc3206504e481cd4961a5a46ecb7b9201c0deb4f6320b286e97ba38fac79ad5ac2b3dcc511c80ed8c8abfb74b5ba785492005ee7ef56764d76650bfb1193fd7c8514069b4f7364b749dc6e60e3d28a55ad83dc453cc72238918e7d580ce2a0d0ac4d9c1712dcba6f442ddc01de9f4bd142391a864ff001a569ba67e38bbbbec8931bcd4fa5e96f6d34d697e098b90e7a0359e96e8b25c431b70d2283ec4d7c4733a2416c32118b335248f13abc6c55d4f661c8af85d379bc9dc969090326ae6692eae659a4396663fd07a0ad05d9677849fd1b297f661e75a7c6916a5a9a8185fa4d4ff00accffcd7ff007531375a207932596327faa9a9eda1b9d3ad92697628087391e9575a759c103c915d0771c2e4559cf1dbd840d29fa31b08f4c93de869fe05e5adc44bfa22e3239da4d6b03ff519bf856ad1a3d36ce1671f5cf28cfd81ad5ed7c0bc665fc92fd43dfceb499238b4b2d2e366f606a7d0dcdd28886207ef9e7655d7851585c430390b1864200f3dbc51b686e744b68a697c34314596abdd234f82da5962be0eea32172b5a3dedbc3e2dbdce04721ecd579f0e3ecf1aca5132721688f9172082391dc518ad75cb088452049e2ab6f8667f141b99504439dbc9ad3aeecf4ed4a786394b5b3f6de7c9855de84cd3492dab26c639da6a1b48b4e49649ae137ec2b81df07915a2cd2cb757933f2e149352e9b378cc4b2e1d8b0dbf7aba748a07b64e4e01ef90147ffa6aead5eeac2d634c64043df8e29b4a963eec631819e69c13a44791db70c7f7ad3efcdbe2290e62f23fbb5716e2e7572395c293ec054e2c1e42973313b18818dd57821bfb26f009630f07d48a8bfe027f76a8f549e2b4687b9931b51fd16ade43f80b988939259bd7cbbd4d6af79a35ac298c948f9e29f41bb4e4c23b679ab0d212fe094a5c813af11d68ba75f69cf2c97322c70ece3755e3a4b7571247f91a562bec4f50289a466460c8c5587041c1a6b8ba986d92e2575f42c4d2a802a29ee23c78734883d01344bc8dba46666f52726a232a67648c99f438acc87995cff5340015e3dc600f1a4c0c606e3e5466b839ccf21cfdcd65f685dedb7d33dab14ad2a1cac8ca718ec6bbf727bd2c92264248e99f438a264d8631236c3cae7b5321a25c2950ec01f206bf1174aa104f26c1c2ee38a6babb6e6e65ff00ec6886460cac411c1070454b717128c493c8e3d1989140d30f915734a30280cd2ad2a75028293410d7875e1d6ca2868ad63a32532d118a2334eb8a23a63a0148b8a8619677db146ce7d00a8f44be6e5517ddabfe8f78832115bd8d3a3a36d652a7d0d014a84d0402bb0acd64d64d66b228a834c94474650699688c530c8a65c74c8e88b5636a6f2e63841c03dd8fa01505b436b16c8d02a814d713248ca4c6143000907b6467bd5bdccd2c806c1b7cfb1f4ce735736d15c4655c7b1f314f01864646e54f502b69ad95b6b6d11d5968ad470cb21c2216a3a55db0fca9fd5aa7d32f62c930311eabde8f6a91688e8a287615a0ca915f7d7fb6840ab89a48de2da7b1e46324d47712b84dee06464fd39c9f4a8ee2e498c3fd39e7b7d854064dac5db386238c706af64125cc8578e3fb501416bb0e9debbd66bb1a2b4474b3b45b9725bf22f3f7a9e64b6db18886300a81f63dff00b7342f70acc22fa01e777739e08a5d498aeef046002c7eaf218e2b56d2e3b98da58d40987f9ae4538c1e883a460e462ad35774c09cb30f5149a9593f130a5b885d1dd1c305e71575a9b4a0a440a83c9f3a0000492001536b9650b6d40d2fdd78a835cb39982b6e88fab7140562b158ac562b53d5c5a318621997cc9e050d76ff007025908f4db565ab4376c232bb243c0e41ad29d76c89e61b3577204d876a1ecdddbbf029ae63dedb608d8a8558c918cf9114b36fb8456b68d4eef319238a96448a3791ce1541269b927d4d38c8e83b0a51518e882ac274899e373859062b61562a790715ae239b30558850df50eba1ce67b1504f78ceca0075c515ad4675b8bd9e54ced66ed9e9a2a6fd461fb0634acf138743822adaf96e1c46e8771feabda9ae6d51b6bc91ab2f2091daa6d4ec13bef0ec38da335a86a135e0d98d917a538a3c563a20a5ec294520c0a14a2b5d2ff82ecc029701bafc30dfadaff01e98ac563a6a76ff0086be9d3cb76e1ec7a6810335d34dc2c6bfe4d30cd59148e6699ce16353fdcf6152b195de461dd8934c2b914e2bcfa0e6a31d107451d2f2d7f176ed0efdb920e719e2b51d265b29608d4b48655caf6abad3af2cc033c252b40b910df043c4c36505ac56051153491c31b49238541c935ab5935dc0baada93244e009479c6452233b0545258f6007735a7dafe12ce28c8fab96f73d1c7471dfa4829ba2d462873483a20a6654566638551935a4adc6ab76ad3cc62b7e5221d8c8055e5fd8e9daa99e797c498858a38d38863af8bafd65ba16917118fd21a0706b4d7925b1b5790e58c609358ac55e7c457a659560d8881880719353dd5cdc9ccd33bfb9ad1b579b4a9f70fae16fcf1d6a074cb136daad959893c60e3d1013516bf7825dd20474f35031514a93451ca87e97008a61dabce9c76a3520ed4f59a4a4e296938a143b0ad5b528fc37b688e58f673567a9bd85bcde013f899be9327ee20f25a666624b12493924f734cccec59989627249a556765551924e00a82210c31463f61157fb0a029bb2b1f40689c93d23b4b9990bc50b381cedee45584e65b0bed39fcd0cd17d9e3ee4515600120804647dc5696d3da58efbb1e1c05c084b7249af2a34ddc53537714fd12938a5a5e297cab57bf6b68c451821e45fcde82a28a59e458e242cec7014724d5d59dc59b88e78f63919db904f5f876c0cf71f8971f445c7dda850abf94c1657328e522623aa3bc6c1918ab0e083822a4bdb99274b8794b4ab8fa8fdab4dd4058ce92bc0930456015eaff51bad466f16e1f3e8a385ad2ee3f11651b13965fa5bdc5373478a6a3c53f45a5e2968714bc8ad76dde48a195549d84835f09416ca9797724a88ebf4027f62af14add4c1a7598ef39914e43f4b2b392f6e1214f3e4fa0ab5822b6852188615450a15ac7fc5deff0028fcff000fcf896580f0ebb87b8a7e6bca9bce8f14fe7d12978a5a5e297a6b2f1a4cd024112e0872e170ddc75f85e2ed7537b250a142be2799e3d3820e249003f349a55f46a1bc12ca40395ef5a3e9b72b3a5cc8bb157807934fcd795351e29fa252714b49c50af2ad5ce7509ffa75d0af8dadd846388e5c2b50a07a6a967f8eb2961fdae53dc51041208f960398213ffb69feba351e29a8f14fd16a33da8521e8a7b56a7fafdcff0019f92c2e3f156504de6c833ee3b1a0681acd6b5008352b8007663bc7ff002f96dbbdb41fca4ff547b0a34e7b53539ec69cf45a8cf443d10d6a7fafdcff0030fc9f0ccf982684fec3861ecdf26b3a68be83283f4d1f74a23153e9125ae9b1ddcf22a3c8e36427f315eb67faa5b7f2929cf4735e7521a7358af3a43438a5343b8a157cdbef2e5bd656f93e1e9b65fecf29108a06b756eacf15692d9db5edc4d7085cc5b8c51f93be7b66aeef2e2f6779e77dcedd6dc6cb6807a469fea98d7029cf490f7a3cf4f2a43487228521e9ab4090ddfd03019777c9f0e450bcd33ba65d00287e5ba52b7338230448dfefe4e1147a28e8e68d31c0a735ea6b34868546dd14d29c8ad7930f03faa91f27c39fac4ffcaa0d5bab756ead7c11a8b1f545eb6112cd79046e32a5bbf4270298f490d31a63815b8d29e88691b3d11b15a9dab5d5b6131b90ee1f27c3b0c9ba69b1f4636566b359acd6bcfbafd87ee228eba2445ef43f922935c53b668d31c0a76e921e8290d0ed48d4a722852362b51b7fc3dd381f95bea5f635676ff8991a3fda28c57dc51ec6be1d9c013c3ece2b22bb576adc056ae73a8dcff10eba145b2da494f2effe053bd1347b53b531a63814c7aa9c50ef4a691a810681ad623dd6e9279a37f8356939b7b98a5fdd6ad62dc4375bd3f24a370ab1b936b731cbe5c37b1a0c08041ed59acd66b54ff90b9fe3eba77d3636e07eed135c53bd335714edd30688e88dd14d23e28106af90bda4e3ff000cff006efd2fa332e9919f38d51ba6953f8b630e795caff6ac8ac8adc2b5170f7d72c0e4173d154bb2a8e49c5468238d1070a00a240a77a66e8ed44d0e80f547e81a95e8306183e74ebb1d97d09141375a843e7163fc74d14e2d0ff30d66b359abc2ad75395e0c8dd34d4df7b0fd8e699c0a67a66e8ef44f427159e9cf40691e860d038a0d528dd72e3d643fee95c0c0ab84d93cabe8e45694a16ca3fb926bb576a760aacde809a27249e9a5e05c9279d87145a8b7477a27a7144f506b9e80d2be29581ac8009cf614edb9d9879b1350cbbe3463e6a0d5f802ee4fbe0d583ffda43ec6b79ade6ae5c8b79bf81bad96ff00c4c7b07bfb57bd160299f344d735c513d48e80d039ac50340d5ddd653c343cf26a3b73245bf3cb003dcd22aaaaa8e00c55f906e5ff00a0ad3a4cc1b3cd4ffbac9ac9ab8c9b79bf80f5b69cc1286f2e0fb51972320d4926d193dea3792762b141239f451bbfd53bb46c55e37561c861835e2f6cec6c578db8e029a2e579461ef48dbab6f423a8358a740c369a16b17fe54a1555540ec38af130339a76323b379b1ad3b2af213c6315e20af1053b86465f5047c915db280ac3229e74910807bfa1ad4ef27d24416164de10112bc8e39766a9b52b9d41218eeb6c862c91263eb34af33fd41d47dab749139c6d05fcfd2916420acb22329fbf71508c29f7ac8e9cd11d41a041ac5771535c33028aa7156b11de1d8600a846c4c1e4924d6eacd6eab983059d718f31d1645600483207047342d61600827bd3c11a2e467342ff004ebe8208f52495658936a4d179ad5e5c69c0451d85bb8d8496964fccf59b727386f6a1246ccde22763d811e54c6dd518202c4f99f2a87f21f7e98ea57e4c915bab35dab03a62b02bb534509e50508a15e105669c12b8142e1fb9304649393bbbd78f21393121fa76fb8fb915e3c84fead0e3d314b3ca872218ff0036e1e80e00a37129e608b34808dc48032c4e07ca288f9f26b26b26b26b27e603e6ffc4002d11000202010205030303050000000000000102001103041205102131514161711320322242622330527291ffda0008010201013f000254ae772e5fd950895cac4b137426599b8cddd60680cbe75c81025f7972c8bbed18ff001b9bc5a83e0407ab19fbbdaa0610197eff0061319a3398ce7cc394f99f53de7d43e60c87cc578af14f330f58554f99994e3f70633c2f37cdf15e2bc4dc7d2293019718cde3cd4b07f7cd4e60c0229bf78d833edddb0d4266e1374c5a4ceea180001ed730e32b98264147bd4268c1d44432e398e61c85581130b5ea12bcf2d6a84d4e403b5dcb10198abe963dbda854d6e4ad40a3d401135246352dd49306666f68865c731cc7334f872646dc842eda36626e0a01367cce2d868a6507bf4225cc1c2b2b51c8e02c03620551d00a1351873637df92bf51bb110c4310cb8f1e0c6d95c22f7331615c49b47c9e5c5f38674c40fe3d4c4059d07a96020e59712e542adda6d28eca7b83531c4e4f3245c871645702ea636deaaf55b85cd565fa381dc771da6462cc598d9334885f53840ff31cd9d548dcc05f6b3357b0e7254dd81751263e4f3247987a62c7fe8265c6b971b237622a6442acca7ba920cc6cd8dd5c1a2a41131b8c888e3b30079712fc71fcc4ef31c4e4e2388e263e889f039711c5b752dfca8ca3384e5728f8c9b0b4441388fe09f3104c6220951c4711d6606dd890dd9e5c4413a93d7d04da670b3b72bad771cb5e4138d7c5988b104412a308eb1d6695c8b43f2258b23d44d68639dec4a9c397facc7c2f2d49df98f81d222c458a3918c23ac5055d4fbc73b722379e866b710215fd7b19b26854876f886116ec7c931562ac039911961599ac8499fae31ee44d934c9458c7fc5be22a455807da442b1c0351d6d07b4d9310a061ec60582a065f432ffef2be7508866d8057223a18dd8d7798ac38ae9ef532302547723d6e5c065ff66a572b9fffc4002d110002020103030302060301000000000001020011030412211031415161711332142022233352438191b1ffda0008010301013f00ef0b012cc020db7df99b904dc2bda6f4f512d4f630a9e8181ef3b4b85a1cc80d5c3971ad7364f6a9f553696bed15f1e46f4303e127cfa4031ec6a3c026e6dc5b37783cc2a8841befc42c10593c439f19ed77f10e4556af3034e21b331be3442adc117710aae562dc0602899929bea32fdb4046a718c2f2c08330f1fe5dbcf69b1eb23273c904463698928f604d0858be1453c10e018c99481bcf0a40131704fee6dfd47899182b3157a6f20f99cd032e08a83b910aa91db89b4555713681e26c4fea3fe414250bba9b16eea509b13fa88501375089b620b333ea062a502da7e27377a5aef306a17358229878ebc4e3ab64c6a79603fdc5756ec411ed187451426a34eccdf5145f1c88770bbc55f2269b0b21391c57b439f1dd6f1f91b5288d5dfe266cb780b633fefd201605ad9f99671ba951467712bae441914a9ec667fe26f8e98989c6bd5af7b5f7b334a07d2208e0930e955b2b004800098f498f1907ee23d7a541d0ccf9531ad30bdde21367814269dcd15f4e65c3a803b0b9766cf99872230dabe22fe410ccce114b1ec265c872359e9814804fac63c1ea8ed8d81131b6e008ec60ea2199906452beb1d76b30bba3531a867021151fed3d4293742ea69377d3162bd20ea3a34c9f7bfc98ac54823c4b0403eb196c1841048f4e9a4fb9e2c1d4743da3fdedf27a60378c7b712a6a14020f9304d1fdcff020fcb70ccebb72b8ae2fa69c7ed09466a97f483e87a6897873f020eb710c07a6b31f671f0651a07c19a7fe25e9aafe31ee7a6956b10f7e7ab1a12e29a32ec4b99806c4e3da635df8b20feb4c268dcdb278ef2e6b3ec5f98220da8a3d001d58f4115bae9545e5f4ed34a08cc7d81e9ac3c209885e44f91d4984d7ccb32a8c06fe602664caa8849efe26955ad89ec4033090350fef7d359f72fc4c6407524d00442c0026f813f118bfbc6cd8d45968b911cf0d666d30807e65180c38d18d900c775c6bff008260c6dbd5cfbcb9aa42c030f1700b3dea15ceb8dac82b530b2ae542c38045cd5321d390cdbdac1146e68148ca4f607c57422a55c22ba5cb1e938963d2109df60ff9186e054f6306910f930e931fa998f4c887702654ffd9',0,'2018-08-30T07:53:53.162Z','2018-08-30T07:53:53.162Z','yi8WmKQdBO'); diff --git a/db/main_note_images.sql b/db/main_note_images.sql deleted file mode 100644 index 7d99174ceb..0000000000 --- a/db/main_note_images.sql +++ /dev/null @@ -1,2 +0,0 @@ -INSERT INTO note_images VALUES('2EtgRRPfk4Fi','1Heh2acXfPNt','ed64aET6i379',0,'2018-01-08T04:41:30.663Z','2018-01-08T04:41:30.663Z',''); -INSERT INTO note_images VALUES('T7qQAw9BVi0E','prjUbW6QtsL4','0mLHhGv61RDM',0,'2018-08-30T07:53:53.165Z','2018-08-30T07:53:53.164Z','lSz2qni/Rx'); diff --git a/src/entities/entity_constructor.js b/src/entities/entity_constructor.js index a890899cee..f96979a037 100644 --- a/src/entities/entity_constructor.js +++ b/src/entities/entity_constructor.js @@ -1,7 +1,5 @@ const Note = require('../entities/note'); const NoteRevision = require('../entities/note_revision'); -const Image = require('../entities/image'); -const NoteImage = require('../entities/note_image'); const Link = require('../entities/link'); const Branch = require('../entities/branch'); const Attribute = require('../entities/attribute'); @@ -12,8 +10,6 @@ const repository = require('../services/repository'); const ENTITY_NAME_TO_ENTITY = { "attributes": Attribute, - "images": Image, - "note_images": NoteImage, "branches": Branch, "notes": Note, "note_revisions": NoteRevision, @@ -42,12 +38,6 @@ function createEntityFromRow(row) { else if (row.linkId) { entity = new Link(row); } - else if (row.noteImageId) { - entity = new NoteImage(row); - } - else if (row.imageId) { - entity = new Image(row); - } else if (row.branchId && row.notePath) { entity = new RecentNote(row); } diff --git a/src/entities/image.js b/src/entities/image.js deleted file mode 100644 index 1de18164dd..0000000000 --- a/src/entities/image.js +++ /dev/null @@ -1,42 +0,0 @@ -"use strict"; - -const Entity = require('./entity'); -const dateUtils = require('../services/date_utils'); - -/** - * This class represents image data. - * - * @param {string} imageId - * @param {string} format - * @param {string} checksum - * @param {string} name - * @param {blob} data - * @param {boolean} isDeleted - * @param {string} dateModified - * @param {string} dateCreated - * - * @extends Entity - */ -class Image extends Entity { - static get entityName() { return "images"; } - static get primaryKeyName() { return "imageId"; } - static get hashedProperties() { return ["imageId", "format", "checksum", "name", "isDeleted", "dateCreated"]; } - - beforeSaving() { - if (!this.isDeleted) { - this.isDeleted = false; - } - - if (!this.dateCreated) { - this.dateCreated = dateUtils.nowDate(); - } - - super.beforeSaving(); - - if (this.isChanged) { - this.dateModified = dateUtils.nowDate(); - } - } -} - -module.exports = Image; \ No newline at end of file diff --git a/src/entities/note_image.js b/src/entities/note_image.js deleted file mode 100644 index 584a9241a3..0000000000 --- a/src/entities/note_image.js +++ /dev/null @@ -1,49 +0,0 @@ -"use strict"; - -const Entity = require('./entity'); -const repository = require('../services/repository'); -const dateUtils = require('../services/date_utils'); - -/** - * This class represents image's placement in the note(s). One image may be placed into several notes. - * - * @param {string} noteImageId - * @param {string} noteId - * @param {string} imageId - * @param {boolean} isDeleted - * @param {string} dateModified - * @param {string} dateCreated - * - * @extends Entity - */ -class NoteImage extends Entity { - static get entityName() { return "note_images"; } - static get primaryKeyName() { return "noteImageId"; } - static get hashedProperties() { return ["noteImageId", "noteId", "imageId", "isDeleted", "dateCreated"]; } - - async getNote() { - return await repository.getEntity("SELECT * FROM notes WHERE noteId = ?", [this.noteId]); - } - - async getImage() { - return await repository.getEntity("SELECT * FROM images WHERE imageId = ?", [this.imageId]); - } - - beforeSaving() { - if (!this.isDeleted) { - this.isDeleted = false; - } - - if (!this.dateCreated) { - this.dateCreated = dateUtils.nowDate(); - } - - super.beforeSaving(); - - if (this.isChanged) { - this.dateModified = dateUtils.nowDate(); - } - } -} - -module.exports = NoteImage; \ No newline at end of file diff --git a/src/routes/api/cleanup.js b/src/routes/api/cleanup.js index 16932ef0c0..01ef083766 100644 --- a/src/routes/api/cleanup.js +++ b/src/routes/api/cleanup.js @@ -2,25 +2,6 @@ const sql = require('../../services/sql'); const log = require('../../services/log'); -const repository = require('../../services/repository'); - -async function cleanupUnusedImages() { - const unusedImages = await repository.getEntities(` - SELECT images.* - FROM images - LEFT JOIN note_images ON note_images.imageId = images.imageId AND note_images.isDeleted = 0 - WHERE - images.isDeleted = 0 - AND note_images.noteImageId IS NULL`); - - for (const image of unusedImages) { - log.info(`Deleting unused image: ${image.imageId}`); - - image.isDeleted = true; - image.data = null; - await image.save(); - } -} async function vacuumDatabase() { await sql.execute("VACUUM"); @@ -28,13 +9,6 @@ async function vacuumDatabase() { log.info("Database has been vacuumed."); } -// Running this periodically is a bit dangerous because it is possible during the normal usage -// that user removed image from its only note, but keeps its URL in clipboard and pastes it into -// a different note. If this cleanup happens during this moment, we delete the image before new note_images -// reference is created. But currently we don't have a better way to do this. -setInterval(cleanupUnusedImages, 4 * 3600 * 1000); - module.exports = { - cleanupUnusedImages, vacuumDatabase }; \ No newline at end of file diff --git a/src/services/content_hash.js b/src/services/content_hash.js index 535fa324b7..d3320a0573 100644 --- a/src/services/content_hash.js +++ b/src/services/content_hash.js @@ -7,10 +7,8 @@ const eventLogService = require('./event_log'); const messagingService = require('./messaging'); const ApiToken = require('../entities/api_token'); const Branch = require('../entities/branch'); -const Image = require('../entities/image'); const Note = require('../entities/note'); const Attribute = require('../entities/attribute'); -const NoteImage = require('../entities/note_image'); const NoteRevision = require('../entities/note_revision'); const RecentNote = require('../entities/recent_note'); const Option = require('../entities/option'); @@ -38,8 +36,6 @@ async function getHashes() { note_revisions: await getHash(NoteRevision), recent_notes: await getHash(RecentNote), options: await getHash(Option, "isSynced = 1"), - images: await getHash(Image), - note_images: await getHash(NoteImage), attributes: await getHash(Attribute), api_tokens: await getHash(ApiToken) }; diff --git a/src/services/sql_init.js b/src/services/sql_init.js index f12b231582..c9648ca326 100644 --- a/src/services/sql_init.js +++ b/src/services/sql_init.js @@ -73,8 +73,6 @@ async function createInitialDatabase(username, password) { const schema = fs.readFileSync(resourceDir.DB_INIT_DIR + '/schema.sql', 'UTF-8'); const notesSql = fs.readFileSync(resourceDir.DB_INIT_DIR + '/main_notes.sql', 'UTF-8'); const notesTreeSql = fs.readFileSync(resourceDir.DB_INIT_DIR + '/main_branches.sql', 'UTF-8'); - const imagesSql = fs.readFileSync(resourceDir.DB_INIT_DIR + '/main_images.sql', 'UTF-8'); - const notesImageSql = fs.readFileSync(resourceDir.DB_INIT_DIR + '/main_note_images.sql', 'UTF-8'); const attributesSql = fs.readFileSync(resourceDir.DB_INIT_DIR + '/main_attributes.sql', 'UTF-8'); await sql.transactional(async () => { diff --git a/src/services/sync.js b/src/services/sync.js index 10407bc2c3..73178f9c7e 100644 --- a/src/services/sync.js +++ b/src/services/sync.js @@ -243,8 +243,6 @@ const primaryKeys = { "branches": "branchId", "note_revisions": "noteRevisionId", "recent_notes": "branchId", - "images": "imageId", - "note_images": "noteImageId", "api_tokens": "apiTokenId", "options": "name", "attributes": "attributeId", diff --git a/src/services/sync_table.js b/src/services/sync_table.js index 742edc6f0c..3f73872967 100644 --- a/src/services/sync_table.js +++ b/src/services/sync_table.js @@ -32,14 +32,6 @@ async function addLinkSync(linkId, sourceId) { await addEntitySync("links", linkId, sourceId); } -async function addImageSync(imageId, sourceId) { - await addEntitySync("images", imageId, sourceId); -} - -async function addNoteImageSync(noteImageId, sourceId) { - await addEntitySync("note_images", noteImageId, sourceId); -} - async function addAttributeSync(attributeId, sourceId) { await addEntitySync("attributes", attributeId, sourceId); } @@ -108,10 +100,9 @@ module.exports = { addNoteRevisionSync, addOptionsSync, addRecentNoteSync, - addImageSync, - addNoteImageSync, addAttributeSync, addApiTokenSync, + addLinkSync, addEntitySync, fillAllSyncRows }; \ No newline at end of file diff --git a/src/services/sync_update.js b/src/services/sync_update.js index 70b02ce84c..6db5cd9bb4 100644 --- a/src/services/sync_update.js +++ b/src/services/sync_update.js @@ -27,12 +27,6 @@ async function updateEntity(sync, entity, sourceId) { else if (entityName === 'links') { await updateLink(entity, sourceId); } - else if (entityName === 'images') { - await updateImage(entity, sourceId); - } - else if (entityName === 'note_images') { - await updateNoteImage(entity, sourceId); - } else if (entityName === 'attributes') { await updateAttribute(entity, sourceId); } @@ -156,38 +150,6 @@ async function updateLink(entity, sourceId) { } } -async function updateImage(entity, sourceId) { - if (entity.data !== null) { - entity.data = Buffer.from(entity.data, 'base64'); - } - - const origImage = await sql.getRow("SELECT * FROM images WHERE imageId = ?", [entity.imageId]); - - if (!origImage || origImage.dateModified <= entity.dateModified) { - await sql.transactional(async () => { - await sql.replace("images", entity); - - await syncTableService.addImageSync(entity.imageId, sourceId); - }); - - log.info("Update/sync image " + entity.imageId); - } -} - -async function updateNoteImage(entity, sourceId) { - const origNoteImage = await sql.getRow("SELECT * FROM note_images WHERE noteImageId = ?", [entity.noteImageId]); - - if (!origNoteImage || origNoteImage.dateModified <= entity.dateModified) { - await sql.transactional(async () => { - await sql.replace("note_images", entity); - - await syncTableService.addNoteImageSync(entity.noteImageId, sourceId); - }); - - log.info("Update/sync note image " + entity.noteImageId); - } -} - async function updateAttribute(entity, sourceId) { const origAttribute = await sql.getRow("SELECT * FROM attributes WHERE attributeId = ?", [entity.attributeId]); diff --git a/src/views/dialogs/options.ejs b/src/views/dialogs/options.ejs index 38070c575b..d930bdbaac 100644 --- a/src/views/dialogs/options.ejs +++ b/src/views/dialogs/options.ejs @@ -164,14 +164,6 @@
This action will create a new copy of the database and anonymise it (remove all note content and leave only structure and metadata) for sharing online for debugging purposes without fear of leaking your personal data.
-This will remove all image data of images not used in any current version of note from the database (metadata will remain). - - This means that some images can disappear from note revisions.
- - -This will rebuild database which will typically result in smaller database file. No data will be actually changed.