Archived
Merge branch 'pr/556'
* pr/556: Add translation strings Display Last Seen value in the UI Add /rest/stats/node endpoint Add stats package and node related statistics model
This commit is contained in:
commit
00b662b53a
10 files changed
+189
-9
No files matched your search
+3
-3
@@ -28,7 +28,7 @@ func init() {
|
||||
bs, _ = ioutil.ReadAll(gr)
|
||||
Assets["angular.min.js"] = bs
|
||||
|
||||
bs, _ = hex.DecodeString("1f8b080000096e8800ffec7d7b73db4692f8fffa1463febc016953a06c675dfbb32ce71cc5ded3c6b15d969dbd2a457b0592431211083000289967ebbb5f77cf009827084a4a76b7ea588945627a7a7a7a7afa350f8c46ec385b6df278be2859ff78c01e1f3cfa96fd2dbac8c6ecfb2c9fb3289d02445ae6f1785d6679c1fa05e7ac5c7076fceeedc70f27df7ffaf8eec3299bc5091f847b80ee6592304257b09c173cbfe4d3907d2a38cb66502d2e5891adf30967936cca19fc9c67973c4ff9948d37d018fbe9e4e37e516e128eb89278c2d3029b8b4a3681d23167b36c0d24c529d1f0e6e4f8d5dbd357d47cb8b7377af06b91c469c9c67976056d3f6365bee643682b2de374cdabdfab645de0ffe2377b30829af3241b4709bbff8ccda2a400a0289daf932897bf11682f58c3970278312983c3bdbdcb2867c5269d40b7d2393baa6a84cb6cba4e783fa8cb82213b0b565131899255ce278b322cf3282d92a8e4c1f9e09010adf3641c01fa231600df087f5d3f840ecce2797fb686077196b2fefd4559aedee7d9653ce5f990ddaff155cf06eccb1e838f06184ef92c5a2765117e2ef2d97ff2089ebd8d96d4e87fed1f9f7e78bdff31bbe02934bea5ee71965dc4bcaaabd514552d8242e0dd691995f1e4350c56f126c3c6fb8248fc006366f1e7672c48808dfbc1b02e28d6335110fe5a646940cfaf8169f8bfcea232cf92049006af2e795a1e9779028c5778564cb2150c2c75abe60f3d0c93a828a91674275d278960008e0b969cfc008f0f64d768d4d793092f8ad7293c6f1a98466554e15570dfe7cbb8ec079f4edea5209c3c181cd610f59778c6fab2a517ec4045821f441cceb2fc5534592842c0916013163fc08b2283199164f37e8fa07a43467fc3785a7d2b37c80cf19d283fb4f0681db06a1915ae95dfd792571e0e637367d4a984a7f372c1f6d9a3f3a676cd72b32a50af202e78f9315ef26c5d2a3c31d941831dce79d9af26d843168c88fee2bb224e27fc288047a2c981563594a3dcaf47db28e7799ee57dfa17ca94de0fd99f0f0ee4836b456c24e86e42339b79a5e6f61c486268e6e85170773d7f7460757d470ada5ab75a6ed102a7d5d3764da06a4ff89e649308a12a36e2b8816ebafc018a8516a89e4287defd088fd086344fd3e8329e038674fef22adae050a3f968ca335202f67354fa515e0a4b22ca70a8552535c996ab8453178ed897eb43bd0c2d84eff9498accd0686dca534e6c29eccac4667c7e76ae3d0703c7131b7cb9a1591b04dad314801d3856795666932c395e80be07f3af3144c2e47c95e525703eb21b1365ef6164627ee5adede814f82fe92bec984dea7a35cfc12c9da4b34cd673cbefc3de08ad546f508b6a235b5850a87310fc98d731b82ce8afcce2bc281982aca339afbc982486872b6127c90fc287602ef3a0a83c19151b7943e03945d266a267153548af385b44979c4597519c44633003eca3a831643d9ef6545405ea63d9a06c895dc5e0c12da372b22070068c82bffb9f4ec1865c2dc076b3deff2cf63ffebd47902a365109047c5383a0fb986625fd3e7edb0b1bed2d6c6b3a1f8a6a20f78d1a0153c7fa0810d38c833fcf09b690f6029e3c7c68ea39040070823b8bcf75e354b501009751124fdf1036701b4bd014cae0b9ac69cecb759e12e2ca5ebd38628fd937dfb0248491e59fdfcd68d807eca85610d5e7dab09268e82b62146c8f5c0d377a099da7badad9c1b9c3568f731e5d186defe9dfae07529efb574076763508c7f0b71f8c39309cafd3047c32454f6a96c4526b8d2621154c78a5e982aabd5a8f8af97d2ae6494fd5c22afa4a1ad0e8573561a64639383c83104b0e0d5f09d96d183a9d5d047268b140a735e57cfab2517f3574902f0370397fe089e289c2c3699ccbe760b9e37ca096a215c24254b5eaf3325b4f1658f06935458f5f145d9b649c4c3c44e47c093192930ebba8220286578ea783107076781e17173529e6f035ceaa3a6064b12130ca35d6e370dc9356edeb57c58e99e3a37aa54e6f5821224ec1fb318a6acbd9885ef571184f1d6b3ff87f292fafb2fc82547f30401b1625fd60013ad7a201a01b8cdb618bc5ba447efb21ddc257715a7a781d596dcc44d0428231dbd86dfb911a531d5ca3e6fce3d9ca583338e8c20a0c0fb9f4073a700375c654f8065042318cae24546f45841be8129c5b7ac30d1616a570f9e85199751acd37a0bb9213b40962b2dfba1f60e16104161f80a27e4ddb408982c0ee8aa698e21e22e9eb82ec6804d65cb860e4378077502ca29c8b5c0c2203335e2e4233fe20e749e5c65bc4e1084211f7f1cc120e49f7714d530548884e7e1832b5373567077e93127c006557f23f82b9fe4e1014f6c4a6df493376f687b8905e76278a410a398ca6ed9f9f551d8030f87c4b9bc73b3448d37c4b739e39e303d7cc58dd4e3a5e15cfd8c1d02a8100d65774927ebf2979f1312ba3c409f06e5d6e8178399dc22802fa9ac2089ee870d74e2bd4cca8edbdfbef521000f1af17758be238a6388db2628e3133874b0beec2772b1a81f0d38797e065ad4a8ca68eec2c12688a9319c415182488e809ede52282200342229672d003e0ff47158e14b4c7944fd03e4c872626d0235711040f65c6a2e2a28e58f0f732ba80e8834d16593c81e0e3fb35699d69960625d531514195f17a8e28966cbace912834ff71946082630d017a9191dee225a2a5cc23292d0b111051c64b996aaea2adcbb888cb90fd7dc1539948161840fdad30436d1314c9688d7001d832237d19a5987cced902fe81e86b9e0d912ad97b13c76f6bb09be8c4ee6925a88e88ac9f912a342ed964bdc4d496a00a154a124d787fd4ffee19fcf78fafe183c35f8a0783a612fcfae508fee99ffde3f0fcc1207c707ff0f51ff0ef08c2bbfb8f7a8e78e35e53d965c30d1280a85e53e1a8c71e32cc7d80d6bb0297fd21eb1d2ea3cffb204454f4e4e0c1e36f1f3c797a60c63d8c63d6dca10580a0870a0b9eabd8f799c0f580b2487665fca0cbb1f63a1ad476a728882c031f6730d3f8f435fc5ba8317f3d01551b41dade302e171ca3a19e02866c4148dd19b9a7b77506f52cadea004111914f5b727cc41767968dbc9aef901cca73f214d75d3e7d38419b96a530eaa253ae4c869999d41a537d267210a4a3648f067eb484b4caaa21714a1853d7489a6ea4c82f0e2904b0fc6b0f0b2b11b9768fece906a2a1a5c652372b0b020cbab24a4f8a91edc0ef4e4323503b59e8629d20b967b1edbabda7863326786f9a162c01f371a4d26f3b77981151b8df32239a46715e10f67fa1e9d158f8ef90349a2392c6e09b3b9f35baa755fb16d8a0d5598794985594dca6f9b96e9bb5261e6d022ba5877b4e2c38c6e0ec606a6ec826b4a073e0a6a2cee34d962b4c76dea0ebc832ac8d12d9133e56af0d1e3fd572af9b283f7bf0831d7b78e4e5149072ee478bcc80ca8fee604c42d157ccLine truncated
|
||||
bs, _ = hex.DecodeString("1f8b080000096e8800ffec7dff73db36b2f8effe2b507d72a594c89493f432f789a3f4a54e72cfd734c9c449efcdb8be37940449ac295225293b7e89fff7b7bb00497ca528dbedddcd3c4d1b4bc462b1582c16bb8b05381ab1a36c7d95c78b65c9fa4703f6e8e0e177ec6fd17936613f64f98245e90c20d2328f279b32cb0bd62f3867e592b3a3776f3f7e38fee1d3c7771f4ed83c4ef820dc03742f928411ba82e5bce0f9059f85ec53c15936876a71c18a6c934f399b6633cee0e722bbe079ca676c72058db19f8e3fee17e555c21157124f795a607351c9a6503ae16c9e6d80a438251ade1c1fbd7a7bf28a9a0ff7f646f77f2d92382dd924cf2ea1eda7accc377c086da5659c6e78f57b9d6c0afc5ffc66f74750739164932861f79eb27994140014a58b4d12e5f23702ed051bf852002fa66570b8b77711e5acb84aa7d0ad74c1c6558d7095cd3609ef0775593064a7c13a2aa651b2cef9745986651ea54512953c381b1c12a24d9e4c22403f6601f08df0d7f543e8c03c5ef4e71b78106729ebdf5b96e5fa7d9e5dc4339e0fd9bd1a5ff56cc0beec31f86880e18ccfa34d5216e1e7229fff278fe0d9db68458dfed7fed1c987d7fb1fb3739e42e35bea1e65d979ccabba5a4d51d5222804de9d9451194f5fc360156f326cbc2f88c40f30661e7f7eca8204d8b81f0ceb8262331705e1af459606f4fc1a9886ffeb2c2af32c490069f0ea82a7e5519927c0788567c5345bc3c052b76afed0c330898a926a4177d24d920806e0b860c9f14b787c20bb46a3be994e7951bc4ee179d3c02c2aa30aaf82fb1e5fc5653ff874fc2e05e1e4c14022c24f3c677dd9c27376a056c60f220ce759fe2a9a2e95c1e748a8098b1fe04191c14c48b245bf4750bd21a3bf613cabbe9557c804f19d283eb4f068845bb58c0ad7caef6ba56b0ece6273a7d4a984a78b72c9f6d9c3b3a676cd6ab32a50af202e78f9315ef16c532a3c31d941831c2e78d9af26d603168c88fee2fb224ea77c1cc023d1e440ab1acad1edd7a36c94f33ccff23efd0b654aef87eccf0707f2c1b5222e1274376199cf2d69b97dcf9318d08f1f0677d7e38707569777a4a0ad75abe596597f523d6d9ff9aab684ef49368d10aa62238e17e8a28b97502c667df5143af4ee4778846b46f3348d2ee2056048172f2ea32b1c625c2e9af28c26bdfd1c957c949762e59065aa469a66ab75c289fe31fb727da897e172e07b7e9c222734429bf294134f0abb32f1189f9f9e69cf6135e3890dbebaa2a91a04dad314801d38d6795666d32c395a827287b55ee38684c9f93acb4b607b643726cadec3b0c4fcd25bdbd1293056d257d8319bd4cd7a91c31a749cce33473d58a92a746e997ed01be14ad51bd4e2dbc81b1614eabc045be6750c660bda2cf3382f4a86209b68c12b4b2689e1e15aac95640be1435832f3a0a8ac19151b5944603d4572dd44eb2a6a905e72b68c2e388b2ea2388926b024b08fa2c690f578da535115a89b6583b22576198315b78acae992c019f00ffeee7f3a81f5e47209eb37ebfdcf72ffe3df7b04a962139540e8af6a103421d3aca4df476f7b61a3cfc4fa9a2e86a21acc8546b5c0b2c7fa0810d32c843fcf08b6906b073c79f0c0d47d0800e004771a9fe90b55d506005c44493c7b43d8c0742c417b2883e75a59735e6ef29410576bd7f3317bc4befd9625218c2cfffc6e4ec33e60e35a69549f6b63c5c445bf2246c1f6d0d570a3abd080aaab9d1e9c39d6ed49cea373a3ed3dfddbf540ca73ff12c8ce2e07e104fef683090786f34d9a805da6e84e6d75b1545da360ae07baf6ba07557bb56e15d3fe44cc939eaa9955f49534a00150d584091ce560fc0c422c3934ec2664b7b1f8e9ec2290438b053aad29e7b3178d56aca1837c1580d9f992278a350a0f67712e9fc32a1ee703b51457262c440dac3e2fb3cd7489059fd633b4fa45d1b549c6f1d44344ce57e02739e9b08b2a226078e5783a0801c387e771715e93620e5f63b0aa0346ab383847b9c67a1c0eb9d0c18cf8a659dbccf111f3481d91faab6abc6ac6723db682b638050349795c2fb08d348a96ecf5b5c6d40ffe5fcacbcb2c3fa7c52118e02a1725fd6009ea576b13201b4ced70c5725322cbdd50ae19a29879dd786cccc0af5fd937a2fbb7e07363675a1c35d88614b48cad97ab5b6720f1029d432e0d840eec406d3113c602949027a353aa9a2fc2e9401be1cca2da0d461600973e4b58669dbaf006b456728cab8198e6b7ee07acedc0efe507a0a85fd3a67a04b0e28aa698622f22e99b8256d008d671619391c5007641b18c722e2231880c16f072199a738cac29951b6f1187c31545dc4773c73427ba8f6a9a2a404274fc72c8d4ded49c6d9b2a1f40cd95fc8f60aebf1304853db1e977d28c9d7d1917d2ecee4431482187d1b40df6d3aa03e00c9f5944624b38818afe367a8e76208626fc16523cf3c907ae2d6e753be9645d3c650743ab045c5d5fd171fac355c98b8f5919254e80779b720bc48bd90c9807e86b0a2378a2c35d1fbabb5709c5f6defd772908004fd98bba45a91c915347f132c79899c3a57982e1bb358d40f8e9c30bb0bdd625ba5e633bce045ae4780ede06ba0ec2d5c265731981eb01fe134b39e808f00aa20a470a9a65c6a7b84acc862626d0319711b81465c6a2e2bcf663f0f72a3a079f844d97593c0597e4870d69a459960625d531514195c9668128566cb6c991285cfde328c150c8065cf922239dc64b444b31495268162220a28c5732085df9601771119721fbfb92a732c42c30806a5c63ecda2628923e1ce102b05546ba344a312c9db325fc033ed9221b2255b2f7268edf36b082a269bba795a0aa22b27e46aa70e1c9a69b1506bf0455a86c9268cafba3fef74fe1bf7f7c0def1ffe52dc1f3495e0d72f63f8a77ffa8fc3b3fb83f0febdc1d77fc0bf2370faee3dec39bc906f9aca2ee7c3200188ea3515c63df68061940434e22518f20f58ef70157dde0721a2a2c707f71f7d77fff19303d31b621ce3e90e2d00043d5058f04cc5becf04aefb146fb22be3070d908dd3eca8dbeee41bd1aac12719cc343e7b0dff6a91807a02aaeb07ad04c6c273ced147ea2960c81684344c2abdad53a867695507088a887cda120d24be38e37164f17c8fe4502494a7b823f3e9c331ae77590aa32e3ae58a6f98b14bad31d59e22e3411a51f668e0470b59abac1a12a7c442eb1a49330a2d229143f2022c83d3c3c27ab1748fecc915f8482b8da56e561604187465951e41a3b503bf3b171a81dac94217eb04c93d8b6dd7ed3d350c35c17bcbf9c01dbbf178acd2eff63b5c6e873d239a46715e10f67fa1e9d1acf0df23693447248dc1b7773e6b744babb62db041abb30e2931ab28014df373dd366b4d3cda04564a0ff79c58708cc1d8c180dd904d69cbe7c04d451ddd9baed61802bd41d79165581b25b2276cac5e1b3c7eaa8d6037517ef6e0073bf660ece5Line truncated
|
||||
gr, _ = gzip.NewReader(bytes.NewBuffer(bs))
|
||||
bs, _ = ioutil.ReadAll(gr)
|
||||
Assets["app.js"] = bs
|
||||
@@ -73,7 +73,7 @@ func init() {
|
||||
bs, _ = ioutil.ReadAll(gr)
|
||||
Assets["favicon.png"] = bs
|
||||
|
||||
bs, _ = hex.DecodeString("1f8b080000096e8800ffec7d6b572437b2e077ff0a75ddb11b66a92ae8d7ec62e02e0ded19c6eec781eeebf5fa78e7a832555532f96a49099431f3db372294ef476516053473c71fbaa9cc544a11a18850442814b9f7e4f8fdd1c79f3ebc6173e37b075fed3d190ebf1a8fd951182d949ccd0ddb38da64cfb6775eb0bff3f370c25e876ac678e0428bc02839894da834dbd042303317ece8fdbb8fa727af3f7d7c7f7ac6a6d2139b23eceed0f31875a799125aa80be18ed8272d583885d7a4663a8c95239813ba82c1e52cbc102a102e9b2c6030f6f6e4e3509b8527b02f4f3a22d0381c37cc81a713c1a6610c20c98060f8e1e4e8cdbbb33734fce8abe110b042e498c783d9fe40040316cc863c8af6077a1138307c30a35b0e62147a9e50fb83b3f4c99151de80391ed77a7f808dbc909f0fb04bc1dd83af18dbf385e1cc9973a585d91fc4663afc9f83fcc1dc9868283ec7f2627ff07f869f0e8747a11f7123279e806e614411c05b276ff6853b1385f702ee8bfdc185149751a84ca1e9a574cd7cdf15174086215d6c01e2d248ee0db5c33db1bf33daae75e40aed281919190685be6acd786ce6a1aab5f064700e13e701c5e0b17162c3a4833dcd9598ee0fa6fc022f471110f2e02b7cc148e389838c88ec77767d8df3fc0ee6f71d8cb4b17973b337b6adb2016c67933034da281e8d1dadc7d9d5c897c108ee0c1238901bf45c0833a876a08006977cb1a4315d33b388006323ae0c8e444f189b84ee825dd34fc622eeba00fd70121a13fabbec2fdbd1d5b7c9b329506838e5bef416bb6cf037e15d08231dcede89580cb65876638b1d2a989a2da679a087c0fa726abbb8f98afecc77b6d8fc19fc7b0eff5ec0bf97d9f0e5214e2d5ad0f71aa3c5deff280ce0733593c1d084d12edb19bd147ea9ed084933f4c320d41107d96c04ebad08bc708bbd0d03eec05f500a3a045901208f40a2a55000e225409875531982831ca0e0b928d2ee8121a932ea00b9bafe1467a7fde91478a5fd69d6b3bbb4e7c6a759cf6e468549a85ca12ced8230a8e0e585b3b042e65db6fd6d99af0a77a89be1cb9cbda2504b14d65de460501717d501a436c3201c4e62d057261b8a6e137b0f91bd2d68951701312ff683ec1d57eac8e3309732002912c389173ae7291c207556c900f7a7fc91310e6974609dfcc1843be73385ca18470915803f9b6c3c7bfe6a8b3d7bb18dffed6c7e5ba6a0e2ae8cf52e7b5e403ea5cf4e74c55ee4f753423e83dbcfd2db3755bc80cd8291cb41a755f8dc135380763b67f4127a3bdbf96de27ceec919d21f91fcb69b562981d335a24e5f9c0bf644faa8d079601a240196afecb5cbb93462483283af5e820e2ce99e4b61a9ff627bbbb127b7a6c62cfecf40897541e18eb4cf3d6f58a2622b40c9cbffdb17aee46cc3e757094dfff2ea2fd1d566d6412257600044a02680a50fec9da2f4658d191bff19781fcc00c338cb9601068bacc115458c66a3ddac2dfb331045819699c09acfa239505a8350314022bc6438551325f8b94613c10be175252215c23b1eb0e058c3e20db6c6a534f3628f969ff488fd799cddae10410199d259b9c9d8716f4c220846c2d85a095fed1186f8c89517555be3cd052cb564671cec8de1b95d42c110631fc308444a31b461f05ec02f3253845fe013fb07d550fad315531e7b603140f782dac919a775dfae700441d20942c181382a79866b23484f798ce14481bd07b0497f963e41fd36605a39f6e79004e6d50bb200d89c38737ff0fcd980596b65b0b3f397c118b0c3deb3a1a2ca38d8099b4b17b4eef00a16e4269321cade8ebdc2eb29f2859f24b7195e642220e1255808713403ad234e8269380ac465017d6a0836ad0983c43eb01799053831413a00fe847f39c1adf9614d493052cfb3813636cb0314693cf316d11cad2796fd1a3a7371a1e06f1c0d529a7d237c9dc97fde098844a0617d10f9afe105f762f85f280d93be3fb8be2ea28b2db4b9b9191c7cb27781c7d8f5d749ebaf6fca5344038d2d090a941c7bb24cd704175785911b5e06656c794298ff1854db01dbce666807a39e492e8abd54703c78e34a6301fcfc4d30017aec4d324e06093648ad09fce3a5f17346c9c6f54510978024340e32508b7308caf3544421ce61e7c4cd5db7326355140e5d976177b0ba876a91344588cb44ed820885a2174440954b6129d3011576d9054f464879215d149b15a086c5c19c59e5ad7b81ee84b30eb0d3ee6e4746d99f8a9f153aa65dd0cc61a93939be4f1aea796c90817b011d4ea79d10dbee6e473f58c70d57a6271b4ea1f9bc039e53dbe37d52904fc2b81fc8b0722b33147e64165dd2837d2e017a6f1c7bcdda337f922cfcf8039617bbdab72cd4b63d9a07df49a50dacf3975b2c0cbc0503e7fc326072ca02e108adb95a7ccb129ab24bae02b49b125322b74470417c02fd4fe5ec24408f3d53d3d0716e179480f186be3bdc79565c5d0bcf810ec263f4ff3019b6bc2254db22ad5d6ab5377f5e58d34a6d285830487904dc4ae10a170cace70719edda0740f3abaaf0a3c2147e9c63ec0969102b3296d89c6b361102dc097e8171a8d880b907a6a803be18bce18e581eddf0639c860430b43a9346148d0203a3dcf5a860c594a6be1d7cf43f2b564a0f3b058d13ed176d141681bb9858460f2ac95513a2c6521e48db545e0d1a26b37ca37459b8c82de7b2708859ec819d0cbc5c61fd1293a7fde18bf9f24cee34db40e31a7da7cdbc87468178b54c1e86e8164703265da4773282147ab9642452747d8daf1ce1830dfc353a39066b98a6102e0537b64ff46ef0ef0f0076c5e65c2a75a576d01284b049f42acdc8b42b596e40078f473a35e822b0c93086f81f257c536b106f02627f92812baed020ad75dfc3522e1a5ccc5209687373d3d5572e07058703c9a9c10974e6969c67869b382778238475433ceb64783917607fc7c17940d6ec27fba36e61f7ef4b032b4602503eb33fd6eacbe18155cd67c9afeede6a7d800a6ce2a016182820dc3110631bd7d7d8ef07a11c601f3e130596ff7ab319ba9521976e234737837d028d1f10e6b62715c7c6de82f5af2ce655fd99487eaa778a225796f2547a5926c6b5d1faacabd586d5a04fb3a0dbc053f1155689c226d7da284922d04c5493065a9a9faab647f870debdfac1d476ae7cd9ea51f005a0ef2503bb19e21846490217056d06efbbad388ddb915a1f5f1b201b8691083af0fe8e5ade01c2c7520907e9b716dea965eb83dfe6fd9c50f297910c2eb827dbb8a7375912ab76a8e5ac8b2e6f940ad7244b330e5f922d665e38e97287ff0a6db8d714ecb80b22cca8f7efa42734fb9d71ef922ff4bbd89f08757353d3dfd20084c9f05bec9f2d9dbd5e18ea6c22038edcf7facbd1771efa5de4fd2174ee8fba1e767e47c4a5be1e116d1d2f8cdd21863dbc907785ebde83dbf77e4aaede3a046e6fcf5b145500eead9d8003b65d0eLine truncated
|
||||
bs, _ = hex.DecodeString("1f8b080000096e8800ffec7d6b771c37aee0f7fc0abaef249666d5dd925fd9ab48ba2b4bce8c12bf8e64df6c36273b875dc5ee66542f932c491d45f3db1700ebfde8aa56cbb266271f6c7555b1400004400024517b8f8edf1d7df8f9fd2b3637be77f0d5dea3e1f0abf1981d85d142c9d9dcb08da34df6647be719fb819f8713f6325433c603175a0446c9496c42a5d986168299b96047efde7e383d79f9f1c3bbd33336959ed81c21b843cf63044e3325b45017c21db18f5ab0700aaf49cd74182b473027740583cb59782154205c36594067eccdc987a1360b4f202c4f3a22d0d81d37cc81a713c1a6610c28c98070787d72f4eaedd92bea7ef4d57008542171cce3c16c7f2082010b66431e45fb03bd081ce83e98d12d07290a3d4fa8fdc159fae4c8286fc01c8f6bbd3fc0465ec8cf07085270f7e02bc6f67c613873e65c6961f607b1990effe7207f3037261a8a4fb1bcd81ffcefe1c7c3e151e847dcc88927002cf4280278ebe4d5be7067a2f05ec07db13fb890e2320a952934bd94ae99efbbe202d830a48b2d205c1ac9bda176b827f67746db3540aed08e929191615080556bc663330f55ad8527837318380f38068f8d131b261d84345762ba3f98f20bbc1c45c0c883aff005238d270e3226b23fd8f5358ef35b18dfb7d0d3c6e6cdcdded8b6ca3ab0c0266168b4513c1a3b5a8fb3ab912f8311dc192478a034e8b910665005a08007977cb1a4315d33b388806223ae0cf6444f189b84ee825dd34fc622eeba80fd70121a13fabbecdbede8eabbe4d91438349c725f7a8b5d36f8bbf02e84910e676f452c065b2cbbb1c50e150ccd16d33cd043107d39b5206ebea23ff39d2d367f02ff9ec2bf67f0ef79d67db98b534b16c05ea3b7d8fb1f850e7cae6632189a30da653ba3e7c22fb51d216b867e18843ae2a09b8d68bd1181176eb13761c01df80b464187a02b80e41168b4140a50bc040c3330952e38e8012a9e8b2aed1e18d22aa30e50aaeb4f7174da9f4e4156da9f6690dda5901b9f6690dd8c0b9350b94259de056150a1cb0b676185cdbb6cfbbbb25c15ee1098e1f35cbca2504b54d65d9460301717d50ea436c3201c4e62b05726eb8a6e93780f51bc2d6a951781302ff683ec1d57eac8e3309632002d12c389173ae7291ea075d6c880f4a7f291090e5974109dfcc1843be73385c6187b0915a03f9b6c3c79fa628b3d79b68dffed6c7e57e6a0e2ae8cf52e7b5a203ee5cf4e74c59ee5f753463e81db4fd2db3755ba40cc8291cbc1a655e4dc1353c0763b17f412793bdbf96d927ceec919f21f89fcae9b572983d339a2ce5f1c0bf648fa68d079601a3401a6afecb5cbb93462483a83af5e820d2cd99e4b61b9ff6c7bbb11925b336396fe2760c4bab07047dae79e372c71b115a1e4e5ffe50b5772b6e1f3ab84a7dfbef836badacc00247a050e4004660244fac0de296a5fd698b1f15f41f6c10d308cb36c1a6030c91a9c51c46836dacddab2bf025314589909ccf92c9a03a73528150322c24b86433551829f6b7411bc105e57225221bce381088e354cdee06b5c4a332f42b4f2a447ecafe3ec7685090ad8948eca4d268e7b6352417012c6d64bf86a8f28c447aebca8fa1aaf2e60aa253fe3606f0ccfed140a8e18fb1046a0528aa10f83f7027e91b922fc029fd83f6886d29fae98f2d8038f01c00b6a27679ce67d3bc311060910c482037354f20ce746d09e721fc389027f0f7093fe2c7d82f66dc0b472eccf2129cc8b67e401b03949e6fee0e99301b3deca6067e7dbc118a843e8595751a51f04c2e6d205ab3bbc8209b9c96588b2b763aff07a4a7ce127e96d4617b908c878091e421ccdc0ea8893601a8e027159209f1a824f6bc220f10fec45e6014e4c9076803fe15fce70eb7e5857129cd4f3aca38dcd7207451ecfbc453447ef8965bf86ce5c5c28f81b47839467df085f67fa9f0301950834cc0f22ff35bce05e0cff0ba561d0f707d7d74572b18536373783838ff62ec818bbfe3a69fdf54d7988a8a3b165418193634f96f99ad0e2aa3072c3cba04c2d4f18f31f836a3b10dbd90cfd60b433c945114a85c68357ae3416c14fdf0413e0c7de249364d06083dc9ac03f5eea3f1794ac5f5f0471094922e32043b53886603c4f4514e218760edcdc752b235625e1d075198283d93d548ba429625c666a1746a814bd3002ae5c0acb990eac1064173e1923e58574516d56c01a260773668db7ee85ba13ce3ad04ec1dd8e8db23f173f290c4cbbb099c3547372fc3979a8e7b14101ee8574389d76626cc1dd8e7f308f1bae4c4f319c42f379073ea716e2e7e4209f84713f9461e6566628fcc82cbab407612e417a6f1c7bcdd6337f924cfcf803a6173bdbb74cd4b63dba07df4ba50dccf3975b2c0cbc0583e0fc326072ca02e108adb95a7cc7129eb24bae02f49b125722f74470427c04f0a772761260c49e9969009cfb052564bca1ef0e779e1467d7c273e083f018fd3f4cba2dcf08d5b6c86b975aedcd9f16e6b4521b4a160c521981b052b8c20507ebe941c6bbf60ed0fdaa1afca830841fe6987b421ec48a9c2536e79a4d848070825f601e2a36e0ee812bea402c066fb823966737fc188721410cbdcea41165a3c0c128831e15bc98d2d0b7a38ff167c54be9e1a7a073a2fda28fc222081713cfe85e35b9ea42d444ca036d9bcaab41c360966f942e0b17b9e75c560e318b3df09341962ba25f12f2141ebe984fcf144eb30d74ae3176dacc21342ac48b65fa30c4b0381a30e922bf931ea4d0cb3523d1a2eb6b7ce5081f6ce0afd1c93178c334847029b8b13031bac1bfaf01ed8acfb954eb4aeda025286193ea559a916b57f2dc800f1e8f74ead045e093610ef13f4af4a6de20de04c2fe2203575ca1435a03dfc3532e3a5ccc7209787373d3052bd78342c081ecd410043a73cbce33c34d9c33bc11c3ba239e01195ece05f8df71701e9037fbd1fea87bd8fd616910c54800c967f6c75ab01c1e58d37c96fcea8656830126b049825a70a0847047478c6d5c5f23dcf74239203e7c260a22fff56633762b632edd46896e46fb041adf23ce6d4f2a818dbd05f35f59cdabf633d1fcd4ee1455aeace5a9f6b24c8d6bbdf59957ab0dab499f6645b789a7e22bac92854daeb5519254a099a9264db4343f556d8ff0e1bc7bf683a1ed9cf9b2d9a3100b00ec251dbb19e19846491217056b06efbbad348ddb895a9f5e9b201b8691083ae8fe9e5ade01c1c7520907f9b716dda967eb43dce6fd9270f2d7910c2eb827dba4a7375b12af76a8e5ac8b2faf940ad7644b330d5f522c665e38e90a87ff066db8d794ecb80b26cc08faf7d2139afdc1b877c917fa6dec4f84bab9a9d96f6900c3a4fb2df6cf16602f1786804d64c051fa5e7e39fece43bf8bbdaf43e7f371d743e077c45c82f58078eb7861ec0e31ede185bc2b5df70ec2be77530af5d661707b7bde62a802086fed001cb0ed720a28bcc4d837774bLine truncated
|
||||
gr, _ = gzip.NewReader(bytes.NewBuffer(bs))
|
||||
bs, _ = ioutil.ReadAll(gr)
|
||||
Assets["index.html"] = bs
|
||||
@@ -103,7 +103,7 @@ func init() {
|
||||
bs, _ = ioutil.ReadAll(gr)
|
||||
Assets["lang-el.json"] = bs
|
||||
|
||||
bs, _ = hex.DecodeString("1f8b080000096e8800ffe43ae98e1cb7d1fffd140501027681f9c6fa6ccb3ff427585996b3d1b590b41104080838dd9c1962bbc936c9ded158d8204f1320af9147c993a4aa7834bb6746c7ca3a8cfcd925eb208bc5ba583d6fbe01801b2767a7f0406e6fdc1986b3805898de3398071158d7f0d8d492e1693ca09ecace38e58ddd26820292c9ac742ee2793842c8122533b269cc064eb4d1dbd6f40ece9d58495edc7aa5577f629e77d1c4a5b436bdae243c93f6525ae69c8012e1819502cb216460bedbaff820fc3f807e3a3b8773af1af59bf0ca68c24e4191b0318e351c061168b4961551c1cfd61a967b079648bbad55abb5877fff0bbebbf5ff3fc05fc48559c05d635720740d7e2d6169485d2830e02adeaa458f97e4ee84653f823f88704f36d2f319e2288295ab82ccb26664398f24a6ea5ba97dd6d118908836ba3102cd4bc45d468040f473add87ef9ff00caf63b4c0ae4d882a7a048a8c5a291707ea6cf98a89826022f2d54a66d0538d9098b42d5f0ea86eaee9095bcba0122d937188b887aab45ab2a4478039db44b635b10a8d1164f5d414d6a42c3dc8259b2f223fb3c6cffb9368b874bd6579adc7d851af8abb40eef287ac8145410e2a6ad72848085f20e8495a056da58147cb3961a1a632ec8b45034a8d642afa49ba3a349408efb27cf6189abb8adf3b20d3af804ab0ee286955ad4494d1aab51bfe0bc683b9c5f86f339501a04cc9dcf00f48f1aef8537b6b26b4485e4b871cdfe50c3620b6eab2bbf4689f2193ec756d38375d6787640585ad326c5402b6a568c4113b0a0d14ddc0cd0c977087059c778d8a8a681054a8cde4ae293f1a0e5f8644855d3a372ede4b45f60ffa802561b0b134601fccbf9299cf448afd11b38e8c099706e632c87acb7a10f2e8046660f30336a607ca850440da364b8171e59a49636c6c03c8ea8c62c4403f7923b33c914b69fb4488d875023c671d0dc0506e2d3ba6139f97f04b17bc259f65c3eef1e68207f206597420a538e0181e821aac051d46ea4086974028964a69a6a670ada4b08671854f7500778c932d6ca0e2c903e1264920c27aa729a085e0387b79fd8ee39c1c1d10375f75b771c38de821f9678d27b0c24baa6f8f754fedaa3425c62df8bcbacaaed5b3859c9489da781e0318bfdd8e429ec49057ba0891cddf6f45ea009c31251939f2ca3a70c446370c1f058b43293f12421d1dd22864701fce40181f06f9c2e978dd24c968611a1335c97600c464f96f00c432be38a69265819562addc943d5623151dcdcdbd07101342cabea74b77c613bb0407a26fc7a8879c9c8427c9498f9c8f8b046e87a0a80f02246caca4aae16d41270f3da488aa41ee46b8c3673788e9c589ce25e1873ada8c8328ffe7e0c95d0c4dc3be41418c4c1add1f62b3cff3254065f8f308572303d6250c94913c9faa6e674e1b94438c2e8702941b69ddf728940b2d67229fac6ef4bb74a4fce773ccf67ff1c7bc5a3714c838d08b56e398d04565e2ab9193d5398721f3cb03c3d79347da84c419150c6ea1d4ea908bdc46b3d0ab67d0093d8b24904df1f03768842509c1046e00e31e97f42caa044e8d060029e472538cb3ae007d05ec2e1b8bbe0cce045d0781a8e10f058ca3a3c86269011590ca4c52ca09fa1191182ff47104a92026f1e47146640bc1232252ea8c847dd9a8a302ea20a57dd28bf6673fe5096b49127215d58218e238a995f2031bfbd02c9145690d60ccf54719a08d06841c57c807e925c69106b0e8fb0e823d723b8c39c40614860c489d560385638ebefb85c1670136d3c0d078446b746167cb4627d1ad35ff2f4b41a5eb7efb3741fc472ad8d72301635c620af5c788814453807592ccb3b8a0368ea296ae19b525e47ce8fddf1e38ed97735e79c98ac68c96ceb83448e725223973e44ec8f3ae635774cc7ec7d8dfb0601e238a254db6189b5a7fa3a80896ca6b7151613b127524e238117ab9524c7dbb7f4416466468fba6bcd263e80c6804464ba2e84c0348c88bea3ac04dfc27d63fb960926a0488835179ce13bd254a6d9fb847a07c5b0ccdaa2fc43de9b8206c2a481381c10fccc86351aed42e2260eaf09e89ee689fc30c17411a5d18a38e88e1a6ece2cfd8622268627ee3a52a540fe22cdf2ce78976badb02386e36774483c93634c707b58fb6e6545bd97b3404d199d942d271b741952ce0c422ca69e0e55799d358b46b69c75608b561b92af961eaadc159d635de3ed16d7fbcf3ffe39defd13ac1f8e40752a3a85952b7673727fb43655c56647bf6854d56c415c0ad570df50787873b3b7cdcd2b56d0b5f8df20ffd5d5bc1001855caa556f439361303641ad256aa350698d55b4baa46de63068a6a50417ef941494884294c28a71b47496f9f36d381c52eaca6e3b5253cf55ace52a962e905b4035aa0833f62943fa98583cbe1d2eb85d8a62768df0d4fe7433e605a77ea37ca3f129d175b97ec72596b90eb0b41d86706ab6f2c2a11f559391e40e145a4fcb72b1f970a5542bd198155ead5083d2feb807282fc17306d031ffe5871bb55b01ab6155f31186479080dbdf15af38e72d9901deb2234bc7a1a1dce711178ea2fb7681e35910c675a28a67ac855b4b3234668af541a1dcaf4db08f561ac6a8db3f7ebdaafbe4e20d0a1c72998a8fae1020c94beee4c27da92cc69635856f91bc814cfe4276585971dbeefb5be80728618d528cd96ab13dc8454b4ee97125647107791039831edf160d33b5b197467e7f886523e545be94ffa5230f175df2b4f1ed25a2e1b0a9d013d73078d1083da8ebc3197737f58aaa7383f2c9ae90f8086b7c3af78c4328e26f65a2a27363e940c73bf2fc2e6b0ea226173da48683f8dd25703f767ce0322836d696a6475dc547cdabf045f4557febd6f712e293f6d58d941b62836f78bb619adff1692e3bd35bee287ea03bde91f7cb0a532827180c062ed3141fe1e2ddcce8ab237f381c0ef0de0cfb36c9f41f64ebd7e61f44b0650feee046efa03ab4dc208c9bf6588e7efc61c818fc85bac137d9f1fea4314b1923ff0c811ba728c3d1fc78c6970a47ff77cc58b41424acc89c8efe763cda4337db0327fa1a057d97527bad7eede53b0e9488f62ed651cffa3dae7c3f5db924b741537a1ab48985831438be9d124fb1fafbb3848dcef5858e2d90348c888e9cec5efc1a5acc129a1e9b129e1b7c6f4537b979154807cc9b88b9ba1ab1c5d7fe3049c8d1af50ca6924a0b29e513c4840eab0b41d351f629f610a1a08fffcfcf9d9334ebbbf9c9f26d2313010c7e60b91a4e108e1726b7c0c98105144cc3f06110d3e35d3cf0814bf21b62166f267098f2f879dc48e42c9d79594c1ec87c8b40c5ffca986911cc38b6b9f8fc4fa42220445bca05f51889a3f860a7e7e52ee98854c8c2cad628716bef8e14136dabaa65f5e9489c7d1a73a6f0c9ff093ad7d48f4c177f76f2261f4e965f4cc5485eb2b6efcaf246fbb907e434ffbd0Line truncated
|
||||
bs, _ = hex.DecodeString("1f8b080000096e8800ffe43adb8e1cb7b1effe8a820001bbc09cb18e6df9412fc1cab29c8d6e0b491b41808080d3cd9921b69b6c93ec1d8d850df23501f21bf9947c49aa8a6493dd33a3cbcaba1879d925eb42168b7563f5bcf906006e9c9c9dc203b9bd71270f6701b130bd67300f22b0aee1b1a925c3d338a39ecace38e58ddd268202329059e95cc4f3708490254a0ec8a6311b38d1466f5bd33b387762257971eb955efd8979de451397d2daf4ba92f04cda4b699973024a8407560a2c879081f96ebfe283f0ff00fae9ec1ccebd6ad46fc22ba3093b0545c2c638d6701844a0d15a5644053f5b6b58ee1d5822edb656add61efefd2ff8eed6ffff007f11176601778d5d81d035f8b584a52175a1c080ab78ab163d5e92bb1396fd08fe20c23dd948cf6788a30856ae0a32cb9a91e53c9298aa6fa5f6838ec68044b4d18d11685e22ee320204a29f6bc5f6cbff3368b0df3c2990630b9e8222a1168b46c2f9993e63a2629a08bcb45099b615e064272c0a55c3ab1baabb4356f2ea068864df602c22eaad16adaa10e10d74d22e8d6d41a0465b3c750535a9090d730b66c9ca8fecf3b0fde7da2c1e2e595f6972f7156ae0afd23abca3e821535041889bb6ca110216ca3b1056825a696351f0cd5a6a688cb920d342d1a05a0bbd926e8e8e260139ee9f3c8725aee2b6cecb36e8e013ac9ac50d2bb5a8939a3456a37ec179d17638bf0ce773a03408983b3f00d03f6abc17ded8caae111592e3c635fb430d8b2db8adaefc1a251acef039b69a1eacb3c6b303c2d29a3629065a51b3620c9a80058d6ee266804ebe4380cb3ac6c346350d2c5062f456129f8c072dc72743aa9a1e956b27a7fd02fb4715b0da5898300ae05fce4fe1a4477a8ddec04107ce84731b633964bd0d7d700134327b80995199f1a14211358c92e15e7864915ada18038771443566211ab897dc9949a6b0fda4456a3c841a318e83e62e30109fd60dcbc9ff2388dd13ce06cfe5f3ee8106f207527629a430e51810881e0abc712725278f3c49484f06f1143d43841c3b814432534d553705ed2584338cb87ba803bc6419ab6c0716481f09b257861355394d04af8163df4fec149cfde0e881bafbad3b0e1c6fc1e7259ef41ea38cae29383e95bff6a81097d8f7e20656d5f62d9cac64a41ea681e0b18c56140611c867796c8629ec491e7ba0891c1dfdf45ea009c3125193672da36f65a231b860782c5a3990f12421d14123864701fce40181f06f9c2e978dd24c968611a107b82ec118be9e2ce1190663c615d381606558d374510f558be547719d6f43c70550cf56d5e9c2f916776081f44cf8758e92c9f2424495982bc922b1aae87a0a99f022c6d6ca4aae2fd41270f3da488abd1ee46b8c4f73788e9c58cee25e18a5ada8c85c8ffe7e0c95d0c4dc3be41418f6c1add1212a3cff32d4125f8f30857230a162181ad22c92f54dcd09c67351718421e352826c3bbfe5a28264ade552f48ddf97a0959e9cef783e9cfd73ec158fc6810e362254c7e534125879a9e466f4b061ca7df0c0f2f4e4d1f4693305454219eb7d38a5b2f512aff528d8f6014c621b4c22f8fe18b0431422e5843002778849ff1352062542870613f03c2ac183ac199f417b09f37177c103831741e3693842c06329ebf07c9a404664319016b3807e86664408fe1f4128490abcc338a2302de29590297109463eead654b671d955b8ea46f9359bf387b2a48d3c09e9c20a711c51ccfc0289f9b51648a6b082b466f84015a789008d1654cc07e827c995b2587378846522b91ec11de6040a4302234eac1fc3b1c2597fc7e5060137d1c6d3302334ba35b2e033172bda98fe92a7a7d5f0ba7d3f48f7412cd7da6808c6a2c618e4950b4f97a26ce7208b857c4771004d3d452d7c85caebc8f9b13b7edc31fbaee69c1393152d39d87a96c8514e6ae4d28788fd51c7bce68ee998bdaf71df20401c47946a3b2cb1f6545f073091cdf4b6c262227651ca6924f062b592e478fb963e881c98d1a3ee5ab3894fa631201199ae0b21300d23a2ef282bc1b770dfd8be658209281262cd0567f8f2349569f63ebade419197595b943fe7bd292813260dc46146f0c31cd668b40b7ca960b0eca998d9e879223f4c305d4469b4220ebaa3169d334bbfa18889e189fb94542990bf48b3bc33dee55a2bec88e1f8e11d12cfe41813dc1ed6be5b5951efe52c5053467ce5b59c6cd06548393308b198ba4054e575d62c1ad972d6812d5a6d48be5a7aa8863eea1ceb1a6fb7b8de7ffef1cff1ee9f60fd7004aa53d129ac5cb19b93fba3b5a92ab647fa45a3aa660be252a8863b8dc2c39b9bbd6d6e5eb182aec5ff06f9afaee6850828e452ad7a1bda12d9d80435a3a8f142a53556d1ea92b69943d64c4b092ede2929281185288515e368e941e6cfb7613ea4d495dd76a4a69eab58cb552c5d20378d6a541166ec5386f431b1787c3b5c708315c5ec1ae1a961ea66cc0b4efd46f946e353a2eb86fa1d97580e7580a5ed3084537b96170e1dac9a8c64e859a1f5b42c179b0f574ab5128d59e1d50a9595f6c73d4079099e33808ef96f78b8518316b01a56351f213f8204dcfeae78c5396fc90cf0961d593a0e0de53e8fb87014ddb70b1ccf8230ae13553c632ddc5a92a13153ac0f0ae57e6d827db4d23046ddfef1eb55dd27172f2b30e732151f5d21409297dc190af7a5b2185bd614be45f20632f90bd96165c5bdbcef6fa11fa084354a3166abc5f620172d39a5c79590c51de441e40c7a7c5b34ccd4c6061bf9fd21968d9417c3a5fc2f1d395f74c9d3c6b7978886c3a6424f5cc3e045237456d78733ee6eea1555e706e5935d21f111d6f874ee198750c4df1a888ace8da5031defc8f3bbac99454d2e7a480d07f1bb4be07eecf8c065506cac2d4d8fba8a8f9a57e11beaabfed6adef25c427edab1b2937c4065f7ebb619adff1692e3bd35bee287ed23bde91f7cb0a532827180c062ed3149fede2ddcce83b257f6acc07786f867d9b0cf41f64ebd7e6cf22d8b2077770a377501d5a2e0be3a63d96a31f7fc81983bf6937f8263bde9f346629630c3f5ce0c629ca70343f9ef1a5c2d1ff1d33162d05092b32a7a3bf1d8ff6d0cdf6c089be4641dfa5d45eab5f7bf98e0325a2bd8b75d4b37e8f2bdf4f572ec96dd0949eb236b17090f4edee764a3cc5eaefcf12363ad7173ab640d230223a72b27bf1fb69314b687a6c4a786ef0bd15dde4e65520cd983711737535628baffd3c49c8d1ef56ca6924a0b29e513c4840eab0b41d351f629f610aca847f7efefcec19a7dd5fce4f13e918188863f38548d2708470436b7c0c981051441c7e3e221a7c6aa61f1e287e436c43cce4cf121e5f0e3b891d8592af2b2983d9e7c8b40cbf11a01a46720c2fae7d3e12eb0b891014f1827e77216afe422af8f949b963163231b2b48a1d5af8e2a70a83d1d635fd56a34c3c8e3ed57963f8849f6ced43a267dfddbf8984d1a797Line truncated
|
||||
gr, _ = gzip.NewReader(bytes.NewBuffer(bs))
|
||||
bs, _ = ioutil.ReadAll(gr)
|
||||
Assets["lang-en.json"] = bs
|
||||
|
||||
@@ -6,6 +6,7 @@ package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
@@ -24,7 +25,6 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"crypto/tls"
|
||||
"code.google.com/p/go.crypto/bcrypt"
|
||||
"github.com/syncthing/syncthing/auto"
|
||||
"github.com/syncthing/syncthing/config"
|
||||
@@ -111,6 +111,7 @@ func startGUI(cfg config.GUIConfiguration, assetDir string, m *model.Model) erro
|
||||
getRestMux.HandleFunc("/rest/system", restGetSystem)
|
||||
getRestMux.HandleFunc("/rest/upgrade", restGetUpgrade)
|
||||
getRestMux.HandleFunc("/rest/version", restGetVersion)
|
||||
getRestMux.HandleFunc("/rest/stats/node", withModel(m, restGetNodeStats))
|
||||
|
||||
// Debug endpoints, not for general use
|
||||
getRestMux.HandleFunc("/rest/debug/peerCompletion", withModel(m, restGetPeerCompletion))
|
||||
@@ -265,6 +266,12 @@ func restGetConnections(m *model.Model, w http.ResponseWriter, r *http.Request)
|
||||
json.NewEncoder(w).Encode(res)
|
||||
}
|
||||
|
||||
func restGetNodeStats(m *model.Model, w http.ResponseWriter, r *http.Request) {
|
||||
var res = m.NodeStatistics()
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
json.NewEncoder(w).Encode(res)
|
||||
}
|
||||
|
||||
func restGetConfig(w http.ResponseWriter, r *http.Request) {
|
||||
encCfg := cfg
|
||||
if encCfg.GUI.Password != "" {
|
||||
|
||||
@@ -125,6 +125,7 @@ The following enviroment variables are interpreted by syncthing:
|
||||
- "net" (the main package; connections & network messages)
|
||||
- "model" (the model package)
|
||||
- "scanner" (the scanner package)
|
||||
- "stats" (the stats package)
|
||||
- "upnp" (the upnp package)
|
||||
- "xdr" (the xdr package)
|
||||
- "all" (all of the above)
|
||||
|
||||
+16
@@ -80,6 +80,7 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http, $translate, $loca
|
||||
$scope.repos = {};
|
||||
$scope.seenError = '';
|
||||
$scope.upgradeInfo = {};
|
||||
$scope.stats = {};
|
||||
|
||||
$http.get(urlbase+"/lang").success(function (langs) {
|
||||
// Find the first language in the list provided by the user's browser
|
||||
@@ -175,6 +176,7 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http, $translate, $loca
|
||||
|
||||
$scope.$on('NodeDisconnected', function (event, arg) {
|
||||
delete $scope.connections[arg.data.id];
|
||||
refreshNodeStats();
|
||||
});
|
||||
|
||||
$scope.$on('NodeConnected', function (event, arg) {
|
||||
@@ -332,10 +334,18 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http, $translate, $loca
|
||||
});
|
||||
}
|
||||
|
||||
var refreshNodeStats = debounce(function () {
|
||||
$http.get(urlbase+"/stats/node").success(function (data) {
|
||||
$scope.stats = data;
|
||||
console.log("refreshNodeStats", data);
|
||||
});
|
||||
}, 500);
|
||||
|
||||
$scope.init = function() {
|
||||
refreshSystem();
|
||||
refreshConfig();
|
||||
refreshConnectionStats();
|
||||
refreshNodeStats();
|
||||
|
||||
$http.get(urlbase + '/version').success(function (data) {
|
||||
$scope.version = data;
|
||||
@@ -1049,6 +1059,12 @@ syncthing.filter('clean', function () {
|
||||
};
|
||||
});
|
||||
|
||||
syncthing.filter('asDate', function() {
|
||||
return function (input) {
|
||||
return new Date(input);
|
||||
}
|
||||
})
|
||||
|
||||
syncthing.directive('optionEditor', function () {
|
||||
return {
|
||||
restrict: 'C',
|
||||
|
||||
@@ -342,6 +342,11 @@
|
||||
<th><span class="glyphicon glyphicon-tag"></span> <span translate>Version</span></th>
|
||||
<td class="text-right">{{nodeVer(nodeCfg)}}</td>
|
||||
</tr>
|
||||
<tr ng-if="!connections[nodeCfg.NodeID]">
|
||||
<th><span class="glyphicon glyphicon-eye-open"></span> <span translate>Last seen</span></th>
|
||||
<td translate ng-if="stats[nodeCfg.NodeID].LastSeen.indexOf('1970') > -1" class="text-right">Never</td>
|
||||
<td ng-if="stats[nodeCfg.NodeID].LastSeen.indexOf('1970') < 0" class="text-right">{{stats[nodeCfg.NodeID].LastSeen | asDate | date:'short'}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"Idle": "Idle",
|
||||
"Ignore Permissions": "Ignore Permissions",
|
||||
"Keep Versions": "Keep Versions",
|
||||
"Last seen": "Last seen",
|
||||
"Latest Release": "Latest Release",
|
||||
"Local Discovery": "Local Discovery",
|
||||
"Local Discovery Port": "Local Discovery Port",
|
||||
@@ -46,6 +47,7 @@
|
||||
"Max File Change Rate (KiB/s)": "Max File Change Rate (KiB/s)",
|
||||
"Max Outstanding Requests": "Max Outstanding Requests",
|
||||
"Maximum Age": "Maximum Age",
|
||||
"Never": "Never",
|
||||
"No": "No",
|
||||
"No File Versioning": "No File Versioning",
|
||||
"Node ID": "Node ID",
|
||||
|
||||
+25
-5
@@ -22,6 +22,7 @@ import (
|
||||
"github.com/syncthing/syncthing/lamport"
|
||||
"github.com/syncthing/syncthing/protocol"
|
||||
"github.com/syncthing/syncthing/scanner"
|
||||
"github.com/syncthing/syncthing/stats"
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
)
|
||||
|
||||
@@ -72,11 +73,12 @@ type Model struct {
|
||||
clientName string
|
||||
clientVersion string
|
||||
|
||||
repoCfgs map[string]config.RepositoryConfiguration // repo -> cfg
|
||||
repoFiles map[string]*files.Set // repo -> files
|
||||
repoNodes map[string][]protocol.NodeID // repo -> nodeIDs
|
||||
nodeRepos map[protocol.NodeID][]string // nodeID -> repos
|
||||
rmut sync.RWMutex // protects the above
|
||||
repoCfgs map[string]config.RepositoryConfiguration // repo -> cfg
|
||||
repoFiles map[string]*files.Set // repo -> files
|
||||
repoNodes map[string][]protocol.NodeID // repo -> nodeIDs
|
||||
nodeRepos map[protocol.NodeID][]string // nodeID -> repos
|
||||
nodeStatRefs map[protocol.NodeID]*stats.NodeStatisticsReference // nodeID -> statsRef
|
||||
rmut sync.RWMutex // protects the above
|
||||
|
||||
repoState map[string]repoState // repo -> state
|
||||
repoStateChanged map[string]time.Time // repo -> time when state changed
|
||||
@@ -114,6 +116,7 @@ func NewModel(indexDir string, cfg *config.Configuration, nodeName, clientName,
|
||||
repoFiles: make(map[string]*files.Set),
|
||||
repoNodes: make(map[string][]protocol.NodeID),
|
||||
nodeRepos: make(map[protocol.NodeID][]string),
|
||||
nodeStatRefs: make(map[protocol.NodeID]*stats.NodeStatisticsReference),
|
||||
repoState: make(map[string]repoState),
|
||||
repoStateChanged: make(map[string]time.Time),
|
||||
protoConn: make(map[protocol.NodeID]protocol.Connection),
|
||||
@@ -122,6 +125,10 @@ func NewModel(indexDir string, cfg *config.Configuration, nodeName, clientName,
|
||||
sentLocalVer: make(map[protocol.NodeID]map[string]uint64),
|
||||
}
|
||||
|
||||
for _, node := range cfg.Nodes {
|
||||
m.nodeStatRefs[node.NodeID] = stats.NewNodeStatisticsReference(db, node.NodeID)
|
||||
}
|
||||
|
||||
var timeout = 20 * 60 // seconds
|
||||
if t := os.Getenv("STDEADLOCKTIMEOUT"); len(t) > 0 {
|
||||
it, err := strconv.Atoi(t)
|
||||
@@ -199,6 +206,15 @@ func (m *Model) ConnectionStats() map[string]ConnectionInfo {
|
||||
return res
|
||||
}
|
||||
|
||||
// Returns statistics about each node
|
||||
func (m *Model) NodeStatistics() map[string]stats.NodeStatistics {
|
||||
var res = make(map[string]stats.NodeStatistics)
|
||||
for _, node := range m.cfg.Nodes {
|
||||
res[node.NodeID.String()] = m.nodeStatRefs[node.NodeID].GetStatistics()
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Returns the completion status, in percent, for the given node and repo.
|
||||
func (m *Model) Completion(node protocol.NodeID, repo string) float64 {
|
||||
var tot int64
|
||||
@@ -535,6 +551,9 @@ func (cf cFiler) CurrentFile(file string) protocol.FileInfo {
|
||||
func (m *Model) ConnectedTo(nodeID protocol.NodeID) bool {
|
||||
m.pmut.RLock()
|
||||
_, ok := m.protoConn[nodeID]
|
||||
if ok {
|
||||
m.nodeStatRefs[nodeID].WasSeen()
|
||||
}
|
||||
m.pmut.RUnlock()
|
||||
return ok
|
||||
}
|
||||
@@ -563,6 +582,7 @@ func (m *Model) AddConnection(rawConn io.Closer, protoConn protocol.Connection)
|
||||
fs := m.repoFiles[repo]
|
||||
go sendIndexes(protoConn, repo, fs)
|
||||
}
|
||||
m.nodeStatRefs[nodeID].WasSeen()
|
||||
m.rmut.RUnlock()
|
||||
m.pmut.Unlock()
|
||||
}
|
||||
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
// Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file).
|
||||
// All rights reserved. Use of this source code is governed by an MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package stats
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/syncthing/syncthing/logger"
|
||||
)
|
||||
|
||||
var (
|
||||
debug = strings.Contains(os.Getenv("STTRACE"), "stats") || os.Getenv("STTRACE") == "all"
|
||||
l = logger.DefaultLogger
|
||||
)
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
// Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file).
|
||||
// All rights reserved. Use of this source code is governed by an MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package stats
|
||||
|
||||
// Same key space as files/leveldb.go keyType* constants
|
||||
const (
|
||||
keyTypeNodeStatistic = iota + 30
|
||||
)
|
||||
Executable
+102
@@ -0,0 +1,102 @@
|
||||
// Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file).
|
||||
// All rights reserved. Use of this source code is governed by an MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package stats
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/syncthing/syncthing/protocol"
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
)
|
||||
|
||||
const (
|
||||
nodeStatisticTypeLastSeen = iota
|
||||
)
|
||||
|
||||
var nodeStatisticsTypes = []byte{
|
||||
nodeStatisticTypeLastSeen,
|
||||
}
|
||||
|
||||
type NodeStatistics struct {
|
||||
LastSeen time.Time
|
||||
}
|
||||
|
||||
type NodeStatisticsReference struct {
|
||||
db *leveldb.DB
|
||||
node protocol.NodeID
|
||||
}
|
||||
|
||||
func NewNodeStatisticsReference(db *leveldb.DB, node protocol.NodeID) *NodeStatisticsReference {
|
||||
return &NodeStatisticsReference{
|
||||
db: db,
|
||||
node: node,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *NodeStatisticsReference) key(stat byte) []byte {
|
||||
k := make([]byte, 1+1+32)
|
||||
k[0] = keyTypeNodeStatistic
|
||||
k[1] = stat
|
||||
copy(k[1+1:], s.node[:])
|
||||
return k
|
||||
}
|
||||
|
||||
func (s *NodeStatisticsReference) GetLastSeen() time.Time {
|
||||
value, err := s.db.Get(s.key(nodeStatisticTypeLastSeen), nil)
|
||||
if err != nil {
|
||||
if err != leveldb.ErrNotFound {
|
||||
l.Warnln("NodeStatisticsReference: Failed loading last seen value for", s.node, ":", err)
|
||||
}
|
||||
return time.Unix(0, 0)
|
||||
}
|
||||
|
||||
rtime := time.Time{}
|
||||
err = rtime.UnmarshalBinary(value)
|
||||
if err != nil {
|
||||
l.Warnln("NodeStatisticsReference: Failed parsing last seen value for", s.node, ":", err)
|
||||
return time.Unix(0, 0)
|
||||
}
|
||||
if debug {
|
||||
l.Debugln("stats.NodeStatisticsReference.GetLastSeen:", s.node, rtime)
|
||||
}
|
||||
return rtime
|
||||
}
|
||||
|
||||
func (s *NodeStatisticsReference) WasSeen() {
|
||||
if debug {
|
||||
l.Debugln("stats.NodeStatisticsReference.WasSeen:", s.node)
|
||||
}
|
||||
value, err := time.Now().MarshalBinary()
|
||||
if err != nil {
|
||||
l.Warnln("NodeStatisticsReference: Failed serializing last seen value for", s.node, ":", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = s.db.Put(s.key(nodeStatisticTypeLastSeen), value, nil)
|
||||
if err != nil {
|
||||
l.Warnln("Failed serializing last seen value for", s.node, ":", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Never called, maybe because it's worth while to keep the data
|
||||
// or maybe because we have no easy way of knowing that a node has been removed.
|
||||
func (s *NodeStatisticsReference) Delete() error {
|
||||
for _, stype := range nodeStatisticsTypes {
|
||||
err := s.db.Delete(s.key(stype), nil)
|
||||
if debug && err == nil {
|
||||
l.Debugln("stats.NodeStatisticsReference.Delete:", s.node, stype)
|
||||
}
|
||||
if err != nil && err != leveldb.ErrNotFound {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *NodeStatisticsReference) GetStatistics() NodeStatistics {
|
||||
return NodeStatistics{
|
||||
LastSeen: s.GetLastSeen(),
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user