Compare commits

...

2359 commits

Author SHA1 Message Date
7edbda70f5 apply build template
Some checks failed
Build Docker Image on Commit / build-and-publish (push) Failing after 14s
2025-04-20 15:59:40 -07:00
canewsin
290025958f v0.9.0(4630) 2023-07-12 18:28:32 +05:30
canewsin
25c5658b72 Upgrade GH runner to 20.04 2023-07-12 18:22:16 +05:30
canewsin
2970e3a205 Fetch plugins changes 2023-07-12 01:25:48 +05:30
PramUkesh
866179f6a3
v0.8.6(4626) 2023-07-01 04:27:48 +05:30
PramUkesh
e8cf14bcf5
Add trackers to Config.py for failsafety incase missing trackers..txt file 2023-07-01 04:25:41 +05:30
PramUkesh
fedcf9c1c6
Added Proxy links 2023-07-01 03:21:32 +05:30
PramUkesh
117bcf25d9
Fix pysha3 dep installation issue 2023-07-01 02:56:49 +05:30
canewsin
a429349cd4 FileRequest -> Fix error wording 2023-03-24 02:24:14 +05:30
canewsin
d8e52eaabd FileRequest -> Remove Unnecessary check 2023-03-24 02:23:16 +05:30
canewsin
f2ef6e5d9c Fix Response when site is missing for actionAs 2023-02-24 16:56:10 +05:30
canewsin
dd2bb07cfb v0.8.5(4625) 2023-02-12 00:41:38 +05:30
Seto
06a9d1e0ff Fix openssl error in windows. 2023-02-10 18:51:36 +05:30
canewsin
c354f9e24d Use default theme-class for corrupt users.json file
where settings key is missing etc
Fixes Ui.UiServer Error 500: UiWSGIHandler error
2022-12-25 01:28:16 +05:30
canewsin
77b4297224 Update Stats Plugin 2022-12-25 01:26:53 +05:30
canewsin
edc5310cd2 v0.8.4(4620) 2022-12-11 05:01:55 +05:30
canewsin
99a8409513 Increase Def Min Site Size to 25MB 2022-12-11 04:30:31 +05:30
canewsin
3550a64837 v0.8.3(4611) 2022-12-11 03:21:22 +05:30
canewsin
85ef28e6fb ContentManager.py Improve Logging of Valid Signers 2022-12-11 03:21:22 +05:30
canewsin
1500d9356b SiteStrorage.py -> Fix accessing unassigned varible 2022-12-11 03:21:22 +05:30
canewsin
f1a71770fa ContentManager -> Support for multiSig 2022-12-11 03:21:22 +05:30
canewsin
f79a73cef4 main.py -> Fix accessing unassigned varible 2022-12-11 00:51:23 +05:30
canewsin
0731787518 v0.8.2(4610) 2022-11-01 18:10:15 +05:30
canewsin
ad95eede10 Config:: Skip loading missing tracker files 2022-11-01 18:06:32 +05:30
canewsin
459b0a73ca Move trackers to seperate file & Add more trackers 2022-11-01 18:01:03 +05:30
canewsin
b7870edd2e Fix Startup Error when plugins dir missing 2022-11-01 18:00:58 +05:30
Ganesh Chowdary Nune
d5703541be Added documentation for getRandomPort fn 2022-10-09 02:36:18 +05:30
canewsin
ba96654e1d
v 0.8.1-patch(4601) 2022-10-05 03:36:15 +05:30
canewsin
ac72d623f0
remove duplicate xescape(s) 2022-10-05 03:33:50 +05:30
canewsin
fd857985f6
v0.8.0(4600) 2022-10-01 02:22:50 +05:30
canewsin
966f671efe
Update CHANGELOG.md 2022-10-01 02:21:54 +05:30
caryoscelus
86109ae4b2 fix readdress loop
use better escaping in render

fixes #19
2022-09-15 19:18:23 +05:30
canewsin
611fc774c8
Remove Patreon badge 2022-06-13 23:07:57 +05:30
BratishkaErik
0ed0b746a4
Update README-ru.md (#177)
@BratishkaErik  Thanks for your contribution
2022-06-13 23:06:04 +05:30
canewsin
49e68c3a78 Include inner_path of failed request for signing in error msg and response 2022-06-11 01:36:01 +05:30
canewsin
3ac677c9a7 Don't Fail Silently When Cert is Not Selected
When Site doesn't have cert selected but has userdata, signing userdata fails silently without proper error message
2022-06-11 01:18:02 +05:30
canewsin
016cfe9e16 Console Log Updates, Specify min supported ZeroNet version for Rust version Protocol Compatibility
Reduce noise(error => warning) on file missing in sites.
2022-06-09 22:38:57 +05:30
canewsin
712ee18634
Update FUNDING.yml 2022-06-02 19:15:22 +05:30
canewsin
5579c6b3cc rev4591 2022-05-27 08:58:42 +05:30
canewsin
c3815c56ea Revert File Open to catch File Access Errors.
https://github.com/ZeroNetX/ZeroNet/issues/174
2022-05-27 08:38:20 +05:30
canewsin
b257338b0a
v 0.8.0(4590)
- Major Version Upgrade to reflect RCE reported by geekless.
2022-05-26 17:30:59 +05:30
canewsin
ac70f83879 v 0.7.9-patch(4586) 2022-05-26 15:41:47 +05:30
canewsin
2ad80afa10 actionUpdate response Optimisation 2022-05-26 11:48:15 +05:30
canewsin
fe048cd08c Update Plugins Repo 2022-05-26 11:47:25 +05:30
canewsin
f9d7ccd83c Fix Unhandled File Access Errors 2022-05-26 11:46:58 +05:30
canewsin
b29884db78
Create codeql-analysis.yml 2022-05-19 00:10:38 +05:30
canewsin
a5190234ab v 0.7.9(4585)
- Tracker Supply Improvements.
- First Party Tracker Update Service using Dashboard Site.
2022-04-08 23:31:12 +05:30
canewsin
00db9c9f87 Rust Version Compatibility for update Protocol msg
and diff patch
2022-04-08 23:12:10 +05:30
canewsin
02ceb70a4f Tracker Supply improvemets
- Removed Non Working Trakers.
 - Dynamically Load Trackers from Dashboard Site.
2022-03-26 18:39:01 +05:30
canewsin
7ce118d645 Fix Repo Url for Bug Report 2022-03-12 17:38:23 +05:30
canewsin
eb397cf4c7 Update Plugins Repo 2022-03-12 11:14:10 +05:30
Marek Küthe
f8c9f2da4f
remove old v2 onion service (#158) 2022-03-12 10:40:33 +05:30
canewsin
69d7eacfa4 v 0.7.9-beta (4581) 2022-03-06 18:23:17 +05:30
canewsin
f498aedb96 v0.7.8 (4580)
- Update Plugins with some bug fixes and Improvements
2022-03-02 20:17:14 +05:30
canewsin
5ee928852b v 0.7.6 (4565)
- Sync Plugin Updates
- Clean up tor v3 patch (#115)
    https://github.com/ZeroNetX/ZeroNet/pull/115
- Add More Default Plugins to Repo
- Doubled Site Publish Limits
- Update ZeroNet Repo Urls (#103)
- UI/UX: Increases Size of Notifications Close Button(#106)
- Moved Plugins to Seperate Repo
- Added `access_key` variable in Config, this used to access restrited plugins when multiuser plugin is enabled. When MultiUserPlugin is enabled we cannot access some pages like /Stats, this key will remove such restriction with access key.
- Added `last_connection_id_current_version` to ConnectionServer, helpful to estimate no of connection from current client version.
- Added current version:  connections to /Stats page. see the previous point.
2022-01-12 05:13:17 +05:30
canewsin
7078badefa Update Docker Image 2021-12-03 01:18:53 +05:30
canewsin
edd2760fed v 0.7.5 (4560) 2021-11-28 23:45:42 +05:30
canewsin
7d1ec41d09 v 0.7.3 (4556) 2021-11-28 22:35:33 +05:30
canewsin
7acd8df906 Fix xrange is undefined error
- xrange is undefined error in  Tor-v3 Patch Files
2021-11-28 22:06:50 +05:30
canewsin
a1eb6eede5 Fix Incorrect viewport on mobile while loading
https://github.com/HelloZeroNet/ZeroNet/issues/2474
2021-11-28 01:23:52 +05:30
canewsin
eab7fc2be4 Tor V3 Patch 2021-11-28 01:15:19 +05:30
ZeroNet
454c0b2e7e
Merge pull request #2716 from imachug/uifile-404-fix
Fix 404 error handler in UiFilePlugin
2021-01-25 03:24:19 +01:00
ZeroNet
03da34c5d6
Merge pull request #2714 from timgates42/bugfix_typo_positive
docs: fix simple typo, positibe -> positive
2021-01-25 03:23:46 +01:00
Ivanq
c3f4591f91 Fix 404 error handler in UiFilePlugin 2020-12-27 13:28:35 +03:00
Tim Gates
3ad7bc87e5
docs: fix simple typo, positibe -> positive
There is a small typo in src/util/UpnpPunch.py.

Should read `positive` rather than `positibe`.
2020-12-22 07:44:57 +11:00
ZeroNet
b4f4c12521
Merge pull request #2695 from kabitofu/test
Japanese Translation
2020-12-14 01:40:45 +01:00
kabitofu
39d86fec9c Japanese Translation 2020-12-04 13:07:32 +09:00
Tamas Kocsis
02c27b841f Rev4555 2020-12-03 20:05:41 +01:00
Tamas Kocsis
8dafbef6ad Fix sidebar menu display 2020-12-03 20:05:13 +01:00
Tamas Kocsis
c831d175ad Merge UiFileManager js 2020-12-03 20:04:58 +01:00
Tamas Kocsis
3cbfbae42d Move file listing binary extension list to separate file, add missing comma 2020-12-03 20:04:37 +01:00
Tamas Kocsis
a1105562cd Fix site listing show on big site visit 2020-12-03 20:04:09 +01:00
Tamas Kocsis
b3c9de5e47 Don't show tracker tor bridge warning if more that 3 trackers finished 2020-12-03 20:02:48 +01:00
Tamas Kocsis
3ffa3c2f79 Use svg for top-right zero button 2020-12-03 20:02:20 +01:00
ZeroNet
03273527da
Merge pull request #2694 from styromaniac/patch-3
Replaced logo-white.png with an SVG data URI. (logo-white.png deleted)
2020-12-03 19:59:40 +01:00
Styromaniac
2795e20b0c
Replaced logo-white.png with an SVG data URI. 2020-12-03 08:33:54 -05:00
ZeroNet
eb86df5fb6
Add Python 3.9 to github tests 2020-11-30 14:51:23 +01:00
Tamas Kocsis
ecfb6b6b3a Rev4553, Debug messages formatting Windows fix 2020-11-30 14:38:25 +01:00
Tamas Kocsis
1b4f93f14b Make Debug message test cases independent from line numbers, Windows support 2020-11-30 14:37:45 +01:00
ZeroNet
40db30a260
Merge pull request #2642 from imachug/better-logs
Use more unique yet short paths for logging
2020-11-30 14:08:50 +01:00
ZeroNet
3a4a5404c0
Merge pull request #2686 from kabitofu/test
Corrections and additions to the Japanese translation
2020-11-28 01:36:19 +01:00
kabitofu
2bb12a247b Japanese Translation 2020-11-27 17:49:21 +09:00
Tamas Kocsis
38a3ea6373 Rev4551, Keep uiserver running if fileserver bind failed 2020-11-26 02:01:41 +01:00
ZeroNet
2798ad6fb2
Readme formatting 2020-11-24 15:39:57 +01:00
ZeroNet
2e7b0071a3
Remove unnecessary html tag from readme 2020-11-24 15:38:12 +01:00
ZeroNet
12e82bc9c4
Merge pull request #2682 from canewsin/patch-4
Added New Google Play Links
2020-11-24 15:33:34 +01:00
canewsin
774691fa39 Added New Google Play Links 2020-11-23 09:36:37 +05:30
Tamas Kocsis
52d6c9fedf Rev4550, Show all modified files after click 2020-11-19 03:05:53 +01:00
ZeroNet
d68c635e9a
Merge pull request #2679 from hashy0917/patch-1
bug fix.
2020-11-19 02:40:47 +01:00
hashy0917
21557b5517
bug fix.
Fixed the part where an error occurs when setting to Japanese.
2020-11-17 19:25:23 +09:00
ZeroNet
11fe0ece67
Add XDA labs link for Android client 2020-11-14 03:15:13 +01:00
ZeroNet
92363d5227
Add .onion a address of zeronet.io website 2020-11-12 02:37:44 +01:00
ZeroNet
cf0c5db5b9
Replace Play Store link as Google removed it 2020-11-12 01:36:49 +01:00
Tamas Kocsis
57dda4e6d6 Rev4549, Fix startup OpenSSL lib find recursion error 2020-11-09 01:21:52 +01:00
Tamas Kocsis
0a3bf43e1c Rev4548 2020-11-03 02:53:15 +01:00
Tamas Kocsis
48455e3e45 Better cli test output 2020-11-03 02:52:50 +01:00
Tamas Kocsis
c515e26cd6 Fix OpenSSL dll/so location find patcher 2020-11-03 02:51:42 +01:00
Tamas Kocsis
5cac059ef4 Display warning if SSLCurve native load failed 2020-11-03 02:50:21 +01:00
Tamas Kocsis
8f6e27904c Display verification lib speedups on benchmark 2020-11-03 02:49:01 +01:00
Tamas Kocsis
e757f2a2d4 Display library versions at /Env url endpoint 2020-11-03 02:48:01 +01:00
Tamas Kocsis
b104d5dd41 Refactor /Stats page rendering to seprate functions 2020-11-03 02:44:31 +01:00
ZeroNet
f6106be733
Merge pull request #2670 from TTTaevas/py3
Fix typo in French translation
2020-11-03 02:34:34 +01:00
Taevas
9305a2e7ac Fix typo in French translation 2020-11-02 15:29:29 +01:00
Jabba
4f6833c488
Complete list of binary extensions (#2661) 2020-10-29 03:24:35 +01:00
Tamas Kocsis
e2b1cf3938 Revert "Travis CI: Run a current version of pytest (#2648)"
This reverts commit 147dd4bc35.
2020-10-29 02:49:04 +01:00
Tamas Kocsis
6fcfe5b394 Rev4540, More proper bigfile filtering for OptionalFileList 2020-10-29 02:44:07 +01:00
Tamas Kocsis
12013d64c8 Rev4539, Add more extensions to UiFileManager binary files 2020-10-29 01:38:49 +01:00
Jabba
54fb2fde7c
Adding OGG MIME (#2657)
* Adding OGG MIME

Fixing: https://github.com/HelloZeroNet/ZeroNet/issues/2656

* Adding ova and ogv extensions
2020-10-26 15:59:42 +01:00
Christian Clauss
147dd4bc35
Travis CI: Run a current version of pytest (#2648)
Pytest 4 --> 6
2020-10-26 15:47:15 +01:00
Christian Clauss
32c9d5fa70
GitHub Actions upgrade to actions/checkout@v2 (#2650)
* GitHub Actions upgrade to actions/checkout@v2

* Update tests.yml
2020-10-26 15:41:46 +01:00
Ivanq
dd08b89c81 Make tests pass on Python 3.5 2020-10-13 20:36:39 +03:00
Ivanq
6770b450b3 Handle src/gevent/... paths 2020-10-13 19:50:08 +03:00
Ivanq
9b2772b171 Use more unique yet short paths for logging 2020-10-13 19:12:46 +03:00
shortcutme
29dac8a188
Rev4538 2020-10-12 13:12:44 +02:00
Ivanq
352da6bf62
Allow sites to request several CORS permissions at once (#2631)
* Allow sites to request several CORS permissions at once

* Fix typo

* Don't wait for CORS site download
2020-10-12 13:00:40 +02:00
Tamas Kocsis
288050e5b4 Rev4537, Add warning on invalid file save in UiFileManager 2020-10-06 17:10:58 +02:00
Tamas Kocsis
785d2351eb Rev4536, Fix Cors permission request for connecting site 2020-10-05 19:02:22 +02:00
Tamas Kocsis
9d1bed11af Rev4533 2020-10-01 17:18:43 +02:00
Tamas Kocsis
b2342e64bd Fix file manager listing height calculation for many files 2020-10-01 17:18:33 +02:00
Tamas Kocsis
dcbfb8afe0 Fix browse files link for not installed domain plugins 2020-10-01 17:17:51 +02:00
Jabba
4b8dfc5114
Update requirements.txt (#2617)
* Update requirements.txt

See: https://github.com/HelloZeroNet/ZeroNet/pull/2616#issuecomment-697341526
2020-09-24 18:24:24 +02:00
Tamas Kocsis
c0baf8b68d Version 0.7.2, Rev4528 2020-09-21 18:28:12 +02:00
Tamas Kocsis
73dc69605b Merge sidebar js, css 2020-09-21 18:26:55 +02:00
Tamas Kocsis
52ed8c18ca Add browse files link to sidebar 2020-09-21 18:26:44 +02:00
Tamas Kocsis
19bc0358b5 Merge UiFileManager js, css 2020-09-21 18:25:53 +02:00
Tamas Kocsis
392350ff79 Codemirror file editor for UiFileManager plugin 2020-09-21 18:25:38 +02:00
Tamas Kocsis
f0b0f57643 UiFileManager plugin 2020-09-21 18:23:28 +02:00
Tamas Kocsis
85790f8866 Check sites on ip change 2020-09-21 18:20:49 +02:00
Tamas Kocsis
ce5b4c3eda Don't non-existent files as bad 2020-09-18 18:45:42 +02:00
Tamas Kocsis
fde3b51129 Formatting 2020-09-18 18:44:42 +02:00
Tamas Kocsis
550d02d473 Retry site update if it was failed last time 2020-09-18 18:44:28 +02:00
Tamas Kocsis
4da89580c1 Don't mark content.json as bad file if update failed 2020-09-18 18:43:54 +02:00
Tamas Kocsis
bf092b83ab Workaround for stuck iframe url in Firefox when using back button 2020-09-18 18:43:25 +02:00
Tamas Kocsis
0309b81695 SiteListModifiedFiles: Give error instead of exception if content file does not exists 2020-09-18 18:42:03 +02:00
Tamas Kocsis
e74fdc4036 Redirect homepage with / at the end 2020-09-09 18:29:53 +02:00
Tamas Kocsis
b9c65d75ef Move error log handler to config object to be able to catch plugin load errors 2020-09-09 18:29:24 +02:00
Tamas Kocsis
49f8e0bc3a Allow link to console tabs 2020-09-09 18:21:09 +02:00
Tamas Kocsis
c4f8c0177e Add mode to tracker announce logging 2020-09-08 19:36:54 +02:00
Tamas Kocsis
8c20927f68 Allow test port checker functions from CLI 2020-09-08 19:35:58 +02:00
Tamas Kocsis
5b09f7af41 New port checker: ipfingerprints.com, PortChecker minor rearranging 2020-09-08 19:35:23 +02:00
Tamas Kocsis
1695571afa Add browser-like header for port checker requests 2020-09-08 19:32:45 +02:00
Tamas Kocsis
8dc5aee8aa Js based redirecting template formatting 2020-09-08 19:32:10 +02:00
Tamas Kocsis
94765af0f3 Fix not downloaded site delete on startup 2020-09-08 19:28:41 +02:00
Tamas Kocsis
5a226baaa5 Reduce announce number for not recently added sites 2020-09-08 19:28:04 +02:00
Tamas Kocsis
b7bc197012 Only try to get more peers for timeout task if site is recently added 2020-09-08 19:26:18 +02:00
Tamas Kocsis
a0dfbe31f6 Add timeout for private key recover message 2020-09-06 17:06:26 +02:00
Tamas Kocsis
964545dd1f Remove unnecessary logging 2020-09-06 17:01:59 +02:00
Tamas Kocsis
817ab04941 Fix private key recover typo 2020-09-04 18:29:02 +02:00
Tamas Kocsis
91d0ce3a50 Save users.json of private key change 2020-09-04 18:21:52 +02:00
Tamas Kocsis
e97236201c Try to recover site privatekey from master seed when site owned switch enabled 2020-09-04 18:21:02 +02:00
Tamas Kocsis
e14f5bf847 Allow modified files query from non-admin sites 2020-09-04 18:15:56 +02:00
Tamas Kocsis
79f10ffe0c Return error when fileGet binary file 2020-09-04 18:15:16 +02:00
Tamas Kocsis
0bc9374a7d Optional stats to dirList websocket API command 2020-09-04 18:14:22 +02:00
Tamas Kocsis
8a71bf65cd Don't leak local path on delete error 2020-09-04 18:08:43 +02:00
Tamas Kocsis
9d198ff7f2 Display full path in 404 error instead of inner_path 2020-09-04 18:07:29 +02:00
Tamas Kocsis
cafeebf120 Fix wrapper_nonce adding to url 2020-09-04 18:07:03 +02:00
Tamas Kocsis
46fba195da Merge js, css 2020-09-04 17:57:56 +02:00
Tamas Kocsis
501bd51bd1 Only set title from content.json if wrapperSetTitle has not been called 2020-09-04 17:57:34 +02:00
Tamas Kocsis
f7874e1ca3 Fix loading bar hide bug 2020-09-04 17:56:16 +02:00
Tamas Kocsis
8d964d1b8e Fix infopanel overflow on mobile devices 2020-09-04 17:55:41 +02:00
Tamas Kocsis
051e404a80 Fix typo in Benchmark cli info success number 2020-09-04 17:52:26 +02:00
Tamas Kocsis
6c1abf4004 Don't switch to libev for newer versions of gevent 2020-09-04 17:49:23 +02:00
Tamas Kocsis
0907edb6b1 Remove obsolate auth_key generation 2020-09-04 17:35:48 +02:00
Tamas Kocsis
6ff14d1bbd Fix plugin config error when running update.py 2020-09-04 17:17:15 +02:00
Tamas Kocsis
4ad5c065f1 Don't display gui error when running from cli on Windows 2020-09-04 17:16:47 +02:00
ZeroNet
c17b8d53d3
Update changelog with 0.6.5, 0.7.0, 0.7.1 2020-09-03 16:56:41 +02:00
ZeroNet
9022a1098a
Merge pull request #2485 from geekless/sidebar-no-content-json
Allow opening the sidebar while content.json is not loaded
2020-07-20 18:00:09 +02:00
ZeroNet
6e758ff363
Merge pull request #2596 from shyam-sam/Dockerfile-arm64v8
arm64 arch docker image request #2568
2020-07-20 17:42:12 +02:00
SuperMan
29c3523353 arm64 arch docker image request #2568 2020-07-18 17:45:32 +05:30
shortcutme
47ff6c6801
Rev4496 2020-06-30 17:04:55 +02:00
shortcutme
6bd49e8aff
Fix killing greenlets gevent exception 2020-06-30 17:04:47 +02:00
shortcutme
ddbd5c7b19
Fix reset file server port with config web interface 2020-06-30 17:04:09 +02:00
shortcutme
635c3b27cd
Fix loading invalid site block list 2020-06-30 17:03:06 +02:00
shortcutme
6776dabdb3
Fix piecemap downlad error when invalid piecemap got downloaded 2020-06-30 17:02:39 +02:00
shortcutme
14cbaf47c8
Rev4493 2020-06-18 17:28:56 +02:00
shortcutme
4eb50377c3
Warning about deleting private key for owned sites 2020-06-18 17:23:15 +02:00
shortcutme
ea6016d004
Fix latest gevent compatibility 2020-06-18 17:22:45 +02:00
shortcutme
79d26060b3
Add site address hash to site info websocket response 2020-06-18 17:22:33 +02:00
shortcutme
97ad084c21
Ignore ipv6 tests if not supported by os 2020-06-18 17:22:08 +02:00
shortcutme
179e5cb651
Fix portchecker.co 2020-06-18 17:21:43 +02:00
ZeroNet
367745b5ea
Move Android Play store link next to download options 2020-06-16 18:25:58 +02:00
ZeroNet
5c38a78b79
Merge pull request #2573 from canewsin/patch-2
Added Android Play Store Link to Read Me
2020-06-16 18:24:48 +02:00
canewsin
a02ed56c69
Added Android Play Store Link to Read Me 2020-06-16 10:33:21 +05:30
ZeroNet
f868fed51d
Merge pull request #2558 from gqgs/ws-iterable
Avoid iterating in uninitialized result
2020-05-19 02:02:16 +02:00
Guilherme
e4f42b8ce3 Avoid iterating in uninitialized result 2020-05-11 11:51:10 -03:00
ZeroNet
eeb48fc72e
Merge pull request #2556 from gqgs/debug
Remove unnecessary debugger
2020-05-10 12:07:39 +02:00
Guilherme
85733abade Remove unnecessary debugger 2020-05-10 02:04:30 -03:00
shortcutme
8db4344171
Rev4486, Fix UiPassword cleanup error 2020-05-04 13:38:30 +02:00
ZeroNet
0a9391d28b
Merge pull request #2547 from anoadragon453/anoa/pluralize
Fix pluralize translation function
2020-05-03 17:51:26 +02:00
Andrew Morgan
cfef7ab071 Fix pluralize translation function 2020-05-03 14:31:20 +01:00
shortcutme
38c1727b94
Rev4485 2020-05-03 03:59:33 +02:00
shortcutme
36d96d484e
Workaround for UiPassword cookie issues with sandboxed iframes 2020-05-03 03:59:09 +02:00
shortcutme
439f8fc476
Fix UiPassword logout and session list url encoding 2020-05-03 03:57:17 +02:00
shortcutme
07faa3d6d3
Move wrapper necessary check to separate function 2020-05-03 03:56:06 +02:00
ZeroNet
3c7022ea9d
Merge pull request #2546 from anoadragon453/anoa/bigfile_seekable
Add missing seekable() class method to BigFile plugin
2020-05-02 11:23:30 +02:00
Andrew Morgan
a657afcd47 Add missing seekable() class method to BigFile plugin 2020-05-01 18:24:47 +01:00
ZeroNet
f3a839f422
Require final gevent 1.5.0 for Python 3.8 2020-04-12 12:15:10 +02:00
shortcutme
ad3920b26a
Rev4478, Skip slow updated files checking with large content.json 2020-04-11 13:34:18 +02:00
ZeroNet
8ffd8d7a3e
Merge pull request #2510 from filips123/patch-1
Use Gevent prerelease for Python 3.8
2020-04-08 21:38:43 +02:00
Filip Š
71001491df
Use Gevent prerelease for Python 3.8 2020-04-08 17:05:39 +02:00
ZeroNet
701765b53b
Merge pull request #2496 from canewsin/patch-2
Update LICENSE
2020-04-01 17:54:47 +02:00
ZeroNet
fa880d99f1
Merge pull request #2503 from imachug/compressed-keys
Support compressed keys
2020-03-31 00:48:28 +02:00
Ivanq
0a9a9b5a57 Support compressed keys 2020-03-30 09:40:06 +03:00
shortcutme
56acac8cd3
Rev4473, Fix Merger site skipping content load to db for some seconds after new site added 2020-03-25 04:13:16 +01:00
ZeroNet
995d3bf717
Merge pull request #2495 from pataquets/patch-1
Readme: Add Docker image info and docker pulls badge
2020-03-25 00:37:16 +01:00
canewsin
1de7485858
Update LICENSE 2020-03-25 03:30:41 +05:30
Alfonso Montero
e1c0fd6984
Readme: Add Docker image info and docker pulls badge 2020-03-24 21:16:33 +01:00
ZeroNet
108a3de433
Update Dockerfile 2020-03-24 02:26:54 +01:00
ZeroNet
740fe65355
Update Dockerfile 2020-03-24 02:09:57 +01:00
ZeroNet
abde3d4cf7
Update Dockerfile 2020-03-24 01:58:33 +01:00
ZeroNet
c90c887f8f
Merge pull request #2491 from imachug/import-sslcrypto
Import sslcrypto from lib
2020-03-21 21:50:35 +01:00
Ivanq
a4d91f7081 Import sslcrypto from lib 2020-03-21 22:52:56 +03:00
shortcutme
31d4304915
Rev4471, Allow files start with dot 2020-03-21 19:51:44 +01:00
shortcutme
1eec388252
Rev4469 2020-03-20 18:53:25 +01:00
shortcutme
70de3213d6
Fix peer save dictionary changed error 2020-03-20 18:52:58 +01:00
shortcutme
f41d022038
Log BrokenPipeError as warning 2020-03-20 18:52:18 +01:00
shortcutme
723d1f4370
Rev4467 2020-03-18 03:21:14 +01:00
shortcutme
ca94703fc3
Fix tray icon destroy overflow exception 2020-03-18 03:21:00 +01:00
shortcutme
a5971adbe6
Add data_dir to example UiConfig tracker list 2020-03-18 03:19:01 +01:00
ZeroNet
dfeebbabe8
Merge pull request #2487 from imachug/gevent-ws-fix2
Update gevent-ws to v2.0.7 to fix werkzeug
2020-03-17 21:49:54 +01:00
Ivanq
66194ce435 Update gevent-ws to v2.0.7 to fix werkzeug 2020-03-17 23:48:36 +03:00
Vadim Ushakov
2de3c9a544 Allow opening the sidebar while content.json is not loaded
If one opens the sidebar of a site not being downloaded yet, the following error occurs:

```
  Internal error: KeyError('content.json',): 'content.json'
  UiWebsocket.py line 79 > 235 > Sidebar/SidebarPlugin.py line 527 > 120 > ContentDbDict.py line 59
```

Also, the sidebar is not visible.

This fixes the both issues.

For sites without peers, the only way to delete the site was to navigate to ZeroHellow, scroll the left panel to "Connecting sites", and delete the site from the list. Now those sites can be deleted from the sidebar.
2020-03-17 23:09:40 +07:00
shortcutme
5fb342a825
Change to GPLv3 license
Based on https://github.com/HelloZeroNet/ZeroNet/issues/2273
2020-03-17 14:48:24 +01:00
ZeroNet
3156d2f94b
Merge pull request #2483 from imachug/gevent-ws-fix
Potential fix of BrokenPipeError
2020-03-17 14:25:11 +01:00
Ivanq
ba156bbdec Potential fix of BrokenPipeError 2020-03-17 07:54:56 +03:00
ZeroNet
6beb76eac8
Merge pull request #2482 from imachug/gevent-ws-insensitive
Upgrade gevent-ws to v2.0.5
2020-03-16 21:36:43 +01:00
Ivanq
d3d18234df Upgrade gevent-ws to v2.0.5 2020-03-16 20:50:10 +03:00
ZeroNet
faa24a8b41
Merge pull request #2478 from imachug/sslcrypto-weird
Switch to sslcrypto v4.0 to support OpenSSL without builtin curves
2020-03-16 17:43:30 +01:00
ZeroNet
f749228a2c
Merge pull request #2475 from imachug/gevent-ws-fix2
Disable process_result on websocket requests
2020-03-16 16:16:47 +01:00
Ivanq
7e17a4e967 Switch to sslcrypto v4.0 to support OpenSSL without builtin curves 2020-03-15 20:18:04 +03:00
Ivanq
19f003141b Disable process_result on websocket requests 2020-03-14 07:27:19 +03:00
ZeroNet
53a6063576
Merge pull request #2471 from imachug/patch-1
Search for any OpenSSL version in LD_LIBRARY_PATH
2020-03-10 21:34:39 +01:00
Ivanq
33af83b2cd
Search for any OpenSSL version in LD_LIBRARY_PATH 2020-03-10 22:31:26 +03:00
ZeroNet
3426d5fe63
Merge pull request #2466 from imachug/websocket
Fix websocket_client compatibility
2020-03-09 15:54:54 +01:00
ZeroNet
f2934c10b4
Merge pull request #2463 from canewsin/patch-1
Added Github Action Test Badge to ReadMe
2020-03-09 15:51:13 +01:00
Ivanq
a2457b2488 Forgot that Upgrade is case-insensitive 2020-03-09 11:06:35 +03:00
canewsin
193632c3f9
Added Github Action Test Badge to ReadMe 2020-03-07 17:30:27 +05:30
ZeroNet
a1c176bb3f
Merge pull request #2459 from imachug/github-actions
Add GitHub Actions workflow
2020-03-05 21:16:13 +01:00
Ivanq
02fd1dc4d0 Add GitHub Actions workflow 2020-03-05 23:03:23 +03:00
ZeroNet
296e4aab57
Fix sslcrypto thread safety (#2454)
* Use sslcrypto instead of pyelliptic and pybitcointools

* Fix CryptMessage

* Support Python 3.4

* Fix user creation

* Get rid of pyelliptic and pybitcointools

* Fix typo

* Delete test file

* Add sslcrypto to tree

* Update sslcrypto

* Add pyaes to src/lib

* Fix typo in tests

* Update sslcrypto version

* Use privatekey_bin instead of privatekey for bytes objects

* Fix sslcrypto

* Fix Benchmark plugin

* Don't calculate the same thing twice

* Only import sslcrypto once

* Handle fallback sslcrypto implementation during tests

* Fix sslcrypto fallback implementation selection

* Fix thread safety

* Add derivation

* Bring split back

* Fix typo

* v3.3

* Fix custom OpenSSL discovery
2020-03-05 17:54:46 +01:00
ZeroNet
7ba2c9344d
Merge pull request #2457 from imachug/segfault
Make ThreadPool a context manager to prevent memory leaks
2020-03-05 10:45:14 +01:00
Ivanq
09e65e1d95 Make ThreadPool a context manager to prevent memory leaks 2020-03-05 08:06:57 +03:00
shortcutme
c4f65a5d7b
Rev4462, Experimental fix for segfault on shutdown 2020-03-04 21:50:28 +01:00
ZeroNet
37a401fdef
Merge pull request #2449 from krzotr/polish-translation
Polish translation
2020-03-04 18:14:06 +01:00
ZeroNet
e7d1e1f097
Merge pull request #2455 from zyw271828/py3
Improve README-zh-cn.md according to latest README.md
2020-03-03 10:36:51 +01:00
zyw271828
6df3036f11
Improve README-zh-cn.md according to latest README.md 2020-03-03 13:12:54 +08:00
zyw271828
e2a582d892
Update "How can I create a ZeroNet site" section of README-zh-cn.md 2020-03-03 12:54:41 +08:00
zyw271828
aaabcb6b1a
Update "How to join" section of README-zh-cn.md 2020-03-03 12:48:18 +08:00
ZeroNet
7bf790003e
Merge pull request #2453 from krzotr/patch-7
Fixed `Cache-Control` for .js and .css files - 10 minutes cache
2020-03-02 18:25:16 +01:00
shortcutme
f46b945cdc
Rev4461 2020-03-02 17:09:21 +01:00
shortcutme
27761c5045
Fix merger site updating 2020-03-02 17:09:13 +01:00
shortcutme
e0bf4dc9ec
Skip announcing to trackers with unsupported address 2020-03-02 17:08:43 +01:00
shortcutme
1fc67a3d71
Rev4460, Fix mergersite update on slow storage 2020-03-02 16:44:34 +01:00
krzotr
5baacf963d
Fixed Cache-Control for .js and .css files 2020-02-29 00:51:41 +01:00
Krzysztof Otręba
b790bcac9b Polish translation 2020-02-28 01:24:44 +01:00
Ivanq
219b90668f
Switch from gevent-websocket to gevent-ws (#2439)
* Switch from gevent-websocket to gevent-ws

* Return error handling, add gevent_ws source to lib
2020-02-28 01:20:04 +01:00
krzotr
2862587c15
Fixed "LookupError: 'hex' is not a text encoding" on /StatsBootstrapper page (#2442)
* Fixed "LookupError: 'hex' is not a text encoding"

* Fixed  KeyError: 'ip4'
2020-02-27 00:48:26 +01:00
shortcutme
6218a92895
Rev4458 2020-02-25 16:47:28 +01:00
shortcutme
58f03e21ef
Change unreliable trackers 2020-02-25 16:47:04 +01:00
shortcutme
b85477787d
Workaround for Tor utf8 cookie file path encoding bug on Windows 2020-02-25 16:46:21 +01:00
shortcutme
6a1235bd45
Remove old Gevent RLock support 2020-02-25 16:45:55 +01:00
ZeroNet
33d6a9c402
Merge pull request #2438 from imachug/websocket
Avoid code duplication in bigfileUploadInit
2020-02-24 17:56:14 +01:00
Ivanq
17f65a5179 Avoid code duplication 2020-02-24 19:19:35 +03:00
Ivanq
f8e2cbe429
Allow uploading files via websocket (#2437)
* Allow uploading files via websocket

* Fix
2020-02-24 13:46:01 +01:00
shortcutme
f0a706f6ab
Rev4455, Fix new sites file downloading 2020-02-21 13:58:11 +01:00
shortcutme
8b994e42c2
Rev4452 2020-02-20 17:27:50 +01:00
shortcutme
ae9a76a6c9
Fix double sites.json loading on startup when adding missing sites 2020-02-20 17:27:31 +01:00
shortcutme
9b85d8638d
Don't allow run site api calls when site is deleting 2020-02-20 17:25:56 +01:00
shortcutme
a9c75a3146
Fix start dir parsing for command line and better description 2020-02-20 17:25:06 +01:00
shortcutme
1cc0ec3f31
Indepently configurable OpenSSL lib/bin file 2020-02-20 17:23:00 +01:00
shortcutme
b1819ff71d
Fix trayicon autostart script duplicated arguments 2020-02-20 17:19:16 +01:00
shortcutme
fca1033f83
Fix trayicon auto start script write/read with utf8 path 2020-02-20 17:18:59 +01:00
ZeroNet
32855d0479
Merge pull request #2426 from canewsin/patch-2
Added Custom Openssl Path for Native Clients and start_dir config
2020-02-19 17:20:24 +01:00
shortcutme
2c826eba2d
Rev4447, Fix Msgpack 1.0.0 compatibility 2020-02-19 16:48:14 +01:00
canewsin
8facd9ff84 Added Custom Openssl Path for Native Clients and start_dir config
This Parameter helpful where openssl path is not fixed always, we can also use this to reduce code verbosity by providing other like these and provide them as parameter

            if sys.platform.startswith("win"):
                self.openssl_bin = "tools\\openssl\\openssl.exe"
            elif config.dist_type.startswith("bundle_linux"):
                self.openssl_bin = "../runtime/bin/openssl"
            else:
                self.openssl_bin = "openssl"
Also Added Custom start_dir config option since android path issue of not valid "./" path, where files via provided path are not loading on some systems like Android client.

for more detailed conversation see pull request [#2422](https://github.com/HelloZeroNet/ZeroNet/pull/2422)
2020-02-18 23:09:16 +05:30
shortcutme
64e5e0c80e
Rev445, Fix and test random fail in CryptMessage decrypt 2020-02-18 15:28:14 +01:00
shortcutme
8aa4e27938
Rev4411 2020-02-13 17:26:29 +01:00
shortcutme
bc76bf291a
Fix site blocklist with address hash based blocking and move checking to server-side 2020-02-13 17:26:15 +01:00
shortcutme
70cc982e2e
Log actual disabled function for multiuser plugin 2020-02-13 17:24:59 +01:00
shortcutme
61ac6a30d3
Fix loading blocked raw sites 2020-02-13 17:24:22 +01:00
shortcutme
d2627f36d5
Pass all arguments on site need 2020-02-13 17:23:37 +01:00
shortcutme
d36324e0d3
More detailed info on http host error 2020-02-13 17:23:00 +01:00
shortcutme
113b57415f
More detailed info on origin error 2020-02-13 17:22:37 +01:00
shortcutme
fefd2474b1
Don't reload sites on listing 2020-02-13 17:22:09 +01:00
tangdou1
28ce08de8e
Update zh.json (#2413)
* Update zh.json

* Update zh.json

* Update zh.json
2020-02-11 16:12:06 +01:00
shortcutme
037f0a3ff4
Rev4404 2020-02-07 16:43:23 +01:00
shortcutme
a3546d56b0
Merge js 2020-02-07 16:42:26 +01:00
shortcutme
95bf4ecb42
Read 5MB of logs for non-default console tabs 2020-02-07 16:40:27 +01:00
shortcutme
c91f2f0a09
Move all optional file download to separate button on sidebar 2020-02-07 16:40:04 +01:00
shortcutme
6d425f30fe
Stop checkconnections with connectionserver 2020-02-07 16:38:42 +01:00
shortcutme
8e79a7da63
Fix incomplete loading of dbschema.json 2020-02-07 16:37:37 +01:00
shortcutme
10c02c31c2
Rev4401 2020-01-28 16:59:03 +01:00
shortcutme
a0f5e1bde8
Fix translations 2020-01-28 16:58:46 +01:00
shortcutme
2e9cff928c
Skip commit if already commiting 2020-01-28 16:58:14 +01:00
shortcutme
46210b2f04
Use peer ip in peer exchange if no active connection 2020-01-28 16:57:20 +01:00
shortcutme
6dae187e22
More detailed logging on write error 2020-01-28 16:56:35 +01:00
ZeroNet
a7e783a26b
Merge pull request #2403 from eduaddad/patch-5
CONFIGURATION ITEM VALUE CHANGED - should work now
2020-01-28 16:50:17 +01:00
ZeroNet
60af3ceda9
Merge pull request #2404 from eduaddad/patch-6
added the Save as .Zip translation to Brazilian Portuguese
2020-01-28 16:49:08 +01:00
shortcutme
11415fe082
Log mock ws caller to get more detail on random test fail 2020-01-24 16:05:19 +01:00
ZeroNet
df93fa0ffe
Add PGP public key link 2020-01-24 14:58:37 +01:00
Eduaddad
849d514f28
added to translation Save as .Zip
added to translation Save as .Zip
2020-01-22 14:00:19 -03:00
Eduaddad
4d8ee4bafb
CONFIGURATION ITEM VALUE CHANGED - should work now
CONFIGURATION ITEM VALUE CHANGED - should work now
2020-01-22 13:54:19 -03:00
shortcutme
ac8aaaff75
Rev4399 2020-01-22 16:37:48 +01:00
shortcutme
238ede9419
Only correct time if we have at least 9 connected peers 2020-01-22 16:37:07 +01:00
shortcutme
835174270e
Less wait for closing cursors 2020-01-22 16:36:52 +01:00
shortcutme
62a2ec7254
Make sure to commit before vacuum 2020-01-22 16:36:33 +01:00
shortcutme
a9368bb3c8
Don't allow parallel sites.json loading 2020-01-22 16:35:40 +01:00
shortcutme
e75e199334
Fix multi-line log events display in web console 2020-01-22 16:33:54 +01:00
shortcutme
2b7aebd89d
Fix optional file loading when sites.json load takes more than 1 sec 2020-01-22 16:33:30 +01:00
shortcutme
3e08eabc86
Proper error when piecemap download fails 2020-01-22 16:31:35 +01:00
shortcutme
a16d55c863
Fix compatibility with Snap package 2020-01-22 16:31:09 +01:00
ZeroNet
e51ae580b9
Merge pull request #2396 from eduaddad/patch-4
Update pt-br.json
2020-01-22 16:27:43 +01:00
ZeroNet
914576b9db
Change to full PGP fingerprint 2020-01-19 13:30:22 +01:00
Eduaddad
3edb34ec56
Update pt-br.json
more translations
2020-01-15 00:53:19 -03:00
shortcutme
224093b3dd
Rev4397, Fix big file invalid path errors 2020-01-09 16:35:05 +01:00
Ivanq
77c3e43978 Detect content encoding based on query string (#2385) 2020-01-07 10:34:14 +01:00
shortcutme
03350d7454
Rev4394 2020-01-04 16:56:42 +01:00
shortcutme
2b5e57e840
Fix updateing deleted site in contentdb 2020-01-04 16:55:56 +01:00
shortcutme
39442977db
Thread safe access and request log updating in optionalmanager 2020-01-04 16:55:40 +01:00
shortcutme
0af90aad37
Maxmind db as download source no longer works 2020-01-04 16:55:08 +01:00
shortcutme
c5d51c9cab
Verify cert in separate function 2020-01-04 16:54:34 +01:00
shortcutme
0dbcec8092
Merge wrapper 2020-01-04 16:54:20 +01:00
shortcutme
76e4b75c2d
Fix removing loading screen without loaded content 2020-01-04 16:54:13 +01:00
shortcutme
c1ad7914f1
Always update loading screen site too large message with site info received 2020-01-04 16:53:49 +01:00
shortcutme
9085a4b0cc
Less frequent update of progress bar 2020-01-04 16:53:11 +01:00
shortcutme
820346c98d
More logging to wrapper 2020-01-04 16:52:51 +01:00
shortcutme
995d87c167
Don't add escaping iframe message for link without target=_top 2020-01-04 16:52:18 +01:00
shortcutme
fe739fa848
Log tasks with larger priority 2020-01-04 16:48:56 +01:00
shortcutme
b6d0bf8f6b
Use msvcrt 110 and 120 when 110 is not avaliable 2020-01-04 16:48:37 +01:00
ZeroNet
aec1ab4ed2
Merge pull request #2378 from rllola/zeroname_doc_update
Update Zeroname updater documentation
2020-01-02 17:54:12 +01:00
rllola
7d5f3354b6 Update README; 'valueencoding' configuration required for rpc call; 2020-01-02 11:32:47 +01:00
shortcutme
feb58e4b0e
Rev4382, Fix is_prev_builtin startup error 2019-12-31 18:15:17 +01:00
shortcutme
163825c03e
Rev4381 2019-12-31 12:56:10 +01:00
shortcutme
3fc80f834d
New tests for worker task manager 2019-12-31 12:55:09 +01:00
shortcutme
20b0db7ddb
Thread safe task remove in failTask 2019-12-31 12:54:45 +01:00
shortcutme
b2e7cbb927
Refactor task adding with less locking 2019-12-31 12:51:52 +01:00
shortcutme
5987274edf
Name task adding lock 2019-12-31 12:50:39 +01:00
shortcutme
ba218974c4
Task remove optimization 2019-12-31 12:50:21 +01:00
shortcutme
721d4a22f1
Remove unnecessary log from worker task manager 2019-12-31 12:49:59 +01:00
shortcutme
32b0153d34
Log site address with getfile error 2019-12-31 12:46:01 +01:00
shortcutme
71d32d7414
Less slow query loggin 2019-12-31 12:45:36 +01:00
shortcutme
796ee572ce
Fix verify invalid json 2019-12-31 12:44:47 +01:00
shortcutme
60146a083c
Fix ui_websocket test result with None 2019-12-21 03:30:27 +01:00
shortcutme
df87bd41b4
Log WsMock sent data itself to figure out random Crypt test fail 2019-12-21 03:22:37 +01:00
shortcutme
3d73599deb
Don't retry bad files also in big file tests 2019-12-21 03:21:38 +01:00
shortcutme
48124e12d9
Rev4372 2019-12-21 03:05:49 +01:00
shortcutme
17fb740c51
Don't try to download bad files again in tests to avoid random test fails 2019-12-21 03:05:19 +01:00
shortcutme
c6b07f1294
Wait until checkmodification spawned pools are finishing 2019-12-21 03:04:36 +01:00
shortcutme
3ccce46314
Wait until downloadContent pool finishes 2019-12-21 03:03:49 +01:00
shortcutme
7c1da5da52
Abilty to disable file bad file retry at end of download 2019-12-21 03:03:32 +01:00
shortcutme
c5de1447c8
onComplete will be triggered by WorkerManager 2019-12-21 03:02:53 +01:00
shortcutme
e16ace433c
Better logging in site download content 2019-12-21 03:02:36 +01:00
shortcutme
975f53b95b
New logging format for tests 2019-12-21 03:01:45 +01:00
shortcutme
8a994b5559
Ask before UiWebsocket server shutdown action 2019-12-21 02:59:50 +01:00
shortcutme
2acf24c336
Fix ipv4 checking regexp 2019-12-21 02:59:18 +01:00
shortcutme
2c3f1ba7ad
Check if all task are complete on fail task 2019-12-21 02:59:04 +01:00
shortcutme
c01245a4e0
Log task fail 2019-12-21 02:58:48 +01:00
shortcutme
f119f7d0d2
Use faster and thread safe way to re-sort tasks 2019-12-21 02:58:35 +01:00
shortcutme
62d4edadf6
Fail task if no peer left to try 2019-12-21 02:57:53 +01:00
shortcutme
8bf17d3a69
Add reason for Worker actions 2019-12-21 02:57:25 +01:00
shortcutme
0881e274a9
Log lock waits for task adding in WorkerManager 2019-12-21 02:56:42 +01:00
shortcutme
7ca09ba75b
Fix updating key 0 in WorkerTaskManager 2019-12-21 02:55:22 +01:00
ZeroNet
bde8b30d5c
Upload logs after failure, remove sometimes failing coverage check 2019-12-20 17:32:49 +01:00
shortcutme
87d1c736e2
Fix log printing typo 2019-12-19 02:45:00 +01:00
shortcutme
eba81cc7d2
Print logs from subdirs 2019-12-19 02:36:36 +01:00
shortcutme
69eb831c7e
Rev4361 2019-12-19 02:17:21 +01:00
shortcutme
99e6326974
More compact stack logging 2019-12-19 02:17:13 +01:00
shortcutme
50bbe47bf2
Better logging on file update 2019-12-19 02:17:00 +01:00
shortcutme
8bfef12ad4
Don't try to pack unknown peer addresses 2019-12-19 02:16:41 +01:00
ZeroNet
6085cfd1a7
Merge pull request #2364 from Zaefarani/patch-1
Add Farsi (Persian) Translation to ZeroNet
2019-12-18 19:29:26 +01:00
shortcutme
d660a268e8
Rev4360 2019-12-18 16:43:58 +01:00
shortcutme
c161140a90
Add locking for db cursor 2019-12-18 16:43:46 +01:00
shortcutme
7af8d1cd93
Save last lock time 2019-12-18 16:42:47 +01:00
shortcutme
845b50915d
Rev4358 2019-12-18 15:32:50 +01:00
shortcutme
dbbad3097c
Add segfault catcher, log plugins to separate directory 2019-12-18 15:32:42 +01:00
shortcutme
1abaa6fddc
Benchmark only exits when running as test from cli 2019-12-18 15:24:40 +01:00
shortcutme
7ecf09a496
Allow to change test log dir with environmental variable 2019-12-18 15:24:05 +01:00
shortcutme
c0639fef75
Lock task adding to avoid race condition when getFileInfo switches 2019-12-18 15:23:16 +01:00
ZeroNet
c08d266822
Change to more simple way to create new site 2019-12-18 14:55:37 +01:00
Hamid reza Zaefarani
6bc3c168c6
Merge pull request #1 from decentralizedauthority/patch-1
Rename fa,json to fa.json
2019-12-18 14:45:00 +03:30
Hamid reza Zaefarani
1fe7127082
Rename fa,json to fa.json 2019-12-18 14:35:54 +03:30
Decentralized Authority
cfaaaf57ec
Rename fa,json to fa.json 2019-12-18 10:59:48 +00:00
shortcutme
93d2ee65fe
Validate json files in src and plugins dir 2019-12-17 21:30:01 +01:00
shortcutme
9c08e41b9e
Rev4355 2019-12-17 21:03:01 +01:00
shortcutme
abee87bbec
Wait for threadpool kill with 1s timeout to fix memory leak test 2019-12-17 21:02:48 +01:00
shortcutme
d4b6f79746
Display logs after failure 2019-12-17 21:01:04 +01:00
shortcutme
a7c26f893f
Rev4354 2019-12-17 20:46:29 +01:00
Hamid reza Zaefarani
24b8cdf87a
Add Farsi (Persian) Translation to ZeroNet
Persian Translation of ZeroNet Site
2019-12-17 23:15:51 +03:30
shortcutme
fd43aa61ef
Current gevent in PyPI is not fully compatible with Python3.8 2019-12-17 20:37:32 +01:00
shortcutme
77869830c5
Fix shutdown hang 2019-12-17 20:36:52 +01:00
shortcutme
87fc8ced5e
Accept only my exception when testing Noparallel 2019-12-17 16:06:13 +01:00
ZeroNet
909967629b
Remove incompatible tests 2019-12-17 15:34:43 +01:00
ZeroNet
afe0d82f18
Run only selected benchmark tests 2019-12-17 15:25:46 +01:00
shortcutme
1ad97a6696
Run internal test on CI 2019-12-17 15:16:23 +01:00
shortcutme
e7e8e59c1e
Rev4353 2019-12-17 15:08:42 +01:00
shortcutme
f3665b172f
Avoid unnecessary pool call 2019-12-17 15:07:32 +01:00
shortcutme
23b3cd3986
Better rebuild log message 2019-12-17 15:07:00 +01:00
shortcutme
f7ee6744af
Db busy event waited in getDb 2019-12-17 15:06:36 +01:00
shortcutme
ac45217816
Add reason for db close and rebuilds 2019-12-17 15:05:59 +01:00
shortcutme
8c51e81a0b
Fix double opening of dbs 2019-12-17 15:05:21 +01:00
shortcutme
9d777951dd
Fix console tabs display gitch on edge 2019-12-17 15:03:04 +01:00
shortcutme
2778b17f8d
Ignore trayicon destroy errors 2019-12-17 15:02:39 +01:00
shortcutme
98c98fbac7
Thread safe method to create directory for db 2019-12-17 15:02:18 +01:00
shortcutme
9b1f6337c3
Wait for cursor finish on db close 2019-12-17 15:02:04 +01:00
shortcutme
2019093431
Fix testing on slower storage 2019-12-17 15:01:15 +01:00
shortcutme
eac25caf28
Log packing peer arrors as debug 2019-12-17 15:00:23 +01:00
shortcutme
b421893434
Return timer greenet 2019-12-17 15:00:09 +01:00
shortcutme
f1b19f5fc7
Fix DbQuery logging 2019-12-17 14:59:54 +01:00
shortcutme
61f1a741fc
Test main loop caller 2019-12-17 14:52:58 +01:00
shortcutme
f01d335835
Test noparallel multi thread compatibility 2019-12-17 14:52:13 +01:00
shortcutme
5c1b34387c
Noparallel multi thread compatibility 2019-12-17 14:51:57 +01:00
shortcutme
dfd55c3957
Fix memory leak when using sleep in threads 2019-12-17 14:50:38 +01:00
shortcutme
b21895fa78
Kill threadpool properly 2019-12-17 14:50:10 +01:00
shortcutme
495d695c5a
Fix threadpool apply and spawn when threadpool is full 2019-12-17 14:49:50 +01:00
shortcutme
3309489c24
Only call the function in separate thread when in the main loop 2019-12-17 14:48:11 +01:00
shortcutme
8a5a75e68f
Allow pass calls to the main loop 2019-12-17 14:47:27 +01:00
shortcutme
c1df78b97f
Name threadpools 2019-12-17 14:43:33 +01:00
shortcutme
4c31aae97b
Refactor worker, fix concurrent write errors 2019-12-17 14:42:33 +01:00
shortcutme
0839fdfc5e
Add reason for db close 2019-12-17 14:35:49 +01:00
shortcutme
d062f01127
Log temp site events under different name 2019-12-17 14:34:53 +01:00
shortcutme
e91fb90a45
Fix tests when running for long time 2019-12-17 14:34:29 +01:00
shortcutme
6539ca5eb0
Log spy actions to file when running tests 2019-12-17 14:33:06 +01:00
shortcutme
b138ebc519
Capture fd for pytest 2019-12-17 14:32:43 +01:00
shortcutme
79c1cd15ab
Use libev when running test 2019-12-17 14:32:17 +01:00
shortcutme
10c1986c54
Fix site list changing during listing 2019-12-17 14:31:55 +01:00
shortcutme
d7cabb47ca
Log task numbers on content.json start 2019-12-17 14:31:41 +01:00
shortcutme
8de1714f08
Fix onComplete call when donwload end 2019-12-17 14:31:12 +01:00
shortcutme
20ba9cd589
Log site download time 2019-12-17 14:30:29 +01:00
shortcutme
af1ac9bce8
Try to find already running task for file before start a new one 2019-12-17 14:30:14 +01:00
shortcutme
31a6e3ee9a
Don't allow clone to run in parallel 2019-12-17 14:29:48 +01:00
shortcutme
dca1dcdd2d
Use always active connection in DbCursor 2019-12-17 14:28:52 +01:00
shortcutme
a54f5f3e9f
Change trackers to more stable onces 2019-12-17 14:26:14 +01:00
shortcutme
51f49cd45a
Always use libev if possible 2019-12-17 14:25:04 +01:00
shortcutme
eb63eb7b1d
Log startup errors in log file 2019-12-17 14:24:44 +01:00
shortcutme
b4f7e51e96
Limit stack size on formatting 2019-12-17 14:24:08 +01:00
shortcutme
c2d2189039
Log content init failed as info 2019-12-17 14:23:47 +01:00
shortcutme
1eda3258de
Always raise error on verify error 2019-12-17 14:23:31 +01:00
shortcutme
0171cb0844
Avoid get db_inner_path for every file on signing 2019-12-17 14:23:18 +01:00
shortcutme
08a0a63631
Create ssl contexts only once 2019-12-17 14:22:29 +01:00
shortcutme
8ed7d0385d
If possible use loaded db to get db file inner_path 2019-12-17 14:21:47 +01:00
shortcutme
02d45e9c39
Use separate threadpool for batch site storage operations 2019-12-17 14:20:49 +01:00
shortcutme
2a402a0674
Use thread-safe mode to create directories 2019-12-17 14:18:54 +01:00
shortcutme
1be56b5a39
Return exit code 1 if any test failed 2019-12-17 14:10:42 +01:00
shortcutme
1e175bc41f
Remove used cursors from benchmark db test 2019-12-17 14:10:05 +01:00
ZeroNet
c16569a6ab
Merge pull request #2363 from GiganticBlackBear/py3
Update hu.json
2019-12-16 16:45:48 +01:00
Gigantic Black Bear
d19cc64611
Update hu.json 2019-12-16 15:19:42 +00:00
shortcutme
958882c1c5
Revert "Switch to sslcrypto for cryptography tasks (#2338)"
This reverts commit fbc7b6fc4f.
2019-12-15 18:30:42 +01:00
ZeroNet
2f7323043f
Merge pull request #2358 from imachug/bencode
Switch to bencode_open
2019-12-15 12:49:04 +01:00
Ivanq
fbc7b6fc4f Switch to sslcrypto for cryptography tasks (#2338)
* Use sslcrypto instead of pyelliptic and pybitcointools

* Fix CryptMessage

* Support Python 3.4

* Fix user creation

* Get rid of pyelliptic and pybitcointools

* Fix typo

* Delete test file

* Add sslcrypto to tree

* Update sslcrypto

* Add pyaes to src/lib

* Fix typo in tests

* Update sslcrypto version

* Use privatekey_bin instead of privatekey for bytes objects

* Fix sslcrypto

* Fix Benchmark plugin

* Don't calculate the same thing twice

* Only import sslcrypto once

* Handle fallback sslcrypto implementation during tests

* Fix sslcrypto fallback implementation selection
2019-12-15 12:46:06 +01:00
Ivanq
3178b69172 Switch to bencode_open 2019-12-12 17:46:16 +03:00
shortcutme
28fcf3c1ea
Rev4327 2019-12-11 20:04:50 +01:00
shortcutme
71939097b0
Make execution order test more predictable 2019-12-11 20:04:39 +01:00
shortcutme
2fd337bb55
Add wasm content type 2019-12-11 20:03:28 +01:00
shortcutme
5e26161e84
Rev4325 2019-12-04 17:16:08 +01:00
shortcutme
04ecb89e9a
Avoid sending too many publish request to an outdated client 2019-12-04 17:15:42 +01:00
shortcutme
23f851343f
Fix exception when params is an iterator 2019-12-04 17:15:08 +01:00
shortcutme
5ce1782d05
Change journal and foreign keys mode on db connect 2019-12-04 17:14:50 +01:00
shortcutme
daee14533c
Fix site number changes when data collected for stats 2019-12-04 17:14:04 +01:00
ZeroNet
31f505b309
Merge pull request #2339 from ethernetcat/py3
Update jp.json
2019-12-04 15:40:51 +01:00
shortcutme
c8214bf3ea
Fix threadpool test premature end on some platforms 2019-12-04 12:47:47 +01:00
shortcutme
1935a69c04
Add session based log disable at test 2019-12-04 12:46:44 +01:00
shortcutme
ea5f64bfea
Only log at start of the test cases 2019-12-04 12:46:13 +01:00
shortcutme
3dd04b27de
Correct invalid UiConfig pt-br json file 2019-12-04 11:03:45 +01:00
ZeroNet
9940b7bff3
Merge pull request #2334 from eduaddad/patch-3
Translation update for latest changes
2019-12-04 11:00:11 +01:00
ethernetcat
901ccf2d14 Update jp.json 2019-12-04 17:52:33 +09:00
Eduaddad
6a1a821ed4
Translation update for latest changes
Translation update for latest changes
2019-11-30 12:04:25 -03:00
shortcutme
aa9fe09337
Remove unnecessary line from config 2019-11-30 02:19:18 +01:00
shortcutme
bdb655243f
Rev4322 2019-11-30 02:16:29 +01:00
shortcutme
566c29363f
Slower progress bar animation 2019-11-30 02:15:17 +01:00
shortcutme
37b8c0241f
Db threads modify in config interface 2019-11-30 02:14:54 +01:00
shortcutme
1a17645e93
Remove unnecessary import 2019-11-30 02:14:08 +01:00
shortcutme
5fba850d74
Don't close connection if it's already closed 2019-11-30 02:13:58 +01:00
shortcutme
bd90e0ce52
Add Db id to logging identifier 2019-11-30 02:13:39 +01:00
shortcutme
c24cfa721b
Lock db while connecting 2019-11-30 02:13:17 +01:00
shortcutme
1670d96908
Execute db commit in separate thread 2019-11-30 02:12:33 +01:00
shortcutme
ec3c44c5b3
Use ThreadPool lock in Db 2019-11-30 02:11:34 +01:00
shortcutme
12bfad8fe6
Don't execute query while commiting 2019-11-30 02:11:11 +01:00
shortcutme
594edc6e9a
Commit after executemany 2019-11-30 02:10:40 +01:00
shortcutme
99304a09ca
Log long db queries 2019-11-30 02:10:11 +01:00
shortcutme
5c93aadce3
Gevent block time resolution log to ms 2019-11-30 02:09:14 +01:00
shortcutme
f0c10efca6
Progress meter for site delete 2019-11-30 02:08:29 +01:00
shortcutme
c10dd5239e
Log test case start/end and debug message 2019-11-30 02:08:11 +01:00
shortcutme
fa0d1a50b5
Better test of threadpool 2019-11-30 02:07:40 +01:00
shortcutme
66a1c4d242
Multi-process and gevent loop friendly lock 2019-11-30 02:07:30 +01:00
shortcutme
b7c6b84826
Don't log killed worker write as error 2019-11-30 02:05:20 +01:00
shortcutme
1c587bde25
Avoid write race on same file 2019-11-30 02:04:59 +01:00
shortcutme
e1dc29c374
Rev4308 2019-11-27 03:08:20 +01:00
shortcutme
59e0ffd8e0
Remove unnecessary imports from CryptMessage 2019-11-27 03:08:01 +01:00
shortcutme
f7c767c1c8
Make Chart plugin compatible with db changes 2019-11-27 03:07:44 +01:00
shortcutme
fca9db7972
Try fix Recursive use of cursors ProgrammingError by creating new cursor for every execute and move Lock to db 2019-11-27 03:07:08 +01:00
shortcutme
afd23849a6
Log site delete as info 2019-11-27 03:04:49 +01:00
shortcutme
1b2eee058c
Log test case start and end 2019-11-27 03:03:31 +01:00
shortcutme
777486a5be
Try new way to avoid pytest io errors 2019-11-27 03:03:22 +01:00
shortcutme
8b6f221e22
Formatting 2019-11-27 03:02:18 +01:00
shortcutme
97ecb7e3aa
Rev4303 2019-11-25 14:50:16 +01:00
shortcutme
5df5e25d68
Better logging of recent peers 2019-11-25 14:49:40 +01:00
shortcutme
66a950a481
New, much faster worker task sorting 2019-11-25 14:43:28 +01:00
shortcutme
29346cdef5
Faster, async local ip discovery 2019-11-25 14:40:52 +01:00
shortcutme
4f8e941e39
Fix err type logging 2019-11-25 14:39:24 +01:00
shortcutme
756f5a1608
Fix display peer found time on /Stats page 2019-11-25 14:38:53 +01:00
shortcutme
416e7d6fe0
Fix too fast benchmark results statistics 2019-11-25 14:38:27 +01:00
shortcutme
7b210429b5
Multi threaded eciesDecrypt 2019-11-25 14:37:55 +01:00
shortcutme
c52d47b15f
Don't show notifications when testing 2019-11-25 14:35:31 +01:00
shortcutme
9a43626aa6
When testing don't register shutdown functions 2019-11-25 14:35:16 +01:00
shortcutme
c14e722303
Fix bug that someomes blocked plugins accessing connectionserver sitelist 2019-11-25 14:34:46 +01:00
shortcutme
07633ba79d
Fix local peers dropping out from recent peers 2019-11-25 14:33:18 +01:00
shortcutme
6ff7fe55fc
Make sure we use local peers if possible 2019-11-25 14:32:06 +01:00
shortcutme
a14c36cd3e
Add peer's site to str represetntation 2019-11-25 14:31:12 +01:00
shortcutme
c21fe3d23a
Prefer connecting to non-onion peers 2019-11-25 14:30:51 +01:00
d9xr92
89e8fd3d3a potential fix for #2323 (#2324)
* potential fix for #2323

* Update DbCursor.py

* replaced RLock with Lock
2019-11-23 13:22:36 +01:00
shortcutme
966f393e20
Rev4290 2019-11-20 14:08:49 +01:00
shortcutme
d85c27e67b
Merge config js 2019-11-20 14:08:19 +01:00
shortcutme
a5f8a53196
Fix change detection for integers on config interface 2019-11-20 14:08:02 +01:00
shortcutme
9299e5b614
Kill greenlets with notify 2019-11-20 14:07:33 +01:00
shortcutme
6c31a3b77e
Change fs thread number on config interface 2019-11-20 14:07:04 +01:00
shortcutme
6262c80886
Fix benchmark on Firefox 2019-11-20 14:06:27 +01:00
shortcutme
5aa115c88a
Heavier task in thread pool test to make sure it will pass 2019-11-19 02:25:28 +01:00
shortcutme
511587dd8b
Allow images from data uris 2019-11-19 02:19:14 +01:00
shortcutme
5d34bb9062
Rev4287 2019-11-19 02:17:32 +01:00
shortcutme
4025d753e3
Don't print errors happened in thread 2019-11-19 02:16:44 +01:00
shortcutme
58214c0ac3
Move file writes and reads to separate thread 2019-11-19 02:16:20 +01:00
shortcutme
5d113757df
Stop greenlets when deleting a site in test 2019-11-19 02:15:47 +01:00
shortcutme
b41a03674f
New configuration options for fs write and read thread count 2019-11-19 02:15:00 +01:00
shortcutme
8c1f64243f
Test CLI action parser 2019-11-19 02:14:29 +01:00
shortcutme
cdd9dd4f6f
Fix duplicate content_db connecting 2019-11-19 02:12:24 +01:00
shortcutme
57f2a43864
Formatting 2019-11-19 02:11:19 +01:00
shortcutme
74d7fb7835
Less verbose logging in site storage 2019-11-19 02:10:42 +01:00
shortcutme
dd61429e2f
Handle announcer thread killing properly 2019-11-19 02:09:55 +01:00
shortcutme
8f27f50b34
Log SQL statements in progress as warning 2019-11-19 02:09:36 +01:00
shortcutme
96e7fbdca1
Don't try to commit if no db connection 2019-11-19 02:08:30 +01:00
shortcutme
39352eb97e
Fix test function listing name 2019-11-19 02:08:03 +01:00
shortcutme
1c607645c7
Track and stop site connected greenlets on delete 2019-11-19 02:07:51 +01:00
shortcutme
2ad3493fb0
Test and benchmark of crypto function in CryptMessage plugin 2019-11-19 02:05:02 +01:00
shortcutme
331dc99086
Fix benchmark plugin test listing if not loaded before other plugins 2019-11-19 02:03:27 +01:00
shortcutme
4424c8272d
New refactored Benchmark plugin to test compatibility and meassure system performance 2019-11-19 01:48:31 +01:00
shortcutme
16162955af
New cli test action 2019-11-19 01:47:06 +01:00
shortcutme
23006e495f
FilePack plugin pass possible other parameters to site storage read function 2019-11-19 01:45:50 +01:00
shortcutme
4351af35f4
Don't load geoip db in parallel 2019-11-19 01:44:26 +01:00
shortcutme
e8af5db2e8
Keep track gevent block number, remove Benchmark from stats plugin 2019-11-19 01:43:39 +01:00
shortcutme
9d048371b7
Better way to patch gevent error handling 2019-11-19 01:42:00 +01:00
shortcutme
a187726ba8
Formatting 2019-11-19 01:40:39 +01:00
shortcutme
0ff1bcfd19
Remove not used variable and module import 2019-11-19 01:40:00 +01:00
shortcutme
08fee35bcf
Fix pytest output capturing error 2019-11-19 01:39:16 +01:00
shortcutme
08574bf676
Handle unkown variables when rendering template 2019-11-19 01:38:22 +01:00
shortcutme
5c27a0efcc
Rev4260, Fix UiConfig pt-br language json 2019-11-15 19:43:56 +01:00
ZeroNet
7576f96604
Merge pull request #2307 from nfenclova/py3
Replace usage of deprecated API 'cgi.parse_qsl'
2019-11-14 17:59:16 +01:00
Natalia Fenclová
456e330854 Replace usage of deprecated API 'cgi.parse_qsl'
Python 3.8.0 removed this deprecated API. We already use the replacement
`urllib.parse.parse_qsl` in `UIRequest.py`
2019-11-14 17:22:39 +01:00
ZeroNet
8d95eb937f
Longer timeout to close connections in ssl connection test 2019-11-11 17:14:36 +01:00
shortcutme
2f50fef787
Rev4259 2019-11-11 16:18:33 +01:00
shortcutme
ac69007292
Fix file rendering if content.json download failed 2019-11-11 16:18:25 +01:00
shortcutme
e8b0a3d1c4
Fix loading screen scrolling on smaller screens 2019-11-11 16:18:01 +01:00
Eduaddad
dfbbbd9381 translation update (#2275)
* translation update

translation update

* Update pt-br.json

* missing comma correction
2019-11-11 15:37:50 +01:00
ZeroNet
4ab339b375
Merge pull request #2278 from eduaddad/patch-2
text was duplicated and in Chinese
2019-11-11 15:37:24 +01:00
shortcutme
fce24cedbd
Rev4257 2019-11-07 02:48:17 +01:00
shortcutme
f9b62564ca
Fix logging in non-debug mode 2019-11-07 02:47:45 +01:00
shortcutme
d569d9488a
Deny invalid files on Windows 2019-11-07 02:47:19 +01:00
shortcutme
f172751df3
Test utf8 filename download 2019-11-07 02:44:54 +01:00
shortcutme
13233d47bd
Fix long running test 2019-11-07 02:44:33 +01:00
Josh
74d7d92a4d Allow all valid filenames to be added to content.json (#2141)
* Allow all valid filenames to be added to content.json

* Replace hex version of regex with non-hex version

* Add basic test for path validation with ASCII and UTF-8 filenames

* Amend path validation test to meet standards
2019-11-07 02:18:27 +01:00
ZeroNet
d3a0f5c268
Add macOS download option, change localhost to 127.0.0.1 2019-11-06 23:26:52 +01:00
ZeroNet
63f213a5d5
Merge pull request #2286 from cclauss/patch-1
Upgrade to the production version of Python 3.8
2019-11-04 19:52:37 +01:00
Christian Clauss
6d4c4d9f27
Upgrade to the production version of Python 3.8 2019-11-04 19:44:15 +01:00
Eduaddad
b2be4672ec
text was duplicated and in Chinese 2019-11-04 09:18:32 -03:00
Lola Dam
1bfe328a1b No restart after update (#2242) 2019-11-01 19:36:43 +01:00
shortcutme
1f453b6c13
Rev4253, Hotfix siteCreate CLI 2019-10-30 03:09:28 +01:00
shortcutme
ee8e3c3c9c
Use master_seed for siteCreate CLI by default 2019-10-30 03:07:06 +01:00
shortcutme
37f315dfc2
Rev4252 2019-10-30 02:31:04 +01:00
shortcutme
1e1e560795
Use master seed to create new site from cli 2019-10-30 02:30:01 +01:00
shortcutme
8d88cfcd68
Fix notification width calculation 2019-10-30 02:28:37 +01:00
shortcutme
74badf9c9c
Rev4250 2019-10-28 16:44:40 +01:00
shortcutme
86087550f1
Log ConnectionResetError as warning 2019-10-28 16:44:14 +01:00
shortcutme
8dfc200f24
Update cachable type list 2019-10-28 16:43:37 +01:00
shortcutme
cb4a4bd707
Add utf-8 charset header to more types 2019-10-28 16:43:19 +01:00
shortcutme
24ba2a150b
Remove limitations for img, font, media, style src in raw mode 2019-10-28 16:42:28 +01:00
shortcutme
e1d92bf0ec
Changing allow-origin to js files looks no longer necessary 2019-10-28 16:41:55 +01:00
shortcutme
270f3e9ffd
Use host to check same origin if referrer looks trimmed to host 2019-10-28 16:41:08 +01:00
shortcutme
e1f73697ff
Extend built-in content types list 2019-10-28 16:11:45 +01:00
shortcutme
e82155aac4
Rev4245, Fix target=_blank links 2019-10-26 20:36:53 +02:00
shortcutme
d7669413af
Log ConnectionAbortedError as warning 2019-10-26 20:17:09 +02:00
shortcutme
28d4fc5d12
Update location of bundled OpenSSL on macOS 2019-10-24 12:22:54 +02:00
Filip Š
dac4fcd52b Allow NOSANDBOX in local mode (#2238) 2019-10-24 12:01:31 +02:00
6543
8dff33b38a git ignore log folder (#2239) 2019-10-24 10:53:41 +02:00
shortcutme
6bae1f8a4b
Rev4243 2019-10-24 03:09:38 +02:00
shortcutme
10ceeb7f02
Remove no longer necessary files after cert generation 2019-10-24 03:09:28 +02:00
shortcutme
448bb3ce98
Fix OpenSSL cert generation using LibreSSL 2019-10-24 03:09:16 +02:00
shortcutme
0531d47721
Fix shutdown errors on macOS 2019-10-24 03:08:45 +02:00
shortcutme
b21719e2f2
Fix OpenSSL lib loading on macOS 2019-10-24 03:08:27 +02:00
Ornataweaver
2960db2352 simple English improvement (#2232) 2019-10-22 17:33:10 +02:00
ZeroNet
cb3629343b
Update requirements.txt 2019-10-22 17:22:30 +02:00
shortcutme
fa7013fdf7
Rev4241 2019-10-16 15:44:56 +02:00
shortcutme
db868dba81
Merge sidebar css 2019-10-16 15:44:38 +02:00
shortcutme
608a411d97
Db table rebuild as debug message 2019-10-16 15:43:28 +02:00
shortcutme
20c63c73b3
Support silent loading of verify lib 2019-10-16 15:43:07 +02:00
shortcutme
5ca3401eb9
Remove UiRequestPlugin from Zeroname plugin 2019-10-16 15:42:49 +02:00
ZeroNet
435a3c285e
Merge pull request #2218 from caryoscelus/py3
minor code improvement: super/init
2019-10-07 11:23:32 +02:00
caryoscelus
6405cae706 minor code improvement: super/init
`__init__` should only ever return None
2019-10-06 22:30:18 +00:00
shortcutme
6451e7f9f1
Console display fixes 2019-10-06 03:32:04 +02:00
shortcutme
127fa5fa82
Rev4238 2019-10-06 03:27:47 +02:00
shortcutme
63fd0a9fa1
Put the infopanel lower to avoid console interruption 2019-10-06 03:21:35 +02:00
shortcutme
344ad44854
Fix reload if there is hash in the url 2019-10-06 03:20:58 +02:00
shortcutme
43a5742258
Resolve domain in parsePath function 2019-10-06 03:20:16 +02:00
shortcutme
924a61309a
Cached isDomain / resolveDomain functions 2019-10-06 03:18:14 +02:00
shortcutme
9dd5c88da4
Monospace font when displaying errors 2019-10-06 03:15:57 +02:00
shortcutme
0598bcf332
Fix utf8 post data parsing 2019-10-06 03:15:20 +02:00
shortcutme
ead1b3e5f5
Log 403 as warning 2019-10-06 03:14:45 +02:00
shortcutme
dd493c87fa
Display WSGI errors to the browser 2019-10-06 03:13:32 +02:00
shortcutme
29640e614c
Admin API call to list server errors 2019-10-06 03:12:47 +02:00
shortcutme
73e0aa17c4
Don't encode byte responses 2019-10-06 03:10:43 +02:00
shortcutme
917a2e59ce
Fix compacting large json files 2019-10-06 03:10:20 +02:00
shortcutme
119e1a9bf0
Simple cache decorator 2019-10-06 03:09:48 +02:00
shortcutme
6eb79ba75e
Don't annunce site if not serving 2019-10-06 03:08:54 +02:00
shortcutme
1f9eafa619
Merge sidebar js, css 2019-10-06 03:08:32 +02:00
shortcutme
d5da404ed4
Log zeroname db load error 2019-10-06 03:08:09 +02:00
shortcutme
1b41aa70cc
Don't mess with console visibility on Windows 2019-10-06 03:07:52 +02:00
shortcutme
284b1a4f8a
Console filters to Warning, Error 2019-10-06 03:07:34 +02:00
shortcutme
fe432ad843
Open console with #ZeroNet:Console hash in url 2019-10-06 03:07:14 +02:00
shortcutme
15fca6bd12
User selection from a list in multiuser local mode 2019-10-06 03:05:39 +02:00
ZeroNet
57c0daa294
Merge pull request #2213 from filips123/sponsor-button
Display a sponsor button in repository (py3)
2019-10-02 18:20:19 +02:00
Filip Š
fee95654fa Create FUNDING.yml
(cherry picked from commit f08bea7f90)
2019-09-30 22:04:40 +02:00
shortcutme
bb436f9931
Rev4223 2019-09-28 17:17:47 +02:00
shortcutme
3682f0aed4
Wait for db close on tests 2019-09-28 17:03:43 +02:00
shortcutme
43c366d2fb
Restrict blocked site addition when using mergerSiteAdd 2019-09-28 17:02:27 +02:00
shortcutme
b21b885aa9
Move site add to separate function 2019-09-28 17:01:37 +02:00
shortcutme
6bb929a896
Merge branch 'py3' of https://github.com/HelloZeroNet/ZeroNet into py3 2019-09-19 16:38:25 +02:00
shortcutme
f5829f6012
Rev4221 2019-09-19 16:38:20 +02:00
shortcutme
d06b4abecf
Add multiuser admin status to server info 2019-09-19 16:38:05 +02:00
shortcutme
d7db631b95
Shut down UiServer if FileServer startup failed 2019-09-19 16:33:45 +02:00
shortcutme
93e6ec4933
Fix display site add prompt 2019-09-19 16:32:30 +02:00
Christian Seibold
2fbf2c7771 English Grammar Fix: Change "Forgot" to "Forget" in Sidebar (#2202)
* Change forgot to forget

English grammar fix

* Change forgot to forget

Fix English grammar
2019-09-18 19:49:53 +02:00
shortcutme
b474677db1
Remove pyelliptic from requirements because an OpenSSL 1.1 compatible version is bundled in the lib dir 2019-09-15 22:14:20 +02:00
shortcutme
dbcd8602c5
Rev4214 2019-09-15 22:12:09 +02:00
shortcutme
1793407748
Png and svg version of the logo 2019-09-15 22:12:03 +02:00
shortcutme
6f0d4a50d1
Add apple touch icon support for Safari 2019-09-15 22:11:51 +02:00
shortcutme
10817aefae
Fix pyelliptic OpenSSL 1.1 compatibility if it's also present in site-packages 2019-09-15 22:08:48 +02:00
shortcutme
4293a44c93
Don't try to find OpenSSL 1.0.x 2019-09-15 22:08:20 +02:00
shortcutme
96759e9303
Rev4210, Fix format exception if no args 2019-09-12 00:24:16 +02:00
shortcutme
448483371c
Formatting 2019-09-12 00:23:36 +02:00
Lola Dam
0738964e64 Save content.json of site even if limit size is reached (#2114)
* fix #2107; Still save the content.json received even if site size limit is reached but dont download files; Allow better distribution of latest version of content.json

* Added test

* Fix test for huge content file (now it fails)

* Dont download huge content.json file and update test

* Remove comments
2019-09-10 18:18:21 +02:00
ZeroNet
deec2e62ce
Add Linux bundle install method 2019-09-10 18:16:02 +02:00
ZeroNet
c52da69367
Check py3 branch build status 2019-09-10 18:08:45 +02:00
shortcutme
2de35266c4
Rev4208, Add details on Tor connection error 2019-09-10 15:43:42 +02:00
ZeroNet
e6b8097b43
Merge pull request #2187 from krzotr/patch-5
Set custom priority in FileNeed and FileGet command
2019-09-08 17:24:19 +02:00
krzotr
55c7585334
Set custom priority in FileNeed and FileGet command
When you use `FileNeed` or `FileGet` command the default priority is set to `6`.
You cannot change that value because is hardcoded.

Now you can set priority of downloading files manually:

```
this.cmd("fileNeed", {
    "inner_path": inner_path + "|all",
    "priority": 10
})
```
2019-09-08 11:51:46 +02:00
shortcutme
62d278a367
Version 0.7.1 2019-09-06 04:03:01 +02:00
shortcutme
38e20b7c31
Rev4206 2019-09-04 20:16:57 +02:00
shortcutme
d3fce8ca36
Support Linux bundle OpenSSL 2019-09-04 20:16:32 +02:00
shortcutme
2a7d7acce0
Support updating linux bundle 2019-09-04 20:15:49 +02:00
shortcutme
eab63c6af8
Keep file permissions on update rename workaround 2019-09-04 20:15:37 +02:00
shortcutme
4f0613689a
Formatting 2019-09-04 20:13:32 +02:00
shortcutme
743463dce9
Execute shutdown function before running update to avoid segfault on linux 2019-09-04 20:13:16 +02:00
shortcutme
0b04176f18
Rev4203, Change console encoding to utf8 on Windows 2019-09-03 12:00:25 +02:00
ZeroNet
166a65e1b1
Merge pull request #2183 from imachug/patch-2
Fix gevent.Timeout being not caught
2019-09-02 21:59:44 +02:00
Ivanq
5da4537d7c
Fix gevent.Timeout being not caught 2019-09-02 19:34:29 +00:00
ZeroNet
b9e71c9f6f
Merge pull request #2181 from imachug/patch-1
Fix UnicodeDecodeError when OpenSSL is not found
2019-09-02 21:10:15 +02:00
Ivanq
500c96abe2
Fix UnicodeDecodeError when OpenSSL is not found
Fixes #2180
2019-09-02 14:35:28 +00:00
shortcutme
149c4f5c7b
Rev4200 2019-09-02 14:17:46 +02:00
shortcutme
76bc9fcddf
Open sidebar with location hash 2019-09-02 14:17:35 +02:00
shortcutme
f999f167b1
Offer access with ip address on invalid host error 2019-09-02 02:10:52 +02:00
shortcutme
9ac96cdd50
Don't leak allowed origins in error message 2019-09-02 02:09:53 +02:00
shortcutme
3c4bc6ae35
Always update merger sites db on content.json update 2019-09-02 02:08:07 +02:00
ZeroNet
879b504b0f
Merge pull request #2179 from krzotr/patch-4
KeyError: 'piece_size' in `fileNeed` command in BigfilePlugin when try to download non-optional files with `|all`
2019-08-30 21:05:46 +02:00
Krzysztof Otręba
baa5df1d01 fixed KeyError: 'piece_size' when try to download non-optional file using '|all' 2019-08-30 18:59:19 +02:00
shortcutme
912c958ac0
Rev4197 2019-08-26 03:21:04 +02:00
shortcutme
d166a16a24
Use function flagging in plugins 2019-08-26 03:20:07 +02:00
shortcutme
1bd1ddf410
Test function flagging 2019-08-26 03:15:29 +02:00
shortcutme
7890771faa
Test permissions of websocket 2019-08-26 03:11:24 +02:00
shortcutme
376fd0d439
Use flags instead of permission list 2019-08-26 03:09:48 +02:00
shortcutme
c414e6caa2
Support action async call flag 2019-08-26 03:08:57 +02:00
shortcutme
ed7a3b2356
Get action permissions from flag db 2019-08-26 03:02:30 +02:00
shortcutme
adffbd1973
New function flagging decorator class to keep track permissions 2019-08-26 02:55:01 +02:00
shortcutme
6750682e4f
Rev4191 2019-08-23 03:42:31 +02:00
shortcutme
d1fb4067e7
Hide trackers proxy settings if tor always set on /Config page 2019-08-23 03:40:44 +02:00
shortcutme
ab9fe173a8
Don't use trackers proxy in tor always mode 2019-08-23 03:40:29 +02:00
shortcutme
8a7ae368d8
No opened services if we are in tor always mode 2019-08-23 03:40:20 +02:00
shortcutme
248fc5f015
Use re.sub to replace template variables 2019-08-23 03:39:50 +02:00
shortcutme
e16611f15a
Allow websocket connection originates from earlier accepted hostnames 2019-08-23 03:39:16 +02:00
Ivanq
24b3651d2e Allow blob: protocol (#2166)
* Allow blob: protocol

* Fix quotes
2019-08-20 12:42:01 +02:00
ZeroNet
0e236e53fd
Merge pull request #2167 from imachug/merge-media
Add --merge_media config option
2019-08-20 12:10:39 +02:00
Ivanq
61ba9848e5 Add --merge_media config option 2019-08-20 08:16:35 +00:00
Ivanq
01ff89315b Add GitLab CI/CD support (#2163)
* Use GitLab CI/CD

* Force colored tests

* Get rid of an error

* Mark tests as slow

* Disable codecov & coveralls

* Python 3.5-3.8

* Add Python 3.4

* Support both OpenSSL 1.1.0 and 1.1.1+

* Test both OpenSSL 1.1.0 and 1.1.1+

* Fix OpenSSL 1.1.1

* Fix Python 3.4 build
2019-08-19 17:30:31 +02:00
shortcutme
155d8d4dfd
Rev4188, Allow only white listed values for open_browser 2019-08-19 13:42:49 +02:00
ZeroNet
c7822ed6e6
Merge pull request #2160 from imachug/patch-1
Allow files with `..` as a name substring
2019-08-19 13:35:29 +02:00
Ivanq
1ed40b3b82
Allow files with .. as a name substring 2019-08-19 07:09:32 +00:00
shortcutme
18dc359cfc
Rev4187 2019-08-18 03:03:22 +02:00
shortcutme
b871849df4
Add origin validation to websocket connections 2019-08-18 03:03:02 +02:00
shortcutme
7d1ca3862d
Make missing IPv6 a warning not an error 2019-08-18 03:02:30 +02:00
shortcutme
2a887870ff
Rev4185 2019-08-17 20:35:00 +02:00
shortcutme
1d5bde01cc
Deny plugin add request in multiuser mode 2019-08-17 20:34:21 +02:00
shortcutme
8537939d26
Disable UDP in proxy mode 2019-08-17 20:34:04 +02:00
shortcutme
fcb3ac3917
Only change default proxy to tor in tor always mode 2019-08-17 20:33:43 +02:00
shortcutme
d63a4b3912
Rev4181 2019-08-15 03:19:23 +02:00
shortcutme
6a245a202c
Fix server connections encryption 2019-08-15 03:19:05 +02:00
shortcutme
429043f60c
CLI peerPing command display connection encryption info only once 2019-08-15 03:09:53 +02:00
shortcutme
8f491fe6e1
Use SSLContext for connection encryption, add fake SNI, ALPN 2019-08-15 03:08:40 +02:00
shortcutme
92358bafc0
Wider max notification width to allow blacklist button in same line 2019-08-15 03:06:13 +02:00
shortcutme
d93e89899b
Fix tracker proxy PySocks import 2019-08-15 03:05:46 +02:00
shortcutme
2bdd073608
Move resolveDomain to SiteManager for easier resolver plugins 2019-08-15 03:05:29 +02:00
shortcutme
7801937f74
Rev4176, Fix update of plugins 2019-08-13 21:07:26 +02:00
shortcutme
1d7e0c47dd
Merge branch 'py3' of https://github.com/HelloZeroNet/ZeroNet into py3 2019-08-12 17:58:28 +02:00
shortcutme
7b9b48e62d
Rev4175, Console and file logging disable support 2019-08-12 17:58:23 +02:00
shortcutme
d610f94e7d
Display TLS 1.3 support on /Stats page 2019-08-12 17:56:06 +02:00
ZeroNet
7742f2f5fb
Merge pull request #2137 from imachug/patch-1
Fix preferring CLI argument over zeronet.conf
2019-08-11 14:51:23 +02:00
Ivanq
3f7e22497d
Fix preferring CLI argument over zeronet.conf
Fix using open_browser from CLI arguments in case there are several `--open_browser` arguments, which often happens after restarts.
2019-08-11 12:18:55 +03:00
shortcutme
e745760520
Rev4172 2019-08-09 13:18:57 +02:00
shortcutme
bd5c2b1daa
Also try to load OpenSSL dll from Python/DDLs directory 2019-08-09 13:18:40 +02:00
shortcutme
0bbeede975
Don't try to display bigfile limit settings if no bigfile plugin enabled 2019-08-09 13:17:48 +02:00
shortcutme
30865c9d1c
Rev4169 2019-08-08 23:37:49 +02:00
shortcutme
1cfe874893
Use find_library first to locate libeay32 2019-08-08 23:37:43 +02:00
shortcutme
5da46ca29c
Cleanup whitespace in pyelliptic 2019-08-08 23:37:21 +02:00
shortcutme
cc21cbd1bd
Use relative import in pyelliptic 2019-08-08 23:36:58 +02:00
shortcutme
79ba4a9d23
Rev4167 2019-08-08 14:39:02 +02:00
shortcutme
44ef0cbe59
Always load plugins abc sorted 2019-08-08 14:37:42 +02:00
shortcutme
88f2b39576
Don't try to connect to onion addresses if not supported by the client 2019-08-08 14:37:19 +02:00
shortcutme
bf10cdef63
Add some delay on pex error before try the next peer 2019-08-08 14:36:33 +02:00
shortcutme
3696db89ab
Don't increment tracker error number if no internet connection 2019-08-08 14:35:58 +02:00
shortcutme
eeaa5d21d8
Start unrealible trackers on force reannounce 2019-08-08 14:35:35 +02:00
shortcutme
f4bec3bb4d
Avoid starting new workers on possibly unvalaible file 2019-08-08 14:35:04 +02:00
shortcutme
dc6f3cf0b2
Merge branch 'py3' of https://github.com/HelloZeroNet/ZeroNet into py3 2019-08-07 14:13:00 +02:00
shortcutme
b5a1310add
Rev4165 2019-08-07 14:12:53 +02:00
shortcutme
b22343f65c
Support multiple trackers_file argument 2019-08-07 14:12:45 +02:00
shortcutme
b9b317e213
Remove accidently left print on plugin load 2019-08-07 14:11:58 +02:00
shortcutme
6cd18bbf04
Display more clean error on users.json/sites.json load error 2019-08-07 14:11:30 +02:00
ZeroNet
8c6400e4d6
Correct venv install 2019-08-06 14:56:45 +02:00
shortcutme
b6e1559a80
Rev4163 2019-08-03 01:35:37 +02:00
shortcutme
605ae75dda
Re-compile UiConfig js, css, backdrop to bottom popup 2019-08-03 01:35:00 +02:00
shortcutme
39f318fbd5
Add plugin version information to server_info 2019-08-03 01:34:21 +02:00
shortcutme
21def81439
Fix js, css merging with absolute merged_path 2019-08-03 01:34:00 +02:00
shortcutme
7e9ab8321a
Add plugin description data 2019-08-03 01:32:55 +02:00
shortcutme
4094d3a9bf
Plugin to install, update and delete third-party plugins using the web interface 2019-08-03 01:31:11 +02:00
shortcutme
0877fec638
Restrict plugin commands in multi-user mode 2019-08-03 01:29:27 +02:00
shortcutme
f40c3e6b81
Add notification messages max-width 2019-08-02 20:11:00 +02:00
shortcutme
bb705ae863
Fix source code reloader crash on directory modifications/file deletions 2019-08-02 16:19:35 +02:00
shortcutme
c4a3a53be0
Also reload source code on file changes in installed plugins 2019-08-02 16:19:05 +02:00
shortcutme
713ff17e91
Allow load installed third-party plugins and enable/disable plugins in config file data/plugins.json 2019-08-02 16:18:37 +02:00
shortcutme
0c659a477d
Remove hard-coded translate files directory 2019-08-02 16:16:19 +02:00
shortcutme
26678a65f8
Limit notifications max with 2019-08-02 16:15:45 +02:00
shortcutme
c5116fb318
Modify testAction command to use handleRequest instead of directly calling the function 2019-08-02 16:14:44 +02:00
shortcutme
fa970fa102
Test CryptMessage plugin using testAction function 2019-08-02 16:14:17 +02:00
shortcutme
fbafd23177
Add OpenSSL 1.1 support to CryptMessage plugin by using radfish's pyelliptic version 2019-08-02 16:13:54 +02:00
shortcutme
be742c78e7
Formatting for better readability 2019-08-02 16:06:22 +02:00
shortcutme
3e97c154a0
Remove hard-coded directory path from plugins 2019-08-02 16:05:19 +02:00
shortcutme
1eb97ea381
Delayed save of sites.json 2019-08-02 14:06:25 +02:00
shortcutme
f6e06456b0
Use advaced json dumper to save sites.json and users.json 2019-08-02 14:06:05 +02:00
shortcutme
5e90cd9714
Move advanced json formatter to helper.py 2019-08-02 14:05:14 +02:00
shortcutme
06406fa46c
Avoid bare exceptions 2019-08-02 14:04:18 +02:00
ZeroNet
08b7034d6f
Merge pull request #2116 from filips123/patch-2
Add response to some commands
2019-08-02 10:52:37 +02:00
Filip Š
5b91aef4ec
Add response to some commands 2019-08-01 19:16:10 +02:00
shortcutme
d8a121cd06
Rev4129 2019-07-18 03:34:09 +02:00
shortcutme
902a1b1c88
Fix OpenSSL dll loading on Windows 2019-07-18 03:33:56 +02:00
shortcutme
c9a2b86c16
Log possible OpenSSL cert generation error message at the same line 2019-07-18 03:33:35 +02:00
shortcutme
27fcb70774
Log loaded verify lib path and load time 2019-07-18 03:32:45 +02:00
shortcutme
e488841031
Display loaded verify lib path in benchmark 2019-07-18 03:32:22 +02:00
shortcutme
6cffa1c0ca
Change maxstdio using ctypes as win32file module is not included with Python3 by default 2019-07-18 03:31:57 +02:00
shortcutme
d3e8fcea47
Rev4126 2019-07-17 16:31:38 +02:00
shortcutme
9526424a47
Display error message dialog on Windows for startup errors 2019-07-17 16:31:32 +02:00
shortcutme
149278abd0
Skip reload on attribute changes 2019-07-17 16:30:56 +02:00
shortcutme
314c8b22db
Fix parsing config file with % in value 2019-07-17 16:30:32 +02:00
shortcutme
c502688ce3
Internals renamed to Console 2019-07-17 16:30:17 +02:00
shortcutme
866346b059
Fix and test bootstrapper hash cache reload from db 2019-07-17 16:29:54 +02:00
shortcutme
de8286829a
Remove outdated cn changelog 2019-07-16 13:41:44 +02:00
ZeroNet
18c407bfc2
Merge pull request #2096 from geekless/missing-encodeResponse
Add missing @helper.encodeResponse
2019-07-15 10:59:03 +02:00
Vadim Ushakov
076684176b Add missing @helper.encodeResponse in StatsPlugin.py and BootstrapperPlugin.py 2019-07-15 14:50:24 +07:00
Vadim Ushakov
a2cb1615b3 Move the BitTorrent related code from SiteAnnouncer.py (#2078)
* Move the BitTorrent related code from SiteAnnouncer.py to a separate plugin

* AnnounceBitTorrentPlugin.py: add missing `from Debug import Debug`
2019-07-10 16:12:25 +02:00
ZeroNet
6b5fa140b9
Try use pypi gevent for py3.8 tests 2019-07-10 12:48:08 +02:00
shortcutme
356d0521e6
Rev4122 2019-07-10 03:15:56 +02:00
shortcutme
5a08ab93d3
Ignore file attribute changes when reloading source code 2019-07-10 03:15:46 +02:00
shortcutme
8185f4dfda
Test getFile inner_path security 2019-07-10 03:14:30 +02:00
shortcutme
f4f0e2afa8
Allow like parameters in database queries 2019-07-10 03:14:09 +02:00
shortcutme
67d6b1e724
Fix double logging when running tests 2019-07-10 03:12:56 +02:00
shortcutme
e34a9d452a
Allow filter optional files by inner path 2019-07-10 03:11:20 +02:00
ZeroNet
2819a36469
Merge pull request #2084 from tangdou1/patch-5
Update zh.json
2019-07-09 03:01:13 +02:00
tangdou1
8815b4e0c3
Update zh.json 2019-07-08 10:05:34 +08:00
ZeroNet
960635b993
Fix win download link 2019-07-08 02:51:16 +02:00
shortcutme
f9dcb29e92
Remove development test version warning, add windows instuctions, remove outdated instuctions 2019-07-08 02:41:30 +02:00
ZeroNet
5a746769d0
Merge pull request #2073 from filips123/fix-infinite-reloading
Fix infinite reloading when system theme changes
2019-07-06 23:25:35 +02:00
Filip Š
87b4500467 Fix infinite reloading when system theme changes 2019-07-05 18:43:54 +02:00
ZeroNet
951e47469a
Merge pull request #2060 from imachug/default-subdir-clone
Fix siteCloning subdirectory with -default files
2019-07-05 17:13:29 +02:00
shortcutme
c1db963c76
Rev4112, Fix loading screen glitch, Change unstable trackers 2019-07-04 14:39:41 +02:00
ZeroNet
a252ec36f0
Merge pull request #2069 from imachug/patch-1
Guess content type correctly
2019-07-04 11:34:01 +02:00
Ivanq
33b478199a
Guess content type correctly
Fix e.g. vue.min.js being reported as text/plain instead of text/javascript.
2019-07-04 12:09:07 +03:00
shortcutme
21f285e099
Rev4111 2019-07-03 18:37:35 +02:00
shortcutme
fec312ed09
Better pytest atexit logging error workaround 2019-07-03 18:37:13 +02:00
shortcutme
eb2627721e
Fix pytest 5.x compatibility 2019-07-03 18:36:41 +02:00
shortcutme
ff32f822ba
Raise exception instead of using assert 2019-07-03 18:35:55 +02:00
ZeroNet
80bfccd9d3
Merge pull request #2066 from geekless/Dockerfile-fix-caching
Fix the order of commands in Dockerfile to make use of the caching
2019-07-03 16:22:03 +02:00
ZeroNet
eb5a24064a
Merge pull request #2067 from rllola/fix-travis
fix pytest version to 4.6.3 to avoid it to broke for python 3.8 dev
2019-07-03 16:21:23 +02:00
rllola
b971ccc673 fix pytest version to 4.6.3 to avoid it to broke for python 3.8 dev 2019-07-03 15:48:18 +02:00
Vadim Ushakov
945687bdad Fix the order of commands in Dockerfile to make use of the caching of intermediate Docker images.
In py2 version, `COPY . /root` was placed after `RUN apk ...`, so that the result of `RUN apk ...` can be cached by Docker.

In py3 version, the commands were reordered to make the file `/root/requirements.txt` available for `pip install`. That prevents caching, and the docker image every time is rebuild from scrach.

To enable the caching back again, we can `COPY` just the single file `requirements.txt` before running other commands. Since the file is unmodified most of the time, the resulting image can be effectively cached. The other ZeroNet files are copied after doing `RUN apk ...`, as in the previous version.
2019-07-03 19:18:54 +07:00
ZeroNet
6f56d0a944
Update .travis.yml 2019-07-03 11:44:12 +02:00
ZeroNet
66c48ba4ec
Update to latest packages before tests 2019-07-02 16:03:41 +02:00
ZeroNet
f83ade8d33
Merge pull request #2061 from imachug/dotdot
Allow some paths to contain .. but not ../
2019-07-01 17:56:27 +02:00
ZeroNet
eae0d1b2a6
Merge pull request #1959 from tangdou1/patch-1
Change default value to 10MB
2019-07-01 17:45:37 +02:00
Ivanq
743f92d15e Allow some paths to contain .. but not ../ 2019-07-01 18:17:42 +03:00
shortcutme
822dec5c03
Rev4110 2019-07-01 16:28:56 +02:00
shortcutme
40b84755de
Add some fixed content_type 2019-07-01 16:28:37 +02:00
shortcutme
1b307166ee
Formatting 2019-07-01 16:27:40 +02:00
shortcutme
7a483e7912
Add short address to site_info 2019-07-01 16:27:34 +02:00
shortcutme
841230fe80
Call onClosed function if websocket is disconneced 2019-07-01 16:27:20 +02:00
shortcutme
900ae4e1ea
Remove notification about port open status on startup 2019-07-01 16:26:57 +02:00
shortcutme
72b6d6c676
Make wrapper compatible with sidebar console function 2019-07-01 16:26:37 +02:00
shortcutme
f979ed133f
Workaround for pytest 0.4.1+ atexit logging errors 2019-07-01 16:25:45 +02:00
shortcutme
fb2cf5f04d
More detailed logging of file change event 2019-07-01 16:24:48 +02:00
shortcutme
62401b24ec
Add r string literal for regexps 2019-07-01 16:24:23 +02:00
shortcutme
43f833e604
Allow multiple values of same key in the config file 2019-07-01 16:20:13 +02:00
shortcutme
612a3f4401
Fix parsing config file for lines that has no values 2019-07-01 16:19:32 +02:00
shortcutme
4c2cf99fd2
Add console function to sidebar 2019-07-01 16:19:12 +02:00
shortcutme
aebd9b410d
Fix feedlistfollow request before siteinfo 2019-07-01 16:08:21 +02:00
Ivanq
8eee9caa01 Fix siteCloning subdirectory with -default files 2019-07-01 09:49:03 +03:00
Ivanq
d278a30d19 Allow sites to lock pointer (#2059)
Add `allow-pointer-lock` to iframe sandbox
2019-06-30 16:39:17 +02:00
Ivanq
1117569148 Fix starting ZeroNet via start.py (#2052) 2019-06-28 00:58:58 +02:00
Lola Dam
753396ac0c Try and catch block for dbRebuild (#2047)
* Try and catch block for dbRebuild

* Use self.log.error and not logging

* Use self.log.error and not logging in SiteStorage also

* Check if the rebuild is working
2019-06-23 14:21:50 +02:00
shortcutme
9a267ffcaf
Rev4016, Fix updater 2019-06-12 02:57:18 +02:00
ZeroNet
6254143fc6
Fix noparallel ignoreclass test 2019-06-11 18:24:44 +02:00
shortcutme
862e19a263
Rev4104, Don't start blocking Noparallel calls in separate greenlet to be able to catch exceptions. 2019-06-11 17:04:37 +02:00
shortcutme
eeef6fe65f
Rev4102, Fix fileGet test 2019-06-06 03:17:42 +02:00
shortcutme
c05916477c
Merge branch 'py3' of https://github.com/HelloZeroNet/ZeroNet into py3 2019-06-06 02:49:14 +02:00
shortcutme
63d7e73cff
Rev4101 2019-06-06 02:49:11 +02:00
shortcutme
8cb629fb55
Return True on rebuildDb success 2019-06-06 02:27:59 +02:00
shortcutme
d596f28f46
Log non-file read errors on fileGet 2019-06-06 02:27:35 +02:00
shortcutme
8f26c0aeae
Test null byte file download bug fix 2019-06-06 02:27:09 +02:00
ZeroNet
e4978d8a05
Use dev version of gevent for Python 3.8 2019-06-04 22:27:16 +02:00
ZeroNet
4f43d977ed
Install cffi files to compile gevent 2019-06-04 20:05:33 +02:00
ZeroNet
d0c39e6bf4
Test using Python 3.8-dev 2019-06-04 19:48:39 +02:00
ZeroNet
0965d98dbd
Also test with Python 3.8 2019-06-04 18:54:47 +02:00
shortcutme
45fea827af
Rev4100 2019-06-04 16:18:59 +02:00
shortcutme
350ee13d66
Fix serving binary files with zero characters in it. 2019-06-04 16:18:52 +02:00
shortcutme
bb7af2e8ed
Fix closing progress notification at 100% 2019-06-04 16:18:02 +02:00
Lola Dam
9cda561091 Show error message when db failed to rebuild (#2043)
* Show error message when db failed to rebuild; fix #1908;

* Forgot file
2019-06-04 13:54:35 +02:00
shortcutme
d38846f126
Rev4099, Fix ZipStream for older Python versions 2019-05-31 15:08:30 +02:00
shortcutme
3b764439af
Rev4098 2019-05-30 04:29:57 +02:00
shortcutme
d1e404f093
New updater that supports updating bundle files 2019-05-30 04:29:47 +02:00
shortcutme
6c4440c2d1
Less verbose Tor controller logging 2019-05-30 04:28:57 +02:00
shortcutme
8e2a7c2b2d
Respect optionalHelp when checking files 2019-05-30 04:28:41 +02:00
shortcutme
fce30baa12
Check files in offline mode on update 2019-05-30 04:28:09 +02:00
shortcutme
c63215c992
Don't download geolite db in offline mode 2019-05-30 04:27:40 +02:00
shortcutme
815fe02c83
Make sidebarGetPeers an async command 2019-05-30 04:27:20 +02:00
shortcutme
e2e1a5b38c
Fix streamZip variable name 2019-05-30 04:27:01 +02:00
shortcutme
4222c31b3e
Don't push body of content.json with updates if larger than 10kb 2019-05-30 04:26:41 +02:00
shortcutme
e5d3b0e7b8
Use openssl from tools directory on Windows 2019-05-30 04:24:58 +02:00
shortcutme
422064e092
Only show console after app close in debug mode 2019-05-30 04:24:42 +02:00
shortcutme
d548c6bdfa
Add new line after benhmark errors 2019-05-30 04:24:17 +02:00
shortcutme
efb7b147af
Fix broken zip file generation 2019-05-30 04:24:01 +02:00
shortcutme
0f8b220f59
Merge sidebar js 2019-05-29 16:03:48 +02:00
shortcutme
1bba253156
Rev4094 2019-05-29 16:03:32 +02:00
shortcutme
a2d29a4531
Only display sign error if there is no stored privatekey 2019-05-29 16:03:10 +02:00
shortcutme
589869c5ed
Move progress display to separate function 2019-05-29 16:02:34 +02:00
shortcutme
7b41922c2d
Use user certificate if possible for signing using sidebar, more sign, publish to separate functions 2019-05-29 16:02:10 +02:00
Lola Dam
7262fbfb4e Added optional redirect value for siteClone (#2032)
* Added optional redirect value; see #1891

* Return address of the newly cloned site
2019-05-28 18:05:52 +02:00
Lola Dam
9c0e8ee833 Better error message if private key not stored when assigning (#2033)
* Return a more instructive message in case the privatekey is not found when attempting to sign

* Fix typo
2019-05-28 18:04:49 +02:00
Ivanq
9119d72b9b Fix calling start.py to reopen browser (#2029)
* Fix calling start.py to reopen browser

* Move below
2019-05-24 16:36:29 +02:00
shortcutme
891aac4713
Rev4093 2019-05-21 15:57:49 +02:00
shortcutme
2fa006d74e
Fix loading json files with utf8 content 2019-05-21 15:54:36 +02:00
shortcutme
a6c97a304f
Remove empty exception from config.py 2019-05-21 15:53:53 +02:00
shortcutme
cfa4f8fa63
Fix log_dir exception on startup fail 2019-05-21 15:53:32 +02:00
shortcutme
ce0cf09b10
Fix sidebar zip generation 2019-05-21 15:52:58 +02:00
shortcutme
1567fb745d
Fix sidebar site download with utf8 title 2019-05-21 15:52:44 +02:00
ZeroNet
416f563261
Exclude third-party pybitcointools from flake8 test 2019-05-20 17:17:49 +02:00
ZeroNet
25d6eea906
Merge pull request #2026 from imachug/js-modules
ECMAScript modules
2019-05-20 17:06:17 +02:00
ZeroNet
4e819ac035
Merge pull request #2025 from imachug/fileneed-timeout
Handle fileNeed timeout
2019-05-20 17:05:23 +02:00
ZeroNet
dbcaa6bf85
Merge pull request #2006 from imachug/cryptmessage-bitcoin
Add privToPub and pubToAddr commands
2019-05-20 17:04:38 +02:00
Ivanq
3205187090 Rename commands to have ecc... prefix 2019-05-19 15:52:36 +03:00
Ivanq
ed85981409 Fix JS modules 2019-05-19 15:45:34 +03:00
Ivanq
5d920ff7df Handle gevent.Timeout error 2019-05-19 15:42:11 +03:00
ZeroNet
5456f0e106
Merge pull request #2020 from cclauss/patch-1
Travis CI: Use flake8 to find Python syntax errors
2019-05-17 17:30:13 +02:00
cclauss
8962c16670
Declare 'err' because Python 3 has stricter scoping rules
I Python 3, __err__ will go out of scope after the __try / except__ block.  This change preserves the value after the end of the __try / except__ block.
2019-05-17 12:33:10 +02:00
cclauss
2ed1572c3c
Travis CI: Use flake8 to find Python syntax errors
Also, put the execution steps in order:
1. before_install -->
2. install -->
3. before_script -->
4. script -->
5. after success -->
6. notifications
2019-05-17 09:00:25 +02:00
ZeroNet
89cb673502
Merge pull request #2016 from cclauss/patch-1
.travis.yml: The 'sudo' tag is now deprecated in Travis CI
2019-05-16 23:16:14 +02:00
ZeroNet
98c9c8dd43
Merge pull request #2018 from cclauss/patch-2
Fix Python 3 syntax errors in zonename_updater.py
2019-05-16 23:13:10 +02:00
cclauss
fd46f141ea
Fix Python 3 syntax errors in zonename_updater.py 2019-05-16 19:39:16 +02:00
cclauss
41aec089bc
.travis.yml: The 'sudo' tag is now deprecated in Travis CI 2019-05-16 00:00:52 +02:00
cclauss
31697022fd
Add Python 3.4 2019-05-15 23:59:36 +02:00
cclauss
948a1c3d03
.travis.yml: The 'sudo' tag is now deprecated in Travis CI
[Travis are now recommending removing the __sudo__ tag](https://blog.travis-ci.com/2018-11-19-required-linux-infrastructure-migration).

"_If you currently specify __sudo: false__ in your __.travis.yml__, we recommend removing that configuration_"

Also, removed Python 3.4 because it is EOL  https://devguide.python.org/devcycle/#end-of-life-branches
2019-05-15 22:36:48 +02:00
shortcutme
20371895c9
Rev4090, Remove fs paths from error responses 2019-05-02 18:02:56 +02:00
shortcutme
617027eb52
Rev4089, Support compressed addresses in libsecp256k1 sign verification 2019-05-02 17:38:36 +02:00
shortcutme
6b9106b178
Test verify of compressed and uncompressed address signature 2019-05-02 17:18:31 +02:00
shortcutme
6207ccd559
Fix pex result parsing when there is no connection 2019-05-02 17:17:57 +02:00
shortcutme
043ac5a510
Log renaming 2019-05-02 17:17:00 +02:00
Ivanq
4eaeade618 Add privToPub and pubToAddr commands 2019-05-01 08:04:39 +03:00
shortcutme
f318f76994
Add missing function 2019-04-29 17:18:02 +02:00
shortcutme
fd085d2d37
Rev4086, Fix verify content.json files without files_optional 2019-04-29 16:54:07 +02:00
shortcutme
327f580218
Rev4085 2019-04-29 16:44:19 +02:00
shortcutme
7bef78e10f
Fix newsfeed sql query with many parameters 2019-04-29 16:44:13 +02:00
shortcutme
b54916b1dc
Show console after got hidden in non-debug mode 2019-04-29 16:43:34 +02:00
ZeroNet
c2ab102c0e
Merge pull request #1999 from filips123/py3
Support for detection of system's theme
2019-04-29 16:35:55 +02:00
ZeroNet
3f3e73455b
Merge pull request #2001 from imachug/build-all
Build wrapper all.js to support web notifications
2019-04-29 16:32:35 +02:00
Ivanq
4f09a5111b Build wrapper all.js to support web notifications 2019-04-27 18:19:16 +03:00
Filip Š
baf820bcdb Support for detection of system's theme 2019-04-26 18:23:25 +02:00
ZeroNet
538f69235f
Merge pull request #1985 from rllola/fix-zeroname-local
New ZeronameLocal plugin with connection to namecoin node
2019-04-26 12:58:50 +02:00
ZeroNet
2b9f1257be
Merge pull request #1993 from imachug/notifications
Support web notifications
2019-04-26 12:58:18 +02:00
Ivanq
6e58e8d50f Don't require WebNotifications permission 2019-04-26 12:55:33 +03:00
shortcutme
90420f1a89
Merge branch 'py3' of https://github.com/HelloZeroNet/ZeroNet into py3 2019-04-23 02:01:45 +02:00
shortcutme
021b822c4f
Rev4080 2019-04-23 02:01:40 +02:00
shortcutme
4ac54845fc
Fix double logging when testing 2019-04-23 02:00:59 +02:00
shortcutme
4c9d3ee3a6
Test big file renames 2019-04-23 02:00:11 +02:00
shortcutme
e688671972
Fix rename error variable problem in site storage 2019-04-23 01:59:59 +02:00
shortcutme
6bd63ff42a
Test file renames 2019-04-23 01:59:12 +02:00
shortcutme
efc5211451
Test optional file renames in OptionalManager plugin 2019-04-23 01:58:37 +02:00
shortcutme
f2bf5b12bd
Support optional file rename in OptionalManager plugin 2019-04-23 01:58:21 +02:00
shortcutme
dccda1af92
Pass optionalRemoved return value 2019-04-23 01:57:57 +02:00
shortcutme
4ca0e6b781
Support file renames in content.json if the sha512 hash is the same 2019-04-23 01:56:11 +02:00
shortcutme
4016e7c217
Test Bigfile plugin using tostring where it possible 2019-04-23 01:55:05 +02:00
rllola
907a26a8b9 Take care of the exceptions so it wont crash zeronet if someting goes wrong. 2019-04-20 20:23:59 +02:00
ZeroNet
dc23bfeb87
Merge pull request #1994 from imachug/ecdsa
A third small ECDSA fix
2019-04-20 13:20:03 +02:00
shortcutme
4bfd4bd714
Rev4074, Fix Ecdsa functions in cryptmessage plugin 2019-04-20 09:48:56 +02:00
Ivanq
9ddb984004 Rename Push notifications to Web notifications 2019-04-19 22:19:25 +03:00
Ivanq
e618c0e9ef Add closePushNotification 2019-04-19 22:19:25 +03:00
Ivanq
b55d2b53df Support Notification API 2019-04-19 22:19:25 +03:00
Ivanq
5733ec8363 Fix 2019-04-19 22:16:59 +03:00
Ivanq
d7d75a1fe8 Fix ECDSA on CryptMessage (#1987)
* Add ecdsaSign and ecdsaVerify

* Fix return

* Fix unicode

* Update CryptMessagePlugin.py

* Remove .encode("utf8")

* Fix keys during ECDSA signing
2019-04-19 19:34:07 +02:00
rllola
ef6ccb330b Dont raise an error if domain has more than one subdomain and just return None 2019-04-18 15:27:49 +02:00
shortcutme
afbacdfc96
Rev4073 2019-04-18 12:23:55 +02:00
shortcutme
5842441062
Remove unused function 2019-04-18 12:22:57 +02:00
shortcutme
f083301b4c
Allow larger packets 2019-04-18 12:22:38 +02:00
shortcutme
8edbecce3c
Fix diffing 2019-04-18 12:21:59 +02:00
shortcutme
b114c52c0d
Allow pluginned classes in memory on reload 2019-04-18 12:21:50 +02:00
shortcutme
4671f47222
Fix bigfile piecefield standalone run test 2019-04-18 12:21:33 +02:00
rllola
4be0e1ee7f Forgot to cache in one 'if' 2019-04-17 18:34:53 +02:00
ZeroNet
dd4c213805
Merge pull request #1989 from radfish/PR-py3--translate-bytearray-fix
Ui, Translate: fix bytearray format string for Py 3.4
2019-04-17 11:29:16 +02:00
redfish
7e57a8f71e Ui,Translate: remove bytearray format string
Py 3.4 does not support bytearray format strings
for % operator: b"%s" % s
2019-04-16 20:54:55 -04:00
rllola
86d3d35619 Disable Zeroname plugin 2019-04-16 20:07:30 +02:00
rllola
f195111354 Using http.client instead of requests module 2019-04-16 16:23:09 +02:00
radfish
ec6fd48b86 Bigfile: fix piece field bitmask to be used as bytearray consistently (#1982)
* Bigfile: make Piecefield array a bytearray

We want an array of characters. Py2 strings made sense to
use as an array of characters, but Py3 strings are different
and no longer a good choice.

* Bigfile: store bits as binary instead of char

* BigFile: rename to/from string -> to/from bytes

Since the type was changed to bytearray.
2019-04-16 15:14:19 +02:00
radfish
1516d55a88 Sidebar: rename media-globe/ to media_globe/ (#1973)
So that it can be an importable package.
This is in preparation for setuptools packaging.
2019-04-16 11:34:55 +02:00
Ivanq
bdb0dc32a7 Add ECDSA actions to CryptMessage (#1984)
* Add ecdsaSign and ecdsaVerify

* Fix return

* Fix unicode

* Update CryptMessagePlugin.py
2019-04-15 22:55:01 +02:00
shortcutme
5ff2f792e6
Rev4070, Fix Multiuser plugin import order, Run coverage before optional plugins 2019-04-15 22:54:17 +02:00
shortcutme
8246505289
Rev4069 2019-04-15 22:48:55 +02:00
shortcutme
526a5d3fb1
Fix compatibility with Python <=3.5 2019-04-15 22:48:43 +02:00
shortcutme
f970815645
Run tests in debug mode 2019-04-15 22:48:16 +02:00
shortcutme
f83c77e7ea
Fix plugin error message 2019-04-15 22:48:09 +02:00
shortcutme
654cce92cd
Rev4068 2019-04-15 22:24:00 +02:00
shortcutme
8f0bfbc553
Test Multiuser and Bootstrapper plugins 2019-04-15 22:23:30 +02:00
shortcutme
bc39e52f56
Rev4066 2019-04-15 22:20:16 +02:00
shortcutme
a822238735
Use 1544 port for tor in tests 2019-04-15 22:19:38 +02:00
shortcutme
b168772d7f
Create user for tests if necessary 2019-04-15 22:19:16 +02:00
shortcutme
034e104c06
Log fileserver startup error for tests 2019-04-15 22:19:00 +02:00
shortcutme
0c0f117bc3
Don't parse config file for tests 2019-04-15 22:18:40 +02:00
shortcutme
1d4ab8833b
Test and enforce proper import plugin order in debug mode 2019-04-15 22:18:18 +02:00
shortcutme
90fee9788d
Always translate html files to avoid compatibility problems with brackets in url 2019-04-15 22:16:47 +02:00
shortcutme
bf7597e1b2
Add simple test for Multiuser plugin 2019-04-15 22:16:05 +02:00
shortcutme
54ff940c2b
Fix Bootstrapper plugin py3 compatibility 2019-04-15 22:15:42 +02:00
shortcutme
446641c31c
Always commit before Db VACUUM 2019-04-15 22:11:44 +02:00
shortcutme
572d55752c
Avoid random websocket test fails 2019-04-15 16:54:49 +02:00
shortcutme
04394d8ced
Rev4064 2019-04-15 16:29:01 +02:00
shortcutme
c7ea66bfef
Fix shutdown before file_server started 2019-04-15 16:07:18 +02:00
shortcutme
bfc5e2dce6
Support live changing offline mode 2019-04-15 15:49:53 +02:00
shortcutme
a7e8293d1a
Add offline mode info to server info 2019-04-15 15:49:34 +02:00
shortcutme
698f0cc230
Fix isServing check in site info formatting 2019-04-15 15:49:04 +02:00
shortcutme
f414f0746c
Don't update site in offline mode 2019-04-15 15:48:16 +02:00
shortcutme
235b8f359c
Don't create new connections in offline mode 2019-04-15 15:47:17 +02:00
shortcutme
2326cf3de8
Ignore incoming connections in offline mode 2019-04-15 15:47:05 +02:00
shortcutme
b8879853d5
Support closing all current connection in ConnectionServer 2019-04-15 15:46:53 +02:00
shortcutme
498fd4bf01
Don't listen ConnectionServer if not started 2019-04-15 15:46:37 +02:00
shortcutme
996f326c74
Store if UiServer is running 2019-04-15 15:45:07 +02:00
shortcutme
43b68faf73
Merge Ui all.js 2019-04-15 15:44:04 +02:00
shortcutme
8429ad7db7
Use global ZeroNet-Internal url to access Websocket 2019-04-15 15:42:24 +02:00
shortcutme
879b522914
Disable portcheck in offline mode 2019-04-15 15:16:38 +02:00
shortcutme
be584aa3d1
Change offline mode in /Config page 2019-04-15 15:12:08 +02:00
shortcutme
b82f57e7a2
Fix small file upload using bigfile plugin 2019-04-15 15:07:31 +02:00
shortcutme
998ec3eb4f
Disable all site serving using a global offline argument 2019-04-15 15:06:25 +02:00
radfish
f6e3a74567 [setuptools packaging] access modules via imports (#1969) 2019-04-15 12:31:33 +02:00
ZeroNet
6d8f55cf75
Merge pull request #1983 from krzotr/patch-3
OptionalManager file info - set bytes_downloaded to total file size if a file is fully downloaded
2019-04-15 12:21:28 +02:00
rllola
c4d8466195 Delete old plugin 2019-04-14 22:58:05 +02:00
rllola
36ff506dfe Added 'requests' dependency to requierements.txt 2019-04-14 22:44:04 +02:00
rllola
af1fb7aaa6 Also recognise 'map' namecoin standard way of registering for domain 2019-04-14 22:41:26 +02:00
rllola
1a944735df New ZeronameLocal plugin with connection to namecoin node 2019-04-14 16:58:58 +02:00
krzotr
1c8fba4286
OptionalManager file info - set bytes_downloaded to file size if a file is fully downloaded 2019-04-13 23:07:13 +02:00
shortcutme
0260b30335
Rev4059 2019-04-12 15:03:58 +02:00
shortcutme
0f72085c2a
Also return ws error to websocket connection 2019-04-12 15:03:43 +02:00
shortcutme
6ad8a10f37
Fix invalid ws request response value 2019-04-12 15:03:19 +02:00
shortcutme
8a38983dfc
Better logging of ws connection for siteCmd CLI action 2019-04-12 15:02:04 +02:00
shortcutme
9f5600b7f7
Rev4057, Log invalid result from websocket 2019-04-11 16:33:36 +02:00
shortcutme
a7632889a2
Rev4056 2019-04-11 01:30:04 +02:00
shortcutme
58a4bf479c
Only send env details if in debug mode 2019-04-11 01:29:56 +02:00
shortcutme
1ce4f99b80
Send noscript header to error messages and OPTIONS request 2019-04-11 01:29:32 +02:00
shortcutme
f94ecb3ec5
Fix error 404 on uimedia route 2019-04-11 01:28:00 +02:00
shortcutme
ce7c22fd57
Ignore items with no date_added in newsfeed 2019-04-11 01:18:52 +02:00
shortcutme
a5c7e59601
Rev4054, Escape error detail to avoid XSS (reported by krzotr) 2019-04-11 00:37:55 +02:00
ZeroNet
efbf70726f
Merge pull request #1975 from krzotr/patch-2
Updated to python 3.6 in Dockerfile
2019-04-10 23:43:50 +02:00
krzotr
490b1dc01b
Updated python version in Dockerfile 2019-04-10 23:08:09 +02:00
shortcutme
ec81965393
Rev4053 2019-04-10 19:59:56 +02:00
shortcutme
21536b8948
More clear logging when pinging unencrypted connections 2019-04-10 19:59:37 +02:00
shortcutme
100c2c8741
Set serial by command line to avoid .srl file creation 2019-04-10 19:59:02 +02:00
shortcutme
d47e4a3e0e
More detailed error logging on ssl handshake fail 2019-04-10 19:58:37 +02:00
shortcutme
0c9ea8f580
Merge branch 'py3' of https://github.com/HelloZeroNet/ZeroNet into py3 2019-04-10 14:57:32 +02:00
shortcutme
2320eb8723
Rev4052 2019-04-10 14:57:24 +02:00
shortcutme
17bbeefeca
Fix getWebsocket 2019-04-10 14:57:06 +02:00
shortcutme
31372e269d
Give notification to all connected clients about ZeroNet update 2019-04-10 14:56:47 +02:00
shortcutme
ac799a60da
Stop fs watcher with UiServer 2019-04-10 14:56:10 +02:00
radfish
6a1d716ba1 test: refer to test data path via variable (#1964) 2019-04-10 11:30:35 +02:00
ZeroNet
ed12cc1186
Merge pull request #1952 from tangdou1/patch-6
Update TrayiconPlugin.py for IPV6 compatibility
2019-04-09 17:53:04 +02:00
ZeroNet
8370ac8426
Merge pull request #1970 from radfish/PR-py3--import-plugins
[setuptools packaging] PluginManager: get plugins path via import
2019-04-09 17:51:05 +02:00
shortcutme
a20ff59572
Rev4050 2019-04-09 16:21:46 +02:00
shortcutme
8587f01caa
Fix update script target directory 2019-04-09 16:21:39 +02:00
shortcutme
c7078be407
Always verify client update 2019-04-09 15:07:56 +02:00
shortcutme
718a00974b
Merge js 2019-04-09 15:06:33 +02:00
shortcutme
d612676a80
Log closing websocket when updating event 2019-04-09 15:06:27 +02:00
shortcutme
d7bcfb415b
Fix js merging white space stripping 2019-04-09 15:06:09 +02:00
shortcutme
6928a17e61
Rev4048 2019-04-08 18:15:23 +02:00
shortcutme
d097092e8e
Merge js 2019-04-08 18:15:02 +02:00
shortcutme
79eb6573be
Support listing bad files with API 2019-04-08 18:14:45 +02:00
shortcutme
ffed8c9181
Add updatesite, dist_type, verify lib to serverinfo for admin sites 2019-04-08 18:14:31 +02:00
shortcutme
ff8573635d
Limit max width of notification 2019-04-08 18:13:58 +02:00
shortcutme
643244ffd1
Less visible changed files notification number 2019-04-08 18:13:18 +02:00
shortcutme
9fd059aef8
Give admin permission to updater site 2019-04-08 18:12:58 +02:00
shortcutme
6764a7ad2f
Fix js merging 2019-04-08 18:12:43 +02:00
shortcutme
5642d0aae6
Also ignore db -wal and -shm temp db files when signing 2019-04-08 18:12:29 +02:00
shortcutme
763e5f4ac0
Fix too short sleep 2019-04-08 18:12:00 +02:00
shortcutme
87abdb92e9
Fix bigfile upload 2019-04-08 18:11:46 +02:00
ZeroNet
447ab47d59
Merge pull request #1971 from radfish/PR-py3--bump-interpreter
[setuptools packaging] zeronet: bump script interpreter to python3
2019-04-08 01:57:58 +02:00
redfish
9ed88f25f0 zeronet: bump script interpreter to python3 2019-04-07 19:41:19 -04:00
redfish
73814550e5 PluginManager: get plugins path via import
* skip __pycache__ when loading
2019-04-07 18:50:23 -04:00
ZeroNet
226f7dea65
Merge pull request #1962 from radfish/PR-py3--sys-geoip
Sidebar: use geoip db from system if exists
2019-04-07 12:04:44 +02:00
ZeroNet
ed3de771e8
Merge pull request #1963 from radfish/PR-py3--dead-ssl-code
[setuptools packaging] remove some  dead code related to openssl, pyelliptic
2019-04-07 12:03:17 +02:00
ZeroNet
edf3cf3b65
Merge pull request #1966 from radfish/PR-py3--ui-pathlib
[setuptools packaging] Ui: extend actionFile to accept pathlib.Path
2019-04-07 12:01:07 +02:00
ZeroNet
7a54615156
Merge pull request #1965 from radfish/PR-py3--cfg-paths-no-dec
[setuptools packaging] config: path.expanduser returns py3 strings
2019-04-07 11:56:18 +02:00
redfish
1e1f967292 Ui: extend actionFile to accept pathlib.Path 2019-04-06 22:22:34 -04:00
redfish
6f5d4fdc51 config: path.expanduser returns py3 strings
And strings have no decode method.
2019-04-06 22:16:37 -04:00
redfish
e7a6be035e zeronet: no openssl.closeLibrary in pyelliptic
Not in pyelliptic 2.0.1 (PyBitmessage fork of pyelliptic)
2019-04-06 20:13:56 -04:00
redfish
ee762f349c zeronet: remove ref to opensslVerify
This module is no longer used. Not in lib/
2019-04-06 20:13:56 -04:00
redfish
4d98b05e6c Sidebar: use geoip db from system if exists 2019-04-06 17:24:25 -04:00
ZeroNet
4f4591658d
Merge pull request #1960 from imachug/start-browser
Fix double --open_browser
2019-04-06 23:13:12 +02:00
Ivanq
0c70e95232
Use spaces instead of tabs 2019-04-06 15:02:18 +03:00
Ivanq
594e8b8c20 Fix double --open_browser 2019-04-06 08:30:45 +03:00
tangdou1
4c358b9f08
Big File is bigger than 10MB
Big File is an optional file which is bigger than 10MB, so the default value should be at least 10MB.
2019-04-06 11:57:58 +08:00
shortcutme
7b1594c69c
Rev4044 2019-04-04 13:29:36 +02:00
shortcutme
6d27feba97
New updater site for Python3 version 2019-04-04 13:29:26 +02:00
shortcutme
4363dcbbc1
Distribtion type config value for future support in the updater script 2019-04-04 13:29:11 +02:00
shortcutme
a208f47b6a
Fix sidebar opening for fast mouse movements 2019-04-04 13:28:38 +02:00
shortcutme
84268cd43c
Updater script 2019-04-04 13:28:02 +02:00
shortcutme
380c32dee2
Worker stats on stop 2019-04-04 13:27:46 +02:00
shortcutme
bfc7e7c33f
Only start worker if there is valid task for it 2019-04-04 13:27:21 +02:00
shortcutme
8594e4ce4a
Add reason for startWorkers 2019-04-04 13:27:06 +02:00
shortcutme
752dabe554
Openssl dll find patch to libeay32 2019-04-04 13:25:10 +02:00
shortcutme
042db64a00
Fix multiuser plugin py3 compatibility 2019-04-04 13:24:42 +02:00
shortcutme
f55fd8d861
Avoid re-define variable name 2019-04-04 13:24:26 +02:00
ZeroNet
cc41572d48
Merge pull request #1953 from tangdou1/patch-4
ipv6 compatibility
2019-04-03 15:54:54 +02:00
tangdou1
42de962cbf
ipv6 compatibility 2019-04-03 19:56:14 +08:00
tangdou1
f527b8225f
IPV6 compatibility 2019-04-03 19:54:19 +08:00
ZeroNet
dd9ccfa3d2
Merge pull request #1947 from radfish/PR-py3--cryptmsg-base64-type
CryptMessage: base64 arg type byte-array; File: set error message before use
2019-04-01 01:15:59 +02:00
ZeroNet
24b6780c1f
Merge pull request #1946 from tangdou1/patch-5
Update README.md
2019-04-01 01:15:20 +02:00
redfish
941571f71f file: set error message before using it
Fixes this exception:

Unhandled exception: [(<class 'UnboundLocalError'>,
UnboundLocalError("local variable 'err' referenced before assignm>
 Traceback (most recent call last):
   File "src/gevent/greenlet.py", line 766, in gevent._greenlet.Greenlet.run
   File "/opt/zeronet/src/util/RateLimit.py", line 57, in <lambda>
     thread = gevent.spawn_later(time_left, lambda: callQueue(event))  # Call this function later
   File "/opt/zeronet/src/util/RateLimit.py", line 42, in callQueue
     return func(*args, **kwargs)
   File "/opt/zeronet/src/File/FileRequest.py", line 185, in actionUpdate
     self.response({"error": "File invalid: %s" % err})
UnboundLocalError: local variable 'err' referenced before assignment
2019-03-31 16:25:26 -04:00
redfish
65be9f438b CryptMessage: pass byte-array type to base64
Fixes this error upon sending a message in ZeroMail:
WebSocket handleRequest error: TypeError: a bytes-like object is
required, not 'str' in UiWebsocket.py line 83 > UiWebsocket.py line 269
> CryptMessage/CryptMessagePlugin.py line 80 >
CryptMessage/CryptMessagePlugin.py line 80 > base64.py line 58
2019-03-31 14:05:15 -04:00
tangdou1
15d13ac9f6
Update README.md 2019-03-31 13:47:47 +08:00
ZeroNet
6df3acaf1e
Merge pull request #1943 from radfish/PR-py3--req
requirements: pyelliptic any version, websocket_client
2019-03-31 00:24:15 +01:00
redfish
b6ee24dcd5 readme: mention distro packages; also formatting 2019-03-30 09:50:10 -04:00
redfish
1a3e5b7893 requirements: main websocket package
'websocket' doesn't look like the right one.
2019-03-30 09:50:10 -04:00
shortcutme
5df8e10b95
Rev4033 2019-03-29 02:31:46 +01:00
shortcutme
bddf2d6537
Fix fileGet command 2019-03-29 02:31:14 +01:00
shortcutme
3d05bdcb63
Log file command errors 2019-03-29 02:31:05 +01:00
shortcutme
52e28eefce
Use lowercase filename for content type guess 2019-03-29 02:30:43 +01:00
shortcutme
b5b0626251
Add name for websocket event on site deletion 2019-03-29 02:30:26 +01:00
shortcutme
4a4f311cf8
Better logging of cert generation 2019-03-29 02:29:55 +01:00
shortcutme
bad4d14cf6
Save OpenSSL rand file in data directory to avoid error message on Windows 2019-03-29 02:29:32 +01:00
shortcutme
b814a633c6
Don't reset broken ssl client list on cleanup 2019-03-29 02:28:46 +01:00
shortcutme
73524d70dc
Switch back to default log file naming because of broken rotate file deleting 2019-03-29 02:28:03 +01:00
shortcutme
9fad83e46c
More detailed logging on archive open error 2019-03-29 02:27:26 +01:00
shortcutme
9fbf4771f2
Fix directory commands on packed files 2019-03-29 02:26:50 +01:00
shortcutme
41cd7da5bd
Rev4026 2019-03-27 03:13:14 +01:00
shortcutme
3d975fd767
Fix libeay32.dll location 2019-03-27 03:12:21 +01:00
shortcutme
f8f857c820
Fix atomicWrite non existing tmpold removal 2019-03-27 03:12:02 +01:00
shortcutme
9546ed0bb6
Try to connect to tor before starting own one under windows 2019-03-27 03:11:38 +01:00
shortcutme
a3f957427f
Make sure the test went without unnecessary reconnects 2019-03-27 03:10:58 +01:00
shortcutme
9b36c55422
Fix pytest warning 2019-03-27 03:10:29 +01:00
shortcutme
b6286372fb
Better cleanup after tests 2019-03-27 03:10:21 +01:00
shortcutme
74e71a1971
Fix http tracker announce compatibility 2019-03-27 03:09:47 +01:00
shortcutme
9050f1a039
Show crypto cipher on peerPing command 2019-03-27 03:09:28 +01:00
shortcutme
de303bf453
Modern crypto ciphers 2019-03-27 03:09:09 +01:00
shortcutme
3d8d3a9237
Randomize SSL subject (merged ValdikSS's commit) 2019-03-27 03:08:37 +01:00
shortcutme
cf354d59fb
Fix incoming connection implicit crypt 2019-03-27 03:06:46 +01:00
shortcutme
706852d9a7
Fix Stats page rendering in non-debug mode, reduce source code size 2019-03-27 03:06:22 +01:00
shortcutme
63e405c27e
Rev4022 2019-03-23 03:42:26 +01:00
shortcutme
33e8c6fb73
Fix ipv6 port checker 2019-03-23 03:41:52 +01:00
shortcutme
faba28dd94
Proper handle of sigterm signal, log reason of shutdown 2019-03-23 03:41:42 +01:00
shortcutme
16f36824e6
Fix benchmark on Python 3.5 2019-03-23 03:40:42 +01:00
shortcutme
5c1ec0b141
Ecies encrypted string length can be different in rare cases 2019-03-23 03:38:30 +01:00
shortcutme
e24d1016a5
Fix bigfile upload post request return value 2019-03-23 03:38:04 +01:00
shortcutme
a82ee338ef
Rev4017, Fix Bigfile test, Python 3.4 compatibility 2019-03-21 02:48:21 +01:00
shortcutme
60405bf222
Rev4016, Add ad test Python 3.4 compatibility 2019-03-21 02:22:22 +01:00
shortcutme
1da6c8c84e
Fix Python 3.7 test 2019-03-20 01:07:18 +01:00
shortcutme
32329c1817
Rev4015 2019-03-20 01:06:56 +01:00
shortcutme
4aee7a6c61
Make openLocked always return BlockingIOError on fail 2019-03-20 01:05:52 +01:00
shortcutme
e6c2937c1b
Rev4014 2019-03-20 00:50:44 +01:00
shortcutme
1bbf9b62ad
Test on multiple python versions 2019-03-20 00:50:32 +01:00
shortcutme
fa9e024b42
Base58 package is required for libsecp256k verify 2019-03-20 00:50:18 +01:00
shortcutme
8c52038671
Switch to WAL mode as it's faster on older sqlite 2019-03-20 00:49:51 +01:00
shortcutme
7aff97b6ff
Fix loading json files to db on Python 3.5 2019-03-20 00:49:27 +01:00
shortcutme
77530f13ee
Fix content.json update and verify on Python 3.5 2019-03-20 00:48:51 +01:00
shortcutme
0a1c22530a
More clear paramter name for verify 2019-03-20 00:48:09 +01:00
shortcutme
e6c0fe0370
OpenSSL config file to lib dir 2019-03-20 00:47:43 +01:00
shortcutme
63ba0a5551
Fix tests on Python 3.5 2019-03-20 00:46:57 +01:00
shortcutme
c7bfe0d537
Fix Upnp test 2019-03-20 00:46:16 +01:00
shortcutme
05887c976a
Test on Python 3.5 using travis, temporary disable docker build until stable release 2019-03-19 17:02:39 +01:00
ZeroNet
ccc8fda24f
Merge pull request #1926 from 0polar/patch-4
Fix unable to open context menu on Windows
2019-03-19 16:42:21 +01:00
ZeroNet
abb458bdd3
Merge pull request #1925 from 0polar/patch-1
Fix "no module" error
2019-03-19 16:41:48 +01:00
ZeroNet
41429dd254
Merge pull request #1922 from 0polar/patch-2
Fix wrong module name
2019-03-19 16:41:05 +01:00
ZeroNet
268a39e93b
Merge pull request #1923 from 0polar/patch-3
pip install in right way
2019-03-19 16:40:39 +01:00
0polar
8411c60d4a
Fix unable to open context menu on Windows
Python3 string no need decoding or encoding
2019-03-19 20:56:30 +08:00
0polar
de91f7ec15
Fix "no module" error
Since added into pip requirements.txt, no need to `from...`
2019-03-19 20:36:26 +08:00
0polar
6094af819b
Update requirements.txt 2019-03-19 20:15:55 +08:00
0polar
5f21563d7d
Update README.md 2019-03-19 20:11:01 +08:00
0polar
5b9afe70b2
pip install in right way 2019-03-19 20:00:30 +08:00
0polar
27f47460e3
Fix wrong module name
Exception: You probably meant to install and run gevent-websocket
2019-03-19 19:59:12 +08:00
shortcutme
ad1bd045f7
Rev4011 2019-03-18 03:38:11 +01:00
shortcutme
9a9a8bfdc7
Fix peer loading 2019-03-18 03:37:05 +01:00
shortcutme
c88152cac2
Use shared cursor where possible 2019-03-18 03:36:44 +01:00
shortcutme
61c72ac3ea
Fix SQLite concurrency errors 2019-03-18 03:36:12 +01:00
shortcutme
84c39f3baa
Less sensitive db progress handler 2019-03-18 03:33:51 +01:00
shortcutme
7d6ef195fd
Don't allow to run db on different thread 2019-03-18 03:33:28 +01:00
shortcutme
52ac972332
Keep need commit status if commit failed 2019-03-18 03:33:06 +01:00
shortcutme
9aa599f9d2
Close and commit all db at exit 2019-03-18 03:32:42 +01:00
shortcutme
a5ce7e5a1f
Rev4006 2019-03-18 01:08:35 +01:00
shortcutme
f8511bf199
Display error if try to start with Python2 2019-03-18 01:08:20 +01:00
shortcutme
cfdc6bac7b
Remove test lock files after test 2019-03-18 01:08:02 +01:00
shortcutme
33e4c088b9
Upnp opening function return success value 2019-03-18 01:07:46 +01:00
shortcutme
a620bf2174
Fix lang html variable on config page 2019-03-18 01:06:45 +01:00
shortcutme
e77d63294e
Fix config page 2019-03-18 01:06:04 +01:00
shortcutme
82c55ba038
Rev4003, Fix peer sorting if no ping delay yet 2019-03-16 04:57:59 +01:00
shortcutme
e1394d7a7d
Fix socks package name 2019-03-16 04:48:56 +01:00
shortcutme
9f99fa8edc
Remove not working tracker 2019-03-16 04:26:59 +01:00
shortcutme
02e67a901f
Import global maxminddb module 2019-03-16 04:26:27 +01:00
shortcutme
f331f5e92c
Add maxminddb as requirement 2019-03-16 04:26:13 +01:00
shortcutme
6e5bf5fef6
Decode masgpack hash key values as byte 2019-03-16 04:22:49 +01:00
shortcutme
c7b4e28f82
Version 0.7.0, Rev4001 2019-03-16 03:53:37 +01:00
shortcutme
9235ecfe7b
Add warning, installation method to readme 2019-03-16 03:53:22 +01:00
shortcutme
7f234721ec
Add required modules 2019-03-16 03:48:58 +01:00
shortcutme
242b3edbc4
Fix BigFilePiecefiled typo 2019-03-16 03:44:13 +01:00
shortcutme
b7894faa96
Fix AnnounceShare backward compatibility 2019-03-16 03:44:01 +01:00
shortcutme
f3a4b9c709
Fix announce py3 compatibility 2019-03-16 03:43:11 +01:00
shortcutme
ea638dd0e0
Fix Noparallel test on slower machines 2019-03-16 03:02:59 +01:00
shortcutme
f0b53c4cbb
Add bundled pybitcointools 2019-03-16 03:01:50 +01:00
shortcutme
3eae349a0a
Remove included win_inet_pton, websocket, rsa, socks, pyelliptic, pybitcointools, pyasn1, opensslVerify, merkletools, geventwebsocket, BitcoinECC, bencode module 2019-03-16 02:58:49 +01:00
shortcutme
ff5004cb8d
Remove included maxminddb 2019-03-16 02:52:12 +01:00
shortcutme
567855e2d2
TestHelper formatting 2019-03-16 02:49:41 +01:00
shortcutme
d20da5d803
1ms is the minimum sleep with new gevent 2019-03-16 02:46:33 +01:00
shortcutme
b98a9d2e80
Commit before vacuum 2019-03-16 02:45:37 +01:00
shortcutme
955164aa3c
New configuration option to use libsecp256k1 for speedup 2019-03-16 02:45:06 +01:00
shortcutme
db8f9988eb
Use log extension for rolled log file names 2019-03-16 02:44:22 +01:00
shortcutme
9b2cae8e33
Don't log geventwebsocket module debug messages 2019-03-16 02:43:45 +01:00
shortcutme
ac325c5c5e
Py3 compatibility of FileRequest module 2019-03-16 02:43:07 +01:00
shortcutme
e92f3ea100
New watchdog module based file change watching 2019-03-16 02:42:43 +01:00
shortcutme
75d8338f2d
Debug stack formatting include module names 2019-03-16 02:41:09 +01:00
shortcutme
a1b5dad1c8
New Db connection type to avoid corruption 2019-03-16 02:40:32 +01:00
shortcutme
0e2f7fb122
Use global rsa module 2019-03-16 02:39:11 +01:00
shortcutme
ee631730c7
Remove sha1 sum function 2019-03-16 02:38:47 +01:00
shortcutme
f7fd445c73
Test sha sum parameter type properly 2019-03-16 02:38:38 +01:00
shortcutme
5c0fc38272
Remove not used ECC cert generation 2019-03-16 02:37:48 +01:00
shortcutme
6df0321962
Py3 compatibilty of CryptConnection module 2019-03-16 02:37:38 +01:00
shortcutme
65d19d350c
We don't support old style sign verification anymore 2019-03-16 02:36:45 +01:00
shortcutme
bc93796727
Add faster libsecp256k1 support for sign verification, Remove old style signing support, 2019-03-16 02:36:11 +01:00
shortcutme
6f0531c663
Test CryptMessage ui_websocket result more reliable way 2019-03-16 02:33:38 +01:00
shortcutme
545acebbaf
New CryptMessage test functions for ecies crypto 2019-03-16 02:33:09 +01:00
shortcutme
af49404320
Remove support of old request type 2019-03-16 02:32:10 +01:00
shortcutme
717802860d
Create new unpacker object if client sending new-style, bin-type compatible msgpack streams 2019-03-16 02:31:49 +01:00
shortcutme
edd3f35790
Use new Msgpack library for unpacking 2019-03-16 02:30:54 +01:00
shortcutme
20806a8c97
ZeroName plugin Py3 compatibility 2019-03-16 02:27:26 +01:00
shortcutme
f071cc5c04
Make Stats page Py3 compatible, Add libsecp256k1 testing, Xy packing format, Reduce code duplication 2019-03-16 02:27:04 +01:00
shortcutme
90c9078bf5
Remove unnecessary logging of Sidebar loadGlobe 2019-03-16 02:25:20 +01:00
shortcutme
203e70afbc
Py3 compatibility of PeerDb plugin 2019-03-16 02:24:36 +01:00
shortcutme
2599e54fd0
Py3 compatibility of FilePack plugin 2019-03-16 02:24:17 +01:00
shortcutme
2737425242
Py3 compatibility of UiPassword plugin 2019-03-16 02:23:46 +01:00
shortcutme
40569eee2e
Py3 compatibility of CryptMessage plugin, Rename ecies crypto function names to make it more clear 2019-03-16 02:23:00 +01:00
shortcutme
883c2851ff
Py3 compatibility of ContentFilter plugin 2019-03-16 02:20:32 +01:00
shortcutme
4fe4d0a7e7
BEGIN / END no longer necessary as there is no autocommit in new db module 2019-03-16 02:18:53 +01:00
shortcutme
a46d8fe7f3
Hash id of the hashmap changed because of use_bin_type msgpack packing 2019-03-16 02:15:37 +01:00
shortcutme
dd70d27a0e
Use new Msgpack modue for testing Bigfile plugin 2019-03-16 02:14:43 +01:00
shortcutme
b46ee0c495
Use Msgpack module in Bigfile plugin 2019-03-16 02:14:08 +01:00
shortcutme
28ffb3fd18
Ignore sha3 warning of merkletools module 2019-03-16 02:13:17 +01:00
shortcutme
d1456850d1
Py3 compatibility in Bigfile piecefield 2019-03-16 02:12:45 +01:00
shortcutme
050e2febab
Log add types with zero announce request 2019-03-16 02:12:03 +01:00
shortcutme
f56c8ef755
Save shared trackers files as utf8 2019-03-16 02:11:38 +01:00
shortcutme
1a9529157f
Backward compatibility with tracker sharing response 2019-03-16 02:11:22 +01:00
shortcutme
8c5c3cb7a6
Use Msgpack module in BroadcastServer plugin 2019-03-16 02:09:27 +01:00
shortcutme
8ab9b06185
Subtl module py3 compatibility 2019-03-16 02:06:28 +01:00
shortcutme
91c5556f21
Remove old gevent compatibility patches 2019-03-16 02:05:27 +01:00
shortcutme
95cf47d9a4
Test site download with all avaliable crypto lib 2019-03-16 01:01:30 +01:00
shortcutme
dfad2370aa
Test file locking 2019-03-16 01:01:06 +01:00
shortcutme
331e25cc41
Test content rules with all avaliable crypto lib 2019-03-16 01:00:49 +01:00
shortcutme
6dcf7e8088
Remove testing of old signature 2019-03-16 01:00:21 +01:00
shortcutme
99690a6145
Test longer string signing 2019-03-16 00:59:27 +01:00
shortcutme
27bcc3c685
Test sign and verify with all crypto lib avaliable 2019-03-16 00:59:11 +01:00
shortcutme
bb60558968
Test hashing functions 2019-03-16 00:57:50 +01:00
shortcutme
af38a3927a
Test utf8 diffing 2019-03-16 00:57:03 +01:00
shortcutme
bf6771152e
Test backward compatibility to py2 byte-less msgpack unpacker 2019-03-16 00:56:50 +01:00
shortcutme
48b6c81b36
Test msgpack streaming with binary data 2019-03-16 00:56:25 +01:00
shortcutme
d95da7372a
Feed Msgpack unpacker as byte 2019-03-16 00:54:27 +01:00
shortcutme
231037b0fe
Test Msgpack result 2019-03-16 00:54:12 +01:00
shortcutme
c481d20ce8
Use new libs in Msgpack tests 2019-03-16 00:54:00 +01:00
shortcutme
dc32556983
Add utf8 and binary data to msgpack test vector 2019-03-16 00:53:18 +01:00
shortcutme
d7b43f4722
Same priority file download order does not matter 2019-03-16 00:51:32 +01:00
shortcutme
ca29fcec7d
findHashId order does not matter 2019-03-16 00:50:25 +01:00
shortcutme
bd637d661a
Test translate of utf8 strings 2019-03-16 00:49:09 +01:00
shortcutme
ef8174af70
All problematic characters will be escaped 2019-03-16 00:48:56 +01:00
shortcutme
dee562437b
Rename hashfield pack functions to bytes 2019-03-16 00:42:21 +01:00
shortcutme
a1a4a73260
Save sites.json as utf8 2019-03-16 00:41:26 +01:00
shortcutme
627edeb0f2
Py3 support in announce requests 2019-03-16 00:33:12 +01:00
shortcutme
16f29b65f2
Use if in protocol port detection 2019-03-16 00:32:50 +01:00
shortcutme
6d2a863af5
Sleep a bit before creating new file_server to allow connection closing 2019-03-16 00:15:43 +01:00
shortcutme
35e61a0c69
More reliable UiWebsocket testing 2019-03-16 00:15:19 +01:00
shortcutme
c474699695
Different crypto lib fixture 2019-03-16 00:14:58 +01:00
shortcutme
1e2dadf75e
Log test to log/cmd.log 2019-03-16 00:14:11 +01:00
shortcutme
002303a765
Db rebuilding error display, reconnect bug fix 2019-03-16 00:11:52 +01:00
shortcutme
59426c31f7
SiteStorage Py3 compatibility 2019-03-16 00:10:49 +01:00
shortcutme
fd895d0ef5
Tormanager only disconnect if connected 2019-03-16 00:08:04 +01:00
shortcutme
8220272953
Py3 encoding support in TorManager 2019-03-16 00:05:23 +01:00
shortcutme
c8fc1ebefa
Remove tor downloading for windows 2019-03-16 00:04:09 +01:00
shortcutme
ac9531eb98
Use global socks module 2019-03-16 00:03:05 +01:00
shortcutme
56d68ce161
Open translate language file as utf8 2019-03-16 00:02:13 +01:00
shortcutme
a3ef3b34e1
Support multi-line notification 2019-03-16 00:01:52 +01:00
shortcutme
30e348f965
Remove empty line from wrapper template 2019-03-16 00:01:15 +01:00
shortcutme
b981ddadca
Encode error repose to bytes 2019-03-16 00:00:35 +01:00
shortcutme
bcd721e2ef
Always display title if there is content.json file 2019-03-16 00:00:04 +01:00
shortcutme
a96ff8399f
Open template as utf8 file 2019-03-15 23:59:30 +01:00
shortcutme
2f4dec45a6
Decode path as utf8 2019-03-15 23:58:18 +01:00
shortcutme
b216e42397
Fix modified files checking 2019-03-15 23:57:30 +01:00
shortcutme
9b6c624554
Allow cloning if content.json update fails 2019-03-15 23:57:06 +01:00
shortcutme
12154613c2
Write use file as binary 2019-03-15 23:56:16 +01:00
shortcutme
a42dee5a44
unpackOnionAddress Py3 support 2019-03-15 23:55:40 +01:00
shortcutme
d4d86172f0
Cmp function backport and Utf8 to Byte response decorator helper funcations 2019-03-15 23:55:23 +01:00
shortcutme
a49f454826
Lock files in binary mode, with one byte 2019-03-15 23:53:48 +01:00
shortcutme
cd9a965057
atomicWrite Py3 support, full stack logging 2019-03-15 23:50:33 +01:00
shortcutme
f5bc26e9fe
Use binary format for atomicWrite 2019-03-15 23:49:55 +01:00
shortcutme
c55d69d587
Python3 has builtin inet_pton support 2019-03-15 23:49:13 +01:00
shortcutme
e508357cfb
RateLimit py3 support 2019-03-15 23:48:46 +01:00
shortcutme
1c578b2b3f
Remove SSL patches for old Python/Gevent support, patch ctypes find_library to find openssl libs 2019-03-15 23:48:28 +01:00
shortcutme
4ce2ef732d
Rename StreamingMsgpack to Msgpack, add helpers 2019-03-15 23:33:04 +01:00
shortcutme
65705aba10
Fix UpnpPunch py3 compatibility 2019-03-15 23:32:05 +01:00
shortcutme
e97873fb7e
UpnpPunch gets custom logger 2019-03-15 23:31:13 +01:00
shortcutme
13d1df3cef
Only log worker download status if small ammount of task present 2019-03-15 23:30:34 +01:00
shortcutme
7ffb7db888
Add task statistics logging every 15sec 2019-03-15 23:29:04 +01:00
shortcutme
74366379ba
Only log added task in verbose mode 2019-03-15 23:26:33 +01:00
shortcutme
6b89d05a3c
Disable update 2019-03-15 23:10:29 +01:00
shortcutme
b0b9a4d33c
Change to Python3 coding style 2019-03-15 21:06:59 +01:00
shortcutme
fc0fe0557b
Ignore *.bak files 2019-03-15 18:47:31 +01:00
ZeroNet
116347ef66
Merge pull request #1921 from rllola/tracker-announcer
If no port defined in tracker url assume it is port 80
2019-03-10 23:42:07 +01:00
rllola
58516913b4 if protocol https choose port 443 2019-03-10 22:19:37 +01:00
rllola
fb836fcf6f If no port defined in tracker url assume it is port 80; fix #1917 2019-03-09 18:41:50 +01:00
ZeroNet
1ad44ace0a
Merge pull request #1916 from rllola/ld-library-path-openssl
Ld library path openssl
2019-03-06 16:05:54 +01:00
rllola
32ddaed376 Actually at ALL the path in the environnement variable and look for the openssl lib 2019-03-05 18:58:47 +01:00
rllola
4e388e5dc2 Find openssl lib in LD_LIBRARY_PATH 2019-03-05 18:33:29 +01:00
shortcutme
44c467f472
Merge branch 'master' of https://github.com/HelloZeroNet/ZeroNet 2019-02-24 02:29:42 +01:00
shortcutme
f90d0d2dae
Rev3853 2019-02-24 02:29:35 +01:00
shortcutme
b47920169f
Test unsupported pex peers removing 2019-02-24 02:29:27 +01:00
shortcutme
81bf349871
Remove ipv6 and onion from pex result if not supported 2019-02-24 02:29:08 +01:00
shortcutme
9d849a16ec
Use defaultdict to for findHashId result 2019-02-24 02:28:42 +01:00
ZeroNet
383749a9c0
Merge pull request #1911 from rllola/zeroname-fix-waitforblock
Zeroname fix waitforblock
2019-02-21 16:55:49 +01:00
rllola
5e2feb5803 Fix the second cal to getinfo/getblockchaininfo; Verify version before doing the call. 2019-02-21 16:10:42 +01:00
rllola
93645681b0 Use waitfornewblock if namecoin version 16.0 or higher 2019-02-21 14:39:58 +01:00
shortcutme
174e8d3c19
Rev3852 2019-02-16 23:49:20 +01:00
shortcutme
511a5c0d1f
Nonce based CSP not supported in Safari yet 2019-02-16 23:49:10 +01:00
shortcutme
c92c840c41
Make sigterm listen optional (fixes macOS problem) 2019-02-16 23:48:18 +01:00
shortcutme
952a1a1da8
Rev3851, Fix typo with onion address detection 2019-02-16 20:50:49 +01:00
ZeroNet
e89cb4cc0e
Merge pull request #1901 from anoadragon453/patch-3
Fix typo
2019-02-16 20:28:37 +01:00
ZeroNet
89cc70091c
Merge pull request #1900 from anoadragon453/patch-2
Remove unnecessary str replace
2019-02-16 20:28:22 +01:00
ZeroNet
cfaa2c542d
Merge pull request #1896 from rllola/zeroname-namecoin-version
Zeroname plugin improvement
2019-02-16 20:27:38 +01:00
Andrew Morgan
c6bbe9e020
Fix typo 2019-02-15 21:22:13 +00:00
Andrew Morgan
15d2fd4581
Remove unnecessary str replace
Presumably left over from before it got moved out into a script.
2019-02-15 21:19:29 +00:00
shortcutme
819c2b0bc3
Rev3850 2019-02-14 15:52:30 +01:00
shortcutme
30984c62fa
Change trackers to more reliable ones 2019-02-14 15:52:22 +01:00
shortcutme
bd649cfb33
Remove ui_server allowed http host learning 2019-02-14 15:49:10 +01:00
shortcutme
5c57cd6541
Support https trackers, add browser-like user agent for tracker http requests 2019-02-14 15:48:36 +01:00
rllola
02e2080ce2 Added test for new standard; Check version for compatibility with namecoin newer version; update README 2019-02-12 23:06:21 +01:00
rllola
c00601743c Added README for zeroname plugin with instructions 2019-02-12 22:09:47 +01:00
shortcutme
523f8dae2a
Rev3846 2019-02-09 13:57:08 +01:00
shortcutme
4e56fe9fc3
Fix sitePublish CLI command if no client is running 2019-02-09 13:56:44 +01:00
shortcutme
2829146598
Merge wrapper js, css 2019-02-09 13:56:21 +01:00
shortcutme
b5ed158cc6
Fix closed display of infopanel if sidebar opened 2019-02-09 13:56:12 +01:00
shortcutme
7314f20563
Set number of changed files for closed infopanel 2019-02-09 13:55:53 +01:00
shortcutme
0559eb1a9a
Rev3844 2019-02-05 15:55:23 +01:00
shortcutme
40f732cd48
Only show modified files notification if site is owned 2019-02-05 15:55:12 +01:00
shortcutme
eb837e3685
Close button for site modified files notification 2019-02-05 15:54:32 +01:00
shortcutme
8ddfbf37c3
New siteSetSettingsValue to change site specific setting 2019-02-05 15:52:01 +01:00
shortcutme
0729ea1c38
Version 0.6.5, Rev3840 2019-02-02 00:13:09 +01:00
shortcutme
39541fe348
Modified site source admin panel 2019-02-02 00:12:50 +01:00
shortcutme
259c5199d6
siteListModifiedFiles admin command 2019-02-02 00:11:47 +01:00
shortcutme
af0b563036
Remove unnecessary character 2019-02-02 00:11:02 +01:00
shortcutme
c2b879ccab
Rev3831, Fix Stats page compatibility with latest gevent 2019-01-31 00:39:45 +01:00
shortcutme
8447c6d79f
Rev3829 2019-01-30 14:58:20 +01:00
shortcutme
46fb61c68c
Consider port opened if we have external ip on the interface 2019-01-30 14:58:11 +01:00
shortcutme
860ef650f9
Support IPv6 in Tor always mode by creating ipv4 sockets with ipv6 address 2019-01-30 14:53:33 +01:00
shortcutme
ef6f9b9d70
Don't try to open ports in Tor mode 2019-01-30 14:52:41 +01:00
shortcutme
9f701c8f35
IPv6 supported in tor mode 2019-01-30 14:52:26 +01:00
shortcutme
e18d3d0c93
Only return valid ips from getInterfaceIps 2019-01-30 14:51:45 +01:00
blurHY
dd46a64e79 Fix atexit not working on SIGTERM (#1882) 2019-01-30 14:47:16 +01:00
shortcutme
31a7effa5f
Rev3827, Share FileServer between sites for non-main CLI commands 2019-01-29 03:17:24 +01:00
shortcutme
42f3f405ea
Rev3826 2019-01-29 03:04:06 +01:00
shortcutme
1b612f7112
Check master seed length for cryptGetPrivatekey CLI command 2019-01-29 03:03:42 +01:00
shortcutme
6e364ce4b9
Wait until site sync finished before cloning 2019-01-29 03:02:57 +01:00
shortcutme
89eb44f3ef
Spawn port check on separate thread when changing ip_external config value 2019-01-29 03:02:22 +01:00
shortcutme
53364d6ddc
Add 169.254.* to local ips, remove unnecessary brackets 2019-01-29 03:00:06 +01:00
shortcutme
4631f2223b
Add public ips from local adapters to external ip list 2019-01-29 02:59:15 +01:00
shortcutme
20fb9ab97d
Only reload source code on create and change event 2019-01-29 02:57:41 +01:00
shortcutme
dcbac42571
Change unstable tracker 2019-01-29 02:57:18 +01:00
shortcutme
0258d926a2
Fix loading multi-line values from config 2019-01-29 02:54:56 +01:00
shortcutme
e79e60f0bb
Fix change detection for textareas in Config page 2019-01-29 02:54:30 +01:00
shortcutme
ef0c0b1e32
Rev3821 2019-01-26 20:43:04 +01:00
shortcutme
14631c65a6
Avoid user creaton when rendering sidebar after site deletion 2019-01-26 20:42:46 +01:00
shortcutme
f706f7508e
Store detected external ips to separate variable 2019-01-26 20:42:27 +01:00
shortcutme
6662b4f047
Test sql queries with lots of variables 2019-01-26 20:40:58 +01:00
shortcutme
13c453d610
Embed query values if more than 100 specified 2019-01-26 20:40:34 +01:00
shortcutme
e8026ef074
Non-private external ip for tests 2019-01-26 20:39:31 +01:00
shortcutme
cefc6f8eac
Test private ip match 2019-01-26 20:38:30 +01:00
shortcutme
bf809ac118
Save users.json immedietly after site creation 2019-01-26 20:31:37 +01:00
shortcutme
88ba0c1154
Don't detect cjdns ips as private ips 2019-01-26 20:31:05 +01:00
shortcutme
43d2d5334a
Merge branch 'master' of https://github.com/HelloZeroNet/ZeroNet 2019-01-26 03:14:03 +01:00
shortcutme
de41efbaf8
Rev3818, Fix peerPing cli command 2019-01-26 03:13:47 +01:00
ZeroNet
81419ca68b
Merge pull request #1879 from tangdou1/patch-1
Update zh.json
2019-01-25 23:34:49 +01:00
shortcutme
276cbc0ace
Rev3817, Support limits for feed search 2019-01-25 14:26:38 +01:00
tangdou1
6ada5110a4
Update zh.json 2019-01-25 15:04:43 +08:00
tangdou1
f6ee45249d
Update zh.json 2019-01-25 14:50:05 +08:00
shortcutme
be36a20249
Rev3815 2019-01-25 01:26:50 +01:00
shortcutme
5173597868
Remove empty lines from multi-line config values 2019-01-25 01:26:39 +01:00
shortcutme
86657529c9
Live update ip_external 2019-01-25 01:24:28 +01:00
shortcutme
6460b7b0a1
Parse ip_external on portCheck function call 2019-01-25 01:23:46 +01:00
shortcutme
3b91be8449
Change ip_external on Config page 2019-01-25 01:22:26 +01:00
ZeroNet
055aea58bb
Merge pull request #1877 from d14na/patch-1
Add support for tilde `~` in filenames.
2019-01-24 15:54:07 +01:00
shortcutme
1914c69c47
Rev3812 2019-01-24 15:20:56 +01:00
shortcutme
fdb06ad973
Cleaner way to record external ips from port checkers 2019-01-24 15:20:37 +01:00
shortcutme
37979b4f9c
Support multiple external ips 2019-01-24 15:20:08 +01:00
shortcutme
0a03c30e8a
findHashId will return real address used by the connection 2019-01-24 15:19:19 +01:00
shortcutme
e8dbf1511b
More clean way to return locally found hash_ids for findHashId 2019-01-24 15:18:12 +01:00
D14na
f163abb4a5
Add support for tilde ~ in filenames.
(source: https://webpack.js.org/guides/code-splitting)

It appears that webpack (bundled w/ the VueJS CLI) will concatenate `chunk` names using the `~` to create one long "bundled" filename. This creates a problem when executing `isValidRelativePath` which DOES NOT allow `~`.

__An example error when signing:__
`Site:1... - [ERROR] Invalid filename: js/about~privacy~search.3c7ce85b.js`

A fix is to use the same name for each file/chunk, but then that breaks the optimizations of code splitting. Is there any reason NOT to permit tilde `~` as a valid filename character? _(NOTE: this may only be an issue if using vue-router)_
2019-01-24 08:41:27 -05:00
ZeroNet
fa99f3dbbe
Merge pull request #1876 from tangdou1/patch-1
Fix a bug
2019-01-24 11:48:10 +01:00
tangdou1
76e21a6378
Fix a bug 2019-01-24 10:00:18 +08:00
ZeroNet
0d3c403f08
Merge pull request #1873 from goofy-mdn/patch-1
Update fr.json
2019-01-23 16:12:17 +01:00
goofy-mdn
7c6ff85acd
Update fr.json
minor typofix
2019-01-23 15:44:14 +01:00
shortcutme
4d60c61512
Rev3808, Use cjdns compatible ipv6 address to test route 2019-01-23 14:21:25 +01:00
ZeroNet
31376ee2fd
Merge pull request #1870 from tangdou1/patch-1
Update all.js
2019-01-23 12:55:37 +01:00
ZeroNet
b067bbd935
Merge pull request #1871 from tangdou1/patch-2
Update zh.json
2019-01-23 12:54:37 +01:00
tangdou1
f980170a82
Update zh.json 2019-01-23 19:05:29 +08:00
tangdou1
8b7ef14f65
Update all.js 2019-01-23 19:00:19 +08:00
ZeroNet
5eb8549aef
Merge pull request #1869 from tangdou1/patch-1
Update all.js
2019-01-23 10:57:06 +01:00
tangdou1
728b76aa7e
Update all.js 2019-01-23 17:24:21 +08:00
shortcutme
c20ed92fab
Merge branch 'master' of https://github.com/HelloZeroNet/ZeroNet 2019-01-23 02:19:08 +01:00
shortcutme
13f6a8da53
Rev3807 2019-01-23 02:19:04 +01:00
shortcutme
28426f3ee3
Fix ip_mode description 2019-01-23 02:18:31 +01:00
shortcutme
fb925745ba
Make notification compatible with latest noscript 2019-01-23 02:15:23 +01:00
shortcutme
271cb66c69
Fix port re-check 2019-01-23 02:14:31 +01:00
shortcutme
b3f2812191
Add ip network support to stats page 2019-01-23 02:13:29 +01:00
shortcutme
1824363f86
Support dual stack listening 2019-01-23 02:13:13 +01:00
shortcutme
439d2bcf7f
Remove unused setIpExternal funtcion 2019-01-23 02:11:59 +01:00
shortcutme
447f5fd5c8
Store opened port status per IP version 2019-01-23 02:11:31 +01:00
shortcutme
ce78e330d3
Async serverPortcheck ZeroFrame API call 2019-01-23 02:07:11 +01:00
tangdou1
7a47d58ad4 Update zh.json for more respect (#1867)
* Update zh.json

* Update zh.json

* Update zh.json
2019-01-22 11:00:17 +01:00
ZeroNet
e9f467ed77
Merge pull request #1864 from tangdou1/patch-2
Fix a small bug
2019-01-21 14:01:25 +01:00
tangdou1
aedfb1d8da Update zh.json (#1863)
* Update zh.json

* Update zh.json
2019-01-21 14:01:04 +01:00
tangdou1
0ab424c0d2 Update the source of translation (#1865)
* Update zh.json

* Update zh-tw.json

* Update tr.json

* Update sl.json

* Update sk.json

* Update ru.json

* Update pt-br.json

* Update pl.json

* Update nl.json

* Update it.json

* Update hu.json

* Update fr.json

* Update es.json

* Update de.json

* Update da.json

* Update zh.json

* Update zh-tw.json

* Update tr.json

* Update sl.json

* Update sk.json

* Update ru.json

* Update pt-br.json

* Update pl.json

* Update nl.json

* Update it.json

* Update hu.json

* Update fr.json

* Update es.json

* Update de.json

* Update da.json
2019-01-21 14:00:44 +01:00
tangdou1
674b1efa0f
Fix a bug
there is no portCheck function
2019-01-21 10:46:06 +08:00
shortcutme
a7509988af
Rev3802, Fix pytest warnings 2019-01-20 20:02:31 +01:00
shortcutme
f58f738fe4
Rev3801 2019-01-20 19:16:56 +01:00
shortcutme
ba9228b142
Is downloading status based on bad_files 2019-01-20 19:15:21 +01:00
shortcutme
0beef302c6
Ipv6 compatibility in AnnounceZero plugin 2019-01-20 19:13:00 +01:00
shortcutme
da538f6424
AnnounceShare compatibility with refactored port checker 2019-01-20 19:12:11 +01:00
shortcutme
8384c2cba3
Ipv6 compatible AnnounceShare test 2019-01-20 19:11:15 +01:00
shortcutme
fbf430fac9
Ipv6 compatible bigfile test 2019-01-20 19:10:52 +01:00
shortcutme
29516304b0
Reset cert data before running crypt test 2019-01-20 19:10:40 +01:00
shortcutme
c853de4315
Ipv6 tracker 2019-01-20 19:08:49 +01:00
shortcutme
e2d17fe20f
Ipv6 test of address packing and unpacking 2019-01-20 19:08:15 +01:00
shortcutme
9e5be7ffcf
Fix noparallel test on slow cpu 2019-01-20 19:07:48 +01:00
shortcutme
44dc3035a5
Make network test compatible with ipv6 2019-01-20 19:07:16 +01:00
shortcutme
468666cdc8
Optimize getOnion function with less lock 2019-01-20 16:51:42 +01:00
shortcutme
00972f5d73
Fix stuck starting when tor client is already running 2019-01-20 16:51:13 +01:00
shortcutme
bffe6e7a32
Tor service ipv6 support 2019-01-20 16:50:55 +01:00
shortcutme
cc3bb912be
Ipv6 support for adding peers by query string 2019-01-20 16:49:52 +01:00
shortcutme
9a64b6080d
Formatting 2019-01-20 16:31:41 +01:00
shortcutme
42156edc76
Opened ipv6 port support for tracker request 2019-01-20 16:31:30 +01:00
shortcutme
7ae98477d5
Separate function for parsing tracker addresses 2019-01-20 16:29:38 +01:00
shortcutme
626b6f5ccd
Formatting 2019-01-20 16:28:47 +01:00
shortcutme
9c82de7df2
Ipv6 support of opened services 2019-01-20 16:28:42 +01:00
shortcutme
e7de562b93
Don't request ipv6 trackers if not supported by the client 2019-01-20 16:27:59 +01:00
shortcutme
06d679d1ca
Support ipv6 in findHashIds response parsing 2019-01-20 16:27:12 +01:00
shortcutme
33cf30a07b
Formatting 2019-01-20 16:26:17 +01:00
shortcutme
6ac1960c47
Support ipv6 for Pex request parsing 2019-01-20 16:26:04 +01:00
shortcutme
1350096545
Support ipv6 for Checkport request 2019-01-20 16:23:53 +01:00
shortcutme
18b9df62e4
Support ipv6 in findHashIds request 2019-01-20 16:23:37 +01:00
shortcutme
42495a9914
Support ipv6 in Pex request 2019-01-20 16:22:32 +01:00
shortcutme
b2f25d7f0a
Store if there was an incoming connection for port open checker 2019-01-20 16:20:41 +01:00
shortcutme
30b71328b9
Turn ipv6 representation of ipv4 addresses to simple ips for incoming connections 2019-01-20 16:20:01 +01:00
shortcutme
7c97e37dc3
Support ipv6 binding for connection server 2019-01-20 16:19:14 +01:00
shortcutme
f42d088fbc
Log supported ip types when binding 2019-01-20 16:18:48 +01:00
shortcutme
a5e63de016
Check if there is ipv6 support in user's system 2019-01-20 16:18:24 +01:00
shortcutme
f7d3718457
Set ConnectionServer default ip for tests based on ip_type 2019-01-20 16:16:55 +01:00
shortcutme
3fa0f1b9e8
Don't correct local time with p2p timecorrection value 2019-01-20 16:15:47 +01:00
shortcutme
f1a54bd7d0
Set strict timeout for connection handshake 2019-01-20 16:15:32 +01:00
shortcutme
1803e47c02
Support creating ipv6 connections 2019-01-20 16:15:07 +01:00
shortcutme
296e44deec
Store ip_type in Connection variable 2019-01-20 16:14:00 +01:00
shortcutme
c546065611
Peerdb ipv6 loading 2019-01-20 16:11:56 +01:00
shortcutme
7e759e6ae8
Ipv6/ipv4 compatible bootstrapper tests 2019-01-20 16:11:08 +01:00
shortcutme
a9608c096e
New bootstrapper tests announce and backward compatibility 2019-01-20 16:10:24 +01:00
shortcutme
4db723fa6f
New bootstraper db format with ipv6 support 2019-01-20 16:08:51 +01:00
shortcutme
64e8efbc07
Fix ipv6 address placing to sidebar map 2019-01-20 03:28:49 +01:00
shortcutme
15f4bc5bd6
Add filesrver_ip_type to config page 2019-01-20 03:28:22 +01:00
shortcutme
ce6668ef8c
Avoid adding supported crypto multiple times 2019-01-20 03:27:44 +01:00
shortcutme
f60ab3e01f
Add local ipv6 address 2019-01-20 03:26:45 +01:00
shortcutme
78a7aa91c0
Add ipv6 address to blacklist 2019-01-20 03:26:12 +01:00
shortcutme
a574f3d173
Fix get settings of not visited site 2019-01-20 03:22:17 +01:00
shortcutme
c9223686d2
Formatting helper 2019-01-20 03:21:38 +01:00
shortcutme
c86afe29ba
GetIpType and createSocket helper functions 2019-01-20 03:21:27 +01:00
shortcutme
0c56a7a23b
Support ipv6 address packing/unpacking 2019-01-20 03:21:07 +01:00
shortcutme
b66676de85
Support absolute path and {data_dir} variable for trackers_file 2019-01-20 03:16:37 +01:00
shortcutme
c7a468eb14
Bind file server to ipv6 interfaces according to fileserver_ip_type config value 2019-01-20 03:15:21 +01:00
shortcutme
1c5b5e3621
Move port checking to separate file, add ipv6 port check 2019-01-20 03:13:54 +01:00
shortcutme
d78c757b52
Automatically run all file_server tests in ipv4 and ipv6 enviroment 2019-01-20 03:11:33 +01:00
shortcutme
9871a4e36f
Fix test gevent monkey patching 2019-01-20 03:10:39 +01:00
shortcutme
3e82595193
Store site download time 2019-01-20 03:10:07 +01:00
shortcutme
044456cd98
Add win_inet_pton package for missing socket functions 2019-01-20 03:09:46 +01:00
shortcutme
c0ba724578
Enable ipv6 for testing 2019-01-20 03:08:34 +01:00
ZeroNet
79daa12b06
Merge pull request #1847 from BoboTiG/fix-invalid-seq-warnings
Fix DeprecationWarning: invalid escape sequence
2019-01-20 01:51:27 +01:00
Lola Dam
1f1e6006ec Support namecoin standard 'map' for subdomain name (#1856)
* Support namecoin standard 'map' for subdomain name

* Proper naming for variables

*  naming fix and added one case for namecoin standard
2019-01-15 16:25:33 +01:00
shortcutme
8ee8acf655
Rev3750, Allow log_level changes 2019-01-10 14:11:46 +01:00
shortcutme
5e928769ec
Add log level to config page 2019-01-10 14:11:30 +01:00
shortcutme
a0b60a8347
Apply log level changes 2019-01-10 14:10:07 +01:00
shortcutme
dbe2a7b240
Fix QueryJson on non-list nodes 2019-01-10 14:09:50 +01:00
Mickaël Schoentgen
e8298726ca Fix DeprecationWarning: invalid escape sequence
Signed-off-by: Mickaël Schoentgen <contact@tiger-222.fr>
2019-01-06 15:15:47 +01:00
shortcutme
4c675b8311
Rev3748, Fix content filter for non existing domains 2019-01-05 19:07:27 +01:00
shortcutme
1ab9bc40a5
Rev3747. Dont show tor meek proxy on configuration page if it's not supported 2019-01-04 14:33:27 +01:00
shortcutme
859c81c81b
Rev3746, Fix open_browser parsing with non-main cli command 2019-01-02 02:31:04 +01:00
shortcutme
83ed87cec0
Merge branch 'master' of https://github.com/HelloZeroNet/ZeroNet 2019-01-02 01:21:05 +01:00
shortcutme
9b6feb4a01
Rev3745, Fix tor bridges config file parsing with True value 2019-01-02 01:21:00 +01:00
ZeroNet
40841b9b07
Update README.md 2018-12-31 01:37:33 +01:00
shortcutme
d1227b6447
Rev3744, Fix typo 2018-12-30 12:28:19 +01:00
shortcutme
fc417e7273
Rev3743, Fix argument parsing on unknown command 2018-12-30 12:09:22 +01:00
shortcutme
bda238344c
Test isIp, isPrivateIp 2018-12-19 13:25:20 +01:00
shortcutme
45add916f4
Rev3742, Move isIp to helper, fix inet_prton error 2018-12-19 13:15:59 +01:00
Andrew Morgan
ca549cf081 Allow IP addresses via WebSocket API (#1819)
* Allow IP addresses via WebSocket API

* Switch to socket. Add host
2018-12-18 14:36:14 +01:00
shortcutme
fb3c5eaafa
Rev3741 2018-12-15 18:40:14 +01:00
shortcutme
8e4873cf2a
Do a quick content.db check on startup 2018-12-15 18:39:39 +01:00
shortcutme
47316741c1
Allow only CREATE in indexes 2018-12-15 17:48:19 +01:00
shortcutme
86dd57d13e
Fix typo in comment 2018-12-15 17:47:34 +01:00
shortcutme
4fe6ae9811
Allow only SELECT in storage.query 2018-12-15 17:45:17 +01:00
shortcutme
edc1a71d0d
Rev3739, Fix atomicWrite of non existent file 2018-12-13 21:17:36 +01:00
shortcutme
ed74403850
Merge branch 'master' of https://github.com/HelloZeroNet/ZeroNet 2018-12-13 21:15:14 +01:00
Thunder33345
9454c05b7e Added issue templates for suggestions (#1814)
* Rename .github/ISSUE_TEMPLATE.md to .github/ISSUE_TEMPLATE/Bug Reports.md

* Update issue templates

* Rename Bug Reports.md to bugs.md

* Update issue templates

oh well apparently it only likes it if you use it's editor

* Delete bug_report.md

* Delete bugs.md
2018-12-12 17:58:40 +01:00
ZeroNet
cdd7f4b6bb
Merge pull request #1800 from caryoscelus/sidebar-fix
Minor fix in sidebar plugin
2018-12-10 16:46:20 +01:00
shortcutme
e4819c1753
Rev3738, More strict csp, No csp on Edge
Edge does not supports nonce on external scripts
2018-12-10 02:29:21 +01:00
ZeroNet
e8e0a19758
Merge pull request #1805 from SuperSandro2000/patch-1
Update Dockerfile
2018-12-08 13:58:01 +01:00
Sandro Jäckel
a8a271e6fb
Update Dockerfile
Update to Alpine 3.8
Apply best practices eg:
- Don't upgrade
- Add --no-cache-dir to pip install
- Remove removing of any tmp folder as it is deprecated
- Format RUN block nicer
2018-12-08 13:32:28 +01:00
caryoscelus
fc6aa7cc1c Minor fix in sidebar plugin
Under certain conditions content["files"] is present, but is None,
which led to exception and thus failure of the whole sidebar.
2018-12-05 10:05:43 +00:00
shortcutme
b0140a655f
Rev3737 2018-12-04 14:16:37 +01:00
shortcutme
ef7ee02f65
Cleanup chart db 10 minutes after startup 2018-12-04 14:16:22 +01:00
shortcutme
3d1d5c1151
Delete old chart entries 2018-12-04 14:16:06 +01:00
shortcutme
e0c56c6342
Fix log directory path bug 2018-12-04 14:15:48 +01:00
shortcutme
2ceada84a6
Rev3736, Fix sidebar content signing changer links 2018-12-04 01:45:01 +01:00
shortcutme
5b50a113d1
Rev3735, certList admin command 2018-11-30 15:56:20 +01:00
shortcutme
fe52cc7797
Rev3734 2018-11-29 14:33:45 +01:00
shortcutme
3923f2baf4
Allow block sites based on sha256 hashed address 2018-11-29 14:32:55 +01:00
shortcutme
0157ade1c9
Don't autodelete optional files from owned files 2018-11-29 14:32:32 +01:00
shortcutme
a863c743c4
Rev3729 2018-11-27 11:30:41 +01:00
shortcutme
62d3b6a3f2
Remove not used variables in getStartDir 2018-11-27 11:30:22 +01:00
shortcutme
e435274329
Convert win-style path to unix-style path for log and data dir 2018-11-27 11:29:55 +01:00
shortcutme
55380298f1
Rev3728 2018-11-26 00:21:22 +01:00
shortcutme
71e65119ae
Add script nonce for blacklisted site page 2018-11-26 00:21:01 +01:00
shortcutme
dc788043ff
Escape notification in ContentFilter plugin 2018-11-26 00:20:37 +01:00
shortcutme
a98c465c9a
Use injectScript for Multiuser plugin notification 2018-11-26 00:19:49 +01:00
shortcutme
dace0671c2
Add script nonce for Multiuser notification script inject 2018-11-26 00:18:46 +01:00
shortcutme
0882f9dd3c
Use redirect API call for logging in using UiPassword plugin 2018-11-26 00:18:08 +01:00
shortcutme
c734e13753
Escape pinned file names 2018-11-26 00:17:29 +01:00
shortcutme
b54483db51
Variables in underline translation helper will be escaped by default 2018-11-26 00:16:53 +01:00
shortcutme
5d0bf2e80b
Replace html tags separately in sidebar html as it would be escaped otherwise 2018-11-26 00:16:19 +01:00
shortcutme
46e694a5c8
Add script nonce when loading js for globe in sidebar 2018-11-26 00:14:30 +01:00
shortcutme
e0756a56a4
Add script_nonce for UiConfig plugin 2018-11-26 00:13:58 +01:00
shortcutme
55e2a2fd5d
Source code reloader only once in every 5 seconds 2018-11-26 00:13:21 +01:00
shortcutme
eecc257822
Make unknown site request a bad action everywhere 2018-11-26 00:12:54 +01:00
shortcutme
36f2998c91
Test if js works in raw and normal mode 2018-11-26 00:12:12 +01:00
shortcutme
131926cad8
Make current url getting compatible with chromedriver 2018-11-26 00:11:58 +01:00
shortcutme
d588327c1c
Change wget to getUrl 2018-11-26 00:11:25 +01:00
shortcutme
68c7f502b4
Use chromedriver instead of phantomjs for testing 2018-11-26 00:10:43 +01:00
shortcutme
06fa669f8c
Test escaping in translation underline helper 2018-11-26 00:09:46 +01:00
shortcutme
d3885eefda
Automatically escape all variables in translation underline func helper 2018-11-26 00:09:24 +01:00
shortcutme
74e551cf1a
Escape error messages 2018-11-26 00:08:41 +01:00
shortcutme
a1333d8d6b
Detailed log certSelect error messages 2018-11-26 00:08:22 +01:00
shortcutme
3dfb40b57e
Use redirect after cloning the site 2018-11-26 00:07:23 +01:00
shortcutme
316cd7710f
Use injectScript in certSelect 2018-11-26 00:07:08 +01:00
shortcutme
cbefc5b81e
Merge wrapper js 2018-11-26 00:05:17 +01:00
shortcutme
233e161327
New injectScript and redirect command for UiServer 2018-11-26 00:05:04 +01:00
shortcutme
7cbbc33319
Expose script nonce for wrapper js obj 2018-11-26 00:04:06 +01:00
shortcutme
61cc0a1864
Add nonce attribute to all scripts in wrapper 2018-11-26 00:03:21 +01:00
shortcutme
99f01475a0
Disallow unknown script by using csp header for wrapper 2018-11-26 00:02:35 +01:00
shortcutme
481e029600
Rev3707 2018-11-21 19:28:43 +01:00
shortcutme
5ff22467a6
Sanitize error message 2018-11-21 19:28:30 +01:00
shortcutme
3fd44a1813
Validate merger type before asking permission 2018-11-21 19:28:11 +01:00
shortcutme
224a354480
Merge branch 'master' of https://github.com/HelloZeroNet/ZeroNet 2018-11-21 03:37:10 +01:00
shortcutme
18cdf5d89d
Rev3704 2018-11-21 03:37:05 +01:00
shortcutme
293afa6059
Replace dead trackers 2018-11-21 03:36:55 +01:00
shortcutme
06fbcde815
Fix setLocalStorage call before websocket connection 2018-11-21 03:32:12 +01:00
shortcutme
4195a72621
Only create default json table if it's not defined in dbschema 2018-11-21 03:31:12 +01:00
ZeroNet
d3bf001752
Merge pull request #1781 from hugbubby/patch-2
Fixed a line in the gentoo instructions.
2018-11-19 13:26:27 +01:00
hugbubby
d4604cba34
Fixed a line in the gentoo instructions.
That keyword only works for one specific iteration of the package. It is wrong for the current version, and this is a more appropriate command.
2018-11-19 05:37:29 -06:00
ZeroNet
221b4a9391
Merge pull request #1780 from mymage/patch-1
Update it.json
2018-11-13 17:09:55 +01:00
mymage
5f5d4d7987
Update it.json
Some fixes
2018-11-12 20:46:42 +01:00
shortcutme
8a17fe927f
Change docs url to self hosted 2018-11-08 02:43:51 +01:00
shortcutme
090d1e900e
Rev3703 2018-11-08 01:37:01 +01:00
shortcutme
d0f9d4de02
Fix invalid user auth address matching 2018-11-08 01:36:12 +01:00
shortcutme
6bc1ac1156
Support pattern based cert signers 2018-11-08 01:35:15 +01:00
shortcutme
c77e403f27
Logging init refactor, log rotate support 2018-11-08 01:32:31 +01:00
shortcutme
5178a288ca
Fix error message testing 2018-11-08 01:31:23 +01:00
shortcutme
7c6702057d
Test invalid cert user id 2018-11-08 01:30:56 +01:00
shortcutme
c1aad3882c
Test signers pattern 2018-11-08 01:30:32 +01:00
shortcutme
8cf30893f2
Don't close idle db connection during rebuild 2018-11-08 01:20:33 +01:00
shortcutme
da9af181dd
Support accepted_pattern for certSelect API call 2018-11-08 01:16:08 +01:00
shortcutme
92e3c028bb
Make cert domains case sensitive 2018-11-08 01:12:27 +01:00
shortcutme
cf7d194dbf
Remove missing optional files from content.json on cloning 2018-11-07 22:48:35 +01:00
shortcutme
eae6a34bfc
Merge branch 'master' of https://github.com/HelloZeroNet/ZeroNet 2018-10-30 04:50:28 +01:00
shortcutme
d9f851f0c1
Rev3688 2018-10-30 04:50:24 +01:00
shortcutme
9590dce8a4
Return ok for site clone, Fix typo in comment 2018-10-30 04:49:42 +01:00
shortcutme
5af77449fa
Move html variable replacement for new function, add site_modified variable, don't send length header for html files 2018-10-30 04:49:11 +01:00
shortcutme
2c39ab01ea
ZeroNet logo for fixbutton 2018-10-30 04:47:19 +01:00
shortcutme
035d70cf57
Spawn site announce to new async line 2018-10-30 04:44:43 +01:00
shortcutme
8c76e258d7
Give 10 second timeout for reannounce 2018-10-30 04:43:58 +01:00
shortcutme
f05c7ffbfa
Fix parsing invalid files for db 2018-10-30 04:43:21 +01:00
shortcutme
a49fcb0176
Fix verification for files without sign 2018-10-30 04:41:45 +01:00
shortcutme
87503b875a
Set timeout for connection 2018-10-30 04:41:11 +01:00
shortcutme
d89d770e73
Log less precise time for connection cleanup 2018-10-30 04:41:02 +01:00
shortcutme
083d64d151
Add site to connection log 2018-10-30 04:40:34 +01:00
shortcutme
281f379ced
Use the Db cursor to delete peers 2018-10-30 04:39:59 +01:00
shortcutme
9dab48d135
Only show multiuser master key on click and allow download as file 2018-10-30 04:39:13 +01:00
shortcutme
56221ebc95
Support limiting maximum bigfile size 2018-10-30 04:38:18 +01:00
ZeroNet
0b4b1cb3f3
Merge pull request #1741 from hugbubby/patch-1
Updated gentoo section
2018-10-27 11:50:17 +02:00
hugbubby
30e417a614
Updated gentoo section
1. Not all installations have layman, and it's being phased out.
2. Need to `emerge --sync` after adding a new repository.
3. Added a line that adds the zeronet service to the default autostart runlevel (under optional)
2018-10-26 19:16:55 -05:00
shortcutme
538de08c07
Rev3673, Fix sidebar input fields on mobile 2018-10-24 13:59:10 +02:00
shortcutme
f540645d80
Rev3672, Fix Config page fileserver port changing 2018-10-24 13:31:42 +02:00
shortcutme
a58743b820
0.6.4 Changelog 2018-10-23 23:59:32 +02:00
ZeroNet
0ed1499d02
Merge pull request #1730 from krixano/patch-2
Import Debug in Db/Db.py
2018-10-20 15:38:26 +02:00
shortcutme
5158a710dc
Rev3671, Fix theme with multiuser plugin 2018-10-20 13:34:49 +02:00
Christian Seibold
413b6cc43c
Import Debug in Db/Db.py 2018-10-20 01:58:35 -05:00
shortcutme
82a10f2558
Version 0.6.4, Rev3670 2018-10-20 02:36:29 +02:00
shortcutme
b97acb3174
Dark theme for loading screen 2018-10-20 02:36:08 +02:00
shortcutme
451976c3c8
Support themeclass variable in html files 2018-10-20 02:35:48 +02:00
shortcutme
8e6494c451
Remove unused code, junk lines 2018-10-20 02:34:26 +02:00
shortcutme
3579f9e0c4
Support global user settings 2018-10-20 02:28:58 +02:00
shortcutme
39d442a05d
Fix getConnectablePeers for low peer sites 2018-10-20 02:26:29 +02:00
shortcutme
0045206735
Merge UI js 2018-10-20 02:22:38 +02:00
shortcutme
7f46767411
Fix undefined in title 2018-10-20 02:22:29 +02:00
shortcutme
5414691f1f
Remove unnnecessary debug 2018-10-20 02:22:20 +02:00
shortcutme
13731fb094
Rename jquery easings file 2018-10-20 02:21:54 +02:00
ZeroNet
40ab9d9366
Merge pull request #1717 from rllola/pyinstaller-browser-fix
Make it compatible with pyinstaller for browser build
2018-10-17 10:54:18 +02:00
rllola
93d6129732 Make it compaticle with pyinstaller for browser build 2018-10-16 07:12:57 +02:00
ZeroNet
776e214789
Merge pull request #1690 from ZeroNetPlus/jquery
[Ready to be merged] Updated jQuery
2018-10-15 17:29:08 +02:00
shortcutme
d8f6621c7d
Rev3660 2018-10-15 13:19:41 +02:00
shortcutme
aca2b4423e
Fix zh-tw lang detection 2018-10-15 13:19:33 +02:00
shortcutme
204e3f8e3e
Change unreliable tracker 2018-10-15 13:19:16 +02:00
shortcutme
f54443d7f8
Reset pinned cache on file deletion 2018-10-15 13:18:18 +02:00
shortcutme
3d82ad9222
Fix optional used bytes calculation 2018-10-15 13:18:00 +02:00
shortcutme
393c66385f
Add pinning notification based on number of files 2018-10-15 13:17:42 +02:00
shortcutme
b008195abd
Set pin using ContentManager function 2018-10-15 13:16:55 +02:00
shortcutme
ad2c11413e
Allow to filter to pinned files on optionalfilelist 2018-10-15 13:16:35 +02:00
shortcutme
1e2853c950
Update hashfield on update peer numbers 2018-10-15 13:15:36 +02:00
shortcutme
171e5d3766
Fix typo on optional file deletion 2018-10-15 13:15:11 +02:00
shortcutme
46535cc7a8
File deletion based on type 2018-10-15 13:14:43 +02:00
shortcutme
16b40a731a
Test pinned cache, download piece queue reset, pinned optional file delete 2018-10-15 13:13:43 +02:00
shortcutme
9b4b9334a3
Remove pinned status of a file on file deletion 2018-10-15 13:12:46 +02:00
shortcutme
96d40d9816
Don't modify pinned status on file downloaded 2018-10-15 13:12:27 +02:00
shortcutme
407b003cd6
Add all piece of an optional file to download queue if one of the piece is downoaded 2018-10-15 13:11:23 +02:00
shortcutme
8129d5e6af
Don't remove pinned files from download queue 2018-10-15 13:10:34 +02:00
shortcutme
c12454a8e9
Don't delete pinned file if it removed by owner 2018-10-15 13:09:43 +02:00
shortcutme
0f49d412b5
Stop auto pinning files larger than 20MB 2018-10-15 13:07:53 +02:00
shortcutme
b33551e62e
Exclude files larger than 20MB from garbage collection 2018-10-15 13:06:50 +02:00
shortcutme
8bb4d149b6
Fix comment typo 2018-10-15 13:05:24 +02:00
shortcutme
854fda4530
Skip updating hashfiled of inactive sites 2018-10-15 13:05:18 +02:00
shortcutme
0deea7133d
Stop downloading bigfile piece if file removed 2018-10-15 13:03:36 +02:00
shortcutme
1eaa8afc5f
Only display the filename on sidebar download queue 2018-10-15 13:02:13 +02:00
shortcutme
1fc364fa07
Remove unused lines from dbCursor 2018-10-15 13:01:44 +02:00
shortcutme
f275ba36a1
Skip table creation on error 2018-10-15 13:01:17 +02:00
shortcutme
1aa741a25b
Always change db cursor settings 2018-10-15 13:01:04 +02:00
shortcutme
6b2f619096
Fix updateHashfield optional file detection 2018-10-15 12:59:28 +02:00
shortcutme
f74ddc1010
Don't delete connecting sites at startup 2018-10-15 12:59:04 +02:00
shortcutme
6a240919bf
Test archived before 2018-10-15 12:58:39 +02:00
shortcutme
2518867d50
Allow to also list connecting site with siteList API command 2018-10-15 12:58:14 +02:00
shortcutme
046b95d5b1
Rev3620 2018-10-08 15:35:32 +02:00
shortcutme
12dab27729
Skip tracker status with no value yet 2018-10-08 15:34:40 +02:00
ZeroNet
29964aa90c
Merge pull request #1683 from geekless/Zeroname-fixes
Allow using other domain resolver plugins along with Zeroname
2018-10-08 15:19:44 +02:00
ZeroNet
f0f7b86c7d
Merge pull request #1693 from krixano/patch-1
Add "allow-presentation" to iframe
2018-10-08 10:48:55 +02:00
Christian Seibold
2d437975a8
Add allow presentation to iframe
Allows zites to use the Presentation API
2018-10-07 20:01:30 -05:00
Daniell Mesquita
a9502a11d6 Update jQuery easing
Signed-off-by: Daniell Mesquita <daniellplasmmer@gmail.com>
2018-10-07 15:03:11 -03:00
Daniell Mesquita
6aa502b1a5 Updated jQuery
Signed-off-by: Daniell Mesquita <daniellplasmmer@gmail.com>
2018-10-07 15:00:02 -03:00
Vadim Ushakov
ea40d212c2 Allow using other domain resolver plugins along with Zeroname
Fixes several closely related bugs in Zeroname Plugin, those prevent correct work of other domain resolvers:

1. get(), isDomain(): when an address doesn't look like a valid domain, pass control to the next plugin in a chain.

3. Move the .bit-domain matching logic to a separate method isBitDomain().

2. get(), need(): use isBitDomain(), not isDomain() to check if domain resolving is needed in order to not interfere with other domain resolvers.

4. Also rewrite isAddress() to make it look similar to the new implementation of isDomain().
2018-10-06 12:35:14 +07:00
shortcutme
befed2200e
Rev3619 2018-10-05 15:09:35 +02:00
shortcutme
7afe1807b7
Merge sidebar js 2018-10-05 15:08:42 +02:00
shortcutme
91478aa128
Add TLS version of the connection to stats page 2018-10-05 15:08:28 +02:00
shortcutme
424b36ffca
Avoid double removing tag on sidebar close 2018-10-05 15:08:12 +02:00
shortcutme
52f7dc71e6
Fix typo in private key confirmation 2018-10-05 15:07:55 +02:00
shortcutme
402e6e7433
Merge branch 'master' of https://github.com/HelloZeroNet/ZeroNet 2018-10-04 15:44:27 +02:00
shortcutme
6592906d0d
Rev3618 2018-10-04 15:44:07 +02:00
shortcutme
678f4102a5
Confirmation of private key forgot 2018-10-04 15:43:25 +02:00
shortcutme
c70e3bb3dd
Add comment to detection of Android float issue 2018-10-04 15:43:12 +02:00
shortcutme
b089355b5a
Fix detaction of pt-br system language 2018-10-04 15:42:45 +02:00
shortcutme
00cf1badfc
Fix error on invalid cli action 2018-10-04 15:42:11 +02:00
shortcutme
07159ea5df
Remove invalid characters from language setting 2018-10-04 15:41:28 +02:00
ZeroNet
52f3b8b507
Merge pull request #1640 from tangdou1/patch-3
Update zh.json
2018-10-02 18:33:39 +02:00
ZeroNet
d1387e50e2
Merge pull request #1643 from DaniellMesquita/patch-3
Update pt-br.json
2018-10-02 18:33:17 +02:00
ZeroNet
65112b6008
Merge pull request #1644 from DaniellMesquita/master
Update Sidebar's pt-br.json
2018-10-02 18:32:50 +02:00
shortcutme
4e4dc30a91
Rev3616 2018-09-30 21:57:14 +02:00
shortcutme
70292dac00
Don't allow to take the ownership of the updater site with the API 2018-09-30 21:56:36 +02:00
shortcutme
e46cb2f240
Fix content type indentification 2018-09-30 21:55:48 +02:00
shortcutme
9fee86df59
Always return lower cased content type 2018-09-30 21:54:50 +02:00
Daniell Mesquita
19b61a32af
Update pt-br.json 2018-09-22 17:12:33 -03:00
Daniell Mesquita
60091a2b5e
Update pt-br.json 2018-09-22 16:08:07 -03:00
tangdou1
68d246a3e9
Update zh.json 2018-09-22 22:45:22 +08:00
tangdou1
9749f59b5a
Update zh.json 2018-09-22 22:37:41 +08:00
shortcutme
15c09a0f03
Rev3612 2018-09-21 20:40:38 +02:00
ZeroNet
971212e7e9
Merge pull request #1635 from tangdou1/patch-1
Fix bootstrapper is blocked by itself
2018-09-21 20:30:29 +02:00
tangdou1
807d461289
Fix bootstrapper is blocked by itself
Make the bootstrapper server can add its own ip and port in its own bootstrapper.db as a peer.
2018-09-21 14:05:27 +08:00
shortcutme
e033b72942
Rev3611 2018-09-21 02:19:01 +02:00
shortcutme
98b476de71
Load current users before creating a new one 2018-09-21 02:18:29 +02:00
shortcutme
8fd2af1870
Private key save and fogot to sidebar 2018-09-21 02:17:53 +02:00
shortcutme
2a1849d027
Rev3609, Don't validate valid pattern in UiConfig if the field is hidden 2018-09-17 17:48:15 +02:00
shortcutme
d04b759913
Allow more time inaccuracy for noparallel test 2018-09-17 15:40:44 +02:00
shortcutme
2772e705ae
Rev3608 2018-09-17 15:34:03 +02:00
shortcutme
d44a4e8ae2
Sidebar optimization and dummy static page for uncoming internal page 2018-09-17 15:33:45 +02:00
shortcutme
53a40fa914
Stop worker if the file is not required anymore 2018-09-17 15:32:32 +02:00
shortcutme
86d1d4898a
Remove task on file write error 2018-09-17 15:31:10 +02:00
shortcutme
e4af2d5e86
Pick up task that is taken by idle peer 2018-09-17 15:30:48 +02:00
shortcutme
d124e2ed15
Support deletion of of all user submitted content that is older than specified date 2018-09-17 15:30:02 +02:00
shortcutme
00c9c14efb
Support listmodified before and after argument 2018-09-17 15:28:53 +02:00
shortcutme
6fc66b7b13
Move file forgot to separate function 2018-09-17 15:27:29 +02:00
shortcutme
9658c2d553
Stop downloadcontent pool if reached 95% of site limit 2018-09-17 15:27:11 +02:00
shortcutme
577761a6bb
Add cache to default settings 2018-09-17 15:25:17 +02:00
shortcutme
6c610c509f
Rename RemoveGoodFileTasks to RemoveSolvedFileTasks and add result argument 2018-09-17 15:24:44 +02:00
shortcutme
1eacc26ef9
Always call addPeer command with strip ip address and int port 2018-09-17 15:20:31 +02:00
shortcutme
5f33516054
Cleanup unreliable trackers easier if reached the shared tracker limit 2018-09-17 15:20:02 +02:00
shortcutme
0766205cb0
Missing changelog for 0.6.3 2018-09-17 15:18:45 +02:00
ZeroNet
0825626fc9
Merge pull request #1506 from eduaddad/patch-1
Create pt-br.json
2018-09-16 13:08:08 +02:00
ZeroNet
470352ddc8
Merge pull request #1610 from DaniellMesquita/patch-1
fix pull request #1597
2018-09-16 13:06:46 +02:00
ZeroNet
5ccff7b406
Merge pull request #1615 from adrelanos/patch-1
add Whonix instructions
2018-09-16 13:03:29 +02:00
Patrick Schleizer
66c03c6798
add Whonix instructions 2018-09-15 13:01:59 -04:00
Daniell Mesquita
d7912c6973 fix pull request #1597
Signed-off-by: Daniell Mesquita <plasmmer@outlook.com>
2018-09-14 16:59:45 -03:00
ZeroNet
afa20c92e8
Merge pull request #1597 from DaniellMesquita/patch-1
Added brazillian portuguese translation for Config
2018-09-13 11:27:19 +02:00
ZeroNet
95562a8965
Merge pull request #1599 from tangdou1/patch-1
Create zh.json for config page
2018-09-13 11:25:07 +02:00
tangdou1
a1abbd406d
Create zh.json 2018-09-13 11:35:47 +08:00
Daniell Mesquita
b05d125db2
Added brazillian portuguese translation for Config 2018-09-12 22:43:37 -03:00
shortcutme
54efe5a351
Rev3597 2018-09-13 03:12:29 +02:00
shortcutme
8594fa8199
Don't try to load english translation files 2018-09-13 03:12:02 +02:00
shortcutme
238667d989
Hungarian translate for configuration page 2018-09-13 03:11:35 +02:00
shortcutme
87536619e3
Translate support for configuration page 2018-09-13 03:11:24 +02:00
shortcutme
84ab076fe8
Rev3594 2018-09-07 11:34:11 +02:00
shortcutme
57f3cee390
Fix fileGet return when file is not existent 2018-09-07 11:33:57 +02:00
shortcutme
714aea2e27
RequestFullscreen API does not requires confirmation anymore as you can call it directly 2018-09-07 11:33:40 +02:00
shortcutme
52081f4a2a
Make Accept a problematic string as it brokes jquery script loading 2018-09-07 11:32:44 +02:00
shortcutme
b88b422e2f
Rev3591 2018-09-06 00:57:21 +02:00
shortcutme
d3499e71ef
FileGet use return function instead of calling response 2018-09-06 00:56:36 +02:00
shortcutme
c7d94548be
Support returning empty list as reponse 2018-09-06 00:55:54 +02:00
shortcutme
c866932861
Full fileList/fileGet/dirList support for packed files 2018-09-06 00:54:57 +02:00
shortcutme
317bd2fcec
Rev3588 2018-09-05 14:34:00 +02:00
shortcutme
b06ba06f40
Add timecorrection to server info 2018-09-05 14:33:31 +02:00
shortcutme
dc52a8a08b
Use shared file_server object when generating server info for websocket 2018-09-05 14:33:21 +02:00
shortcutme
5f1e7ffd0c
Correct sent time with timecorrection value 2018-09-05 14:32:43 +02:00
shortcutme
21a80650b0
Cache timecorrection value 2018-09-05 14:32:23 +02:00
shortcutme
3b7ec3d913
Lowercased Timecorrection function 2018-09-05 14:32:01 +02:00
shortcutme
f1c89f0917
Stats page show peer reputation 2018-09-05 14:31:26 +02:00
shortcutme
8692ea1a74
Rev3585 2018-09-04 15:44:23 +02:00
shortcutme
a5c25ce438
Dont add removed trackers to announcer stats 2018-09-04 15:43:52 +02:00
shortcutme
12d494bf38
Limit peer reputation increase from tracker 2018-09-04 15:43:20 +02:00
shortcutme
f0f9b93694
Merge branch 'master' of https://github.com/HelloZeroNet/ZeroNet 2018-09-02 02:34:50 +02:00
shortcutme
a97f5a8488
Rev3582 2018-09-02 02:34:47 +02:00
shortcutme
a4224555d2
Increase gzipped json file size limit 2018-09-02 02:33:44 +02:00
shortcutme
1b0055ac61
Less reputation for onion peers 2018-09-02 02:26:42 +02:00
shortcutme
7dcde3e585
Store peer reputation, time_found in peer db 2018-09-02 02:26:17 +02:00
shortcutme
4fe33268ac
Don't allow parallel rebuild 2018-09-02 02:24:07 +02:00
shortcutme
b84abea670
Order more peers for connected peers simply by reputation 2018-09-02 02:23:46 +02:00
shortcutme
a5fcc7d65f
Sort recent peers by reputation 2018-09-02 02:23:19 +02:00
shortcutme
313d9a4ef9
Need less peer sites with less peers 2018-09-02 02:23:06 +02:00
shortcutme
658aace8f1
Increase peer reputation when found by tracker 2018-09-02 02:22:35 +02:00
shortcutme
49562d43c3
Change peer reputation on connection success and error 2018-09-02 02:22:21 +02:00
shortcutme
4241b62760
Log peer reputation on connect 2018-09-02 02:21:48 +02:00
shortcutme
47fcee4df8
Limit peer reputation 2018-09-02 02:21:38 +02:00
shortcutme
6c2eae29f5
Sort trackers in stats page 2018-09-02 02:20:02 +02:00
shortcutme
3869cb9bf3
Show incoming and outgoing connection separatley in stats page 2018-09-02 02:19:51 +02:00
shortcutme
89c871f171
Fix newsfeed listing during new site added 2018-09-02 02:18:57 +02:00
shortcutme
12c95e6fca
Fix marking peers from zero trackers 2018-09-02 02:18:11 +02:00
shortcutme
2affb9b863
Configurable wokring shared trackers limit 2018-09-02 02:17:42 +02:00
shortcutme
710a85429e
Remove unreliable shared trackers earlier if we have atleast 4 working one 2018-09-02 02:17:18 +02:00
ZeroNet
2efa6f5cb1
Merge pull request #1558 from imachug/cors-fix
Allow 'fileList' (and other) commands on CORS
2018-08-31 19:07:18 +02:00
Ivanq
3f1a103e82 Allow 'fileList' command on CORS 2018-08-31 19:46:45 +03:00
shortcutme
1ce87ecfa8
Rev3576 2018-08-29 19:58:33 +02:00
shortcutme
e102d256b2
Formatting 2018-08-29 19:58:23 +02:00
shortcutme
3b6b79229f
Db table stats 2018-08-29 19:58:18 +02:00
shortcutme
70c1e57ff0
Shared tracker found time to stats page 2018-08-29 19:57:54 +02:00
shortcutme
ad02f384d2
Connection time correction on stats page 2018-08-29 19:57:38 +02:00
shortcutme
0efa6a5816
Time correction to stats page 2018-08-29 19:56:27 +02:00
shortcutme
6edabeeecc
Log hashfield query time 2018-08-29 19:55:50 +02:00
shortcutme
b96559b76f
Reduce connection requirements on startup 2018-08-29 19:55:04 +02:00
shortcutme
3a9ded9315
On startup don't run more than 5 checkSite at the same time 2018-08-29 19:54:31 +02:00
shortcutme
ee97eb6d27
Calculate media time correction from connections 2018-08-29 19:53:44 +02:00
shortcutme
16f7dafcdf
Only record offline internet if there was message received before 2018-08-29 19:53:24 +02:00
shortcutme
1cce926ef8
Record handshake time for connections 2018-08-29 19:52:55 +02:00
shortcutme
1cf50e5fcd
Fix chart collection when there is no site 2018-08-29 19:52:24 +02:00
shortcutme
d8654edd2c
Fix comment 2018-08-29 19:52:10 +02:00
shortcutme
f3b97dedc8
Fix time_found record for tracker stats 2018-08-29 19:51:26 +02:00
shortcutme
b45bbff97c
Rev3571 2018-08-27 11:51:07 +02:00
shortcutme
23284e1f35
Reduce the reannounce to unreliable trackers not just single announces 2018-08-27 11:50:53 +02:00
shortcutme
c9c6a4b867
Less frequent reannounce to zero trackers 2018-08-27 11:50:13 +02:00
shortcutme
069c59d3d7
Only allow zero trackers to be shared 2018-08-27 11:49:24 +02:00
shortcutme
4f2352355f
Return True when adding new tracker 2018-08-27 11:49:05 +02:00
shortcutme
984f50b792
Working tracker list default type 2018-08-27 11:48:52 +02:00
shortcutme
426309a8f5
Stop discovering new trackers after 5 working one 2018-08-27 11:48:39 +02:00
shortcutme
b4b4694eb5
Only add one new tracker from one source 2018-08-27 11:48:25 +02:00
shortcutme
5505a8609d
Fix AnnounceShare source code reloading 2018-08-27 11:48:11 +02:00
shortcutme
030ad0a8de
Rev3568 2018-08-26 22:58:56 +02:00
shortcutme
71d05a6fc2
Global stats to reduce tracker request for unreliable trackers 2018-08-26 22:58:27 +02:00
shortcutme
867cf478b1
Log tracker request mode on error 2018-08-26 22:57:34 +02:00
shortcutme
b43a05b662
Don't increase request tracker number before actually sending it 2018-08-26 22:57:09 +02:00
shortcutme
92db3878cf
Don't include skipped trackers to report 2018-08-26 22:56:46 +02:00
shortcutme
b6d11d6be3
Fix request number counting with zero trackers 2018-08-26 22:56:20 +02:00
shortcutme
669572b0e6
Fix udp tracker lib error reporting 2018-08-26 22:55:31 +02:00
shortcutme
5887f90202
Wait handshake done before sending other request to connections 2018-08-26 22:54:45 +02:00
shortcutme
81d50ed3bb
Add trackers to stats page 2018-08-26 22:53:01 +02:00
shortcutme
9bdf3ad0c8
Only log new tacker discovery if it was not added before 2018-08-26 22:52:30 +02:00
shortcutme
0b38d73cc5
AnnounceZero return None on skipped announce due batching 2018-08-26 22:52:21 +02:00
shortcutme
7a3dbf626e
Only share trackers with success in last hour 2018-08-26 22:50:46 +02:00
shortcutme
767ec1795a
Reset shared tracker error number on startup 2018-08-26 22:45:44 +02:00
shortcutme
ecbf230293
Fix site update on non existent sites 2018-08-26 22:44:55 +02:00
shortcutme
839b63e389
Tracker stat skip data with no status information 2018-08-26 22:44:31 +02:00
shortcutme
73078531aa
Rev3565 2018-08-26 02:58:05 +02:00
shortcutme
c5c3f7a667
Don't reannounce site if just added 2018-08-26 02:57:02 +02:00
shortcutme
8738817eab
Fix tor logging on message fail 2018-08-26 02:56:41 +02:00
shortcutme
33877c73bb
Test tracker address validity 2018-08-26 02:56:24 +02:00
shortcutme
0e3698fa2f
Announce to next tracker on fail 2018-08-26 02:55:08 +02:00
shortcutme
65f48800b9
Allow tracker list to be extended by plugins 2018-08-26 02:53:39 +02:00
shortcutme
7738e6a381
Fix tracker annonce sleeping formatting 2018-08-26 02:53:15 +02:00
shortcutme
ca3b01f898
Allow tracker connection to loopback to same client 2018-08-26 02:52:42 +02:00
shortcutme
e05c432d14
Store if it's tracker connection on connect 2018-08-26 02:52:23 +02:00
shortcutme
53a8c2d574
Fix trayicon compatibility with latest gevent 2018-08-26 02:48:36 +02:00
shortcutme
6783fb9010
Formatting 2018-08-26 02:47:58 +02:00
shortcutme
a7adb517ca
Only return small number of peers if no new site added by the peer 2018-08-26 02:47:43 +02:00
shortcutme
b7a66295f6
Start local peer discovery async to avoid double announce 2018-08-26 02:46:12 +02:00
shortcutme
27f2c44532
AnnounceShare plugin 2018-08-26 02:45:37 +02:00
shortcutme
efd1efad4d
Rev3550 2018-08-16 16:23:04 +02:00
shortcutme
b2ea4c758d
Handle error on file listing API calls 2018-08-16 16:22:17 +02:00
shortcutme
cfce057783
Support streaming bigfile for zip file listing and reading 2018-08-16 16:21:21 +02:00
shortcutme
5854beebc6
Fix Bigfile tell 2018-08-16 16:20:21 +02:00
shortcutme
879eb6295d
BigFile lock seek and read until previous request finished, fix seek relative to bigfile end 2018-08-16 16:20:11 +02:00
eduaddad
3ae761dd9d
Create pt-br.json
translation into brazilian portuguese
2018-08-14 16:59:33 -03:00
shortcutme
f5ab2f63c0
Rev3546 2018-08-13 02:45:02 +02:00
shortcutme
c89170a22d
Allow first local ip find method to fail 2018-08-13 02:44:50 +02:00
shortcutme
84b36e72e4
Prefer non-onion peers when sidebar copy peers to clipboard 2018-08-13 02:43:23 +02:00
ZeroNet
9298922601
Merge pull request #1498 from radfish/PR--fix-log-warn
Fix issues with log messages related to Tor errors
2018-08-09 03:26:54 +02:00
ZeroNet
9913e7198c
Merge pull request #1496 from tangdou1/patch-1
small update in zh.json
2018-08-09 03:19:15 +02:00
redfish
9bd10d5102 TorManager: correct the Tor error log message
On Linux, there is no self-bundled Tor, so the message was not correct
because it was stating that self-bundled Tor was being started.
2018-08-02 23:47:24 +00:00
redfish
4c62840cef TorManager: escalate log error for Tor auth
This errorr is fatal for Tor usage (on Linux). Let's make escalate
it. Also see the previous commit, without which, this error doesn't
even get printed at all.
2018-08-02 23:42:50 +00:00
redfish
e6f0a86c5a main: logging: do not override the warn level
This fixes the very annoying problem where the log messages with
level WARNING are not printed, while log messages with lower
level INFO are printed. This is very confusing behavior and should
be avoided. This was due to this override. If there is too much
logging output in debug mode, then let's deescalate the level
of the frequently-printed log messages down to DEBUG level.
2018-08-02 23:40:44 +00:00
tangdou1
c9da6d2ee2
small update in zh.json
small update in zh.json
2018-08-01 18:05:25 +08:00
shortcutme
f33350a4ef
Rev3542, Trackers file path always relative to executable 2018-07-21 04:25:40 +02:00
shortcutme
debe9959e4
Fix saving browser open setting 2018-07-21 04:24:35 +02:00
shortcutme
a357b021ba
Rev3540 2018-07-19 20:44:25 +02:00
shortcutme
f7099b2bc7
Load trackers file on startup 2018-07-19 20:43:46 +02:00
shortcutme
8d3b1d10d2
Fix typo 2018-07-19 20:43:33 +02:00
shortcutme
f143000f4a
Fix parsing udp trackers with request path 2018-07-19 20:43:14 +02:00
shortcutme
7954caf957
Force reannounce not yet download site on refresh 2018-07-19 20:42:53 +02:00
shortcutme
a07a31a2bb
Copy site url with peers link to sidebar 2018-07-19 20:42:04 +02:00
shortcutme
405394707f
Shorter download site button title 2018-07-19 20:40:55 +02:00
ZeroNet
f13b8d1557
Merge pull request #1479 from vitorio/master
Support removing donation link / custom donation text
2018-07-18 13:58:09 +02:00
shortcutme
6e1f4fada9
Rev3537, Allow to add peers to site with get request 2018-07-17 02:09:14 +02:00
ZeroNet
892ef23ca0
Merge pull request #1487 from rllola/fix-rev-3535
Fix rev 3535 big javascript file
2018-07-16 23:01:12 +02:00
rllola
8e1c0a7fa4 Fix rev 3535 big javascript file 2018-07-16 17:32:18 +02:00
shortcutme
113e7e0d3d
Rev3535 2018-07-16 01:56:37 +02:00
shortcutme
ea619ce99a
Fix tor disabling for tests 2018-07-16 01:56:19 +02:00
shortcutme
e9c7d6a0cc
Add bigfile test for dynamic file allocation 2018-07-16 01:55:58 +02:00
shortcutme
2f57e9cbee
Bigfile test formatting fix 2018-07-16 01:55:41 +02:00
shortcutme
0de16855b0
Merge config js, css 2018-07-16 01:55:15 +02:00
shortcutme
4fedace179
Css for custom tracker proxy field 2018-07-16 01:55:09 +02:00
shortcutme
8d2da6f30b
Add animation helper for config 2018-07-16 01:54:39 +02:00
shortcutme
8f427b727c
Save config storage item for value 2018-07-16 01:54:30 +02:00
shortcutme
f1f0332d22
Config filed for custom socks proxy for trackers 2018-07-16 01:54:07 +02:00
shortcutme
7c0541034a
Restrict port to numbers 2018-07-16 01:53:34 +02:00
shortcutme
e8895a4d76
Only save if values validated 2018-07-16 01:52:51 +02:00
shortcutme
a42bcfceb6
Validate config values before saving 2018-07-16 01:52:27 +02:00
shortcutme
fcda2e8706
Reset restart loading status on weboscket connection 2018-07-16 01:52:10 +02:00
shortcutme
efe3680cd7
Fix typo 2018-07-16 01:51:32 +02:00
shortcutme
272e30d761
Separate config renderer related functions to separate file 2018-07-16 01:51:18 +02:00
shortcutme
30940fad2e
Set value to default one on pending reset 2018-07-16 01:49:12 +02:00
shortcutme
d772280147
Global announcer statistics admin API call 2018-07-16 01:48:27 +02:00
shortcutme
7475fa69fa
Support custom proxy for tracker connections 2018-07-16 01:47:49 +02:00
shortcutme
ec8b53263c
Store last announce error time 2018-07-16 01:36:23 +02:00
shortcutme
0f567385a8
Only check size on file request for smaller files 2018-07-16 01:35:35 +02:00
shortcutme
dae1197ce4
Pass the real file size on bigfile request as the size on the disk can be smaller 2018-07-16 01:34:48 +02:00
shortcutme
1296ab9b60
Only pre-allocate up to 5MB from big files 2018-07-16 01:34:21 +02:00
shortcutme
b1575a979e
Rev3524, Fix saving for single line config values 2018-07-10 04:00:16 +02:00
shortcutme
d677eb1698
Rev3523 2018-07-10 03:46:05 +02:00
shortcutme
71ad1d9906
Properly handle saving on multiline config settings 2018-07-10 03:45:57 +02:00
shortcutme
731b79fc6c
Store copy of variables of list config items to be able to read the original value 2018-07-10 03:45:33 +02:00
shortcutme
e001448adb
Add config link to loading screen 2018-07-10 03:43:57 +02:00
shortcutme
3041064d21
Reload trackers file on value change 2018-07-10 03:43:31 +02:00
shortcutme
30134dbbc9
Store API changeable configuration keys in Config.py 2018-07-10 03:40:56 +02:00
shortcutme
4208885e36
Store pending configuration values 2018-07-10 03:39:33 +02:00
shortcutme
656f48b354
Support open_browser disable even if it's started with start.py 2018-07-10 03:37:38 +02:00
shortcutme
68eb9a37ca
Strip ending / character when using url as function name 2018-07-10 03:36:09 +02:00
shortcutme
6c4ce03d59
Reload trackers file before start downloading new site 2018-07-10 03:34:23 +02:00
shortcutme
86e4679e04
Skip tracker announce on incalid url pattern 2018-07-10 03:34:06 +02:00
shortcutme
71806e6f95
Trackers loaded from trackers_file will be appended to trackers instead of replacing it 2018-07-10 03:33:32 +02:00
shortcutme
7e8a93e974
Load trackers files in announceSites loop 2018-07-10 03:32:37 +02:00
shortcutme
b87ad9cd2f
Fix disabled tor startup 2018-07-10 03:31:39 +02:00
shortcutme
10bab2b6e4
UiConfig plugin 2018-07-10 03:30:47 +02:00
shortcutme
5aab10fab2
Support client restart without updating 2018-07-10 03:28:02 +02:00
shortcutme
77aa23a375
Make UiWebsocket admin_commands and async_commands class variables for easier extension 2018-07-10 03:24:34 +02:00
vitorio
b09da2641e Preserve site address 2018-07-07 10:55:20 -05:00
vitorio
26b0a7d75d Support removing donation link / custom donation test 2018-07-07 01:15:40 -05:00
shortcutme
b6bf38b85c
Rev3504 2018-07-06 22:57:27 +02:00
shortcutme
b6424b4596
Fix sk translation 2018-07-06 22:57:18 +02:00
shortcutme
dc2051fb59
Skip invalid translate files 2018-07-06 22:56:54 +02:00
shortcutme
8bdc61ddcc
Rev3503, Ignore invalid site translation files 2018-07-05 01:59:10 +02:00
ZeroNet
d4a25230ec
Merge pull request #1474 from mkg20001/patch-1
de.json: Fix typo
2018-07-04 01:58:40 +02:00
Maciej Krüger
e548a4b6aa
de.json: Fix typo
Net{ => z}werkverbindung
2018-07-03 23:40:25 +02:00
ZeroNet
8607fe43a6
Merge pull request #1473 from rubo77/patch-1
de.json - correct german translation
2018-07-03 23:15:32 +02:00
Ruben Barkow
718178c1b6
de.json - correct german translation 2018-07-03 21:42:14 +02:00
ZeroNet
930205b1c9
Merge pull request #1469 from Biosias/patch-1
Adding few translations
2018-07-03 13:55:19 +02:00
shortcutme
ec05e6864a
Rev3502, Start fileserver to new greenlet to fix siteDownload and siteAnnounce CLI action 2018-07-02 15:42:16 +02:00
Biosias
e08a702408
Adding few translations 2018-07-02 01:00:42 +02:00
shortcutme
d5b31a5545
Rev3501 2018-06-29 14:20:54 +02:00
shortcutme
811c694f80
Ignore filter includes from removed sites 2018-06-29 14:20:44 +02:00
shortcutme
8775222a61
Add missing word to websocket error message 2018-06-29 14:18:27 +02:00
shortcutme
3aebdae305
Log last announce time on force announce 2018-06-29 14:18:09 +02:00
shortcutme
d3122020b9
Rev3500 2018-06-28 14:07:43 +02:00
shortcutme
822ea1b450
Fix site blacklisting using sidebar 2018-06-28 14:07:06 +02:00
shortcutme
515057c7d0
Update multiuser plugin with new filter commands 2018-06-28 14:06:28 +02:00
shortcutme
54b93febba
Fix included file content leaking to filters.json 2018-06-28 14:05:57 +02:00
shortcutme
5d0600a0af
Rev3499 2018-06-28 02:39:55 +02:00
shortcutme
1ca2b40bf9
Fix IE Edge compatibility on notification button clicks 2018-06-28 02:39:46 +02:00
shortcutme
ff85241962
More detailed not supported browser error message 2018-06-28 02:39:20 +02:00
shortcutme
bc227b5f56
Rev3498, Go back to homepage and less inviting open site button on blocked site page 2018-06-28 02:03:47 +02:00
shortcutme
283231ac6e
Remove renamed Mute plugin 2018-06-25 15:13:56 +02:00
shortcutme
fc46bb65f8
Version 0.6.3, Rev3495 2018-06-25 14:41:34 +02:00
shortcutme
c5ca4dd7b3
Change dead tracker 2018-06-25 14:40:51 +02:00
shortcutme
c493f732f9
New ContentFilter plugin for shared site and user blocklist 2018-06-25 14:35:26 +02:00
shortcutme
a59fb4fd1e
Send file updated event to site on signing 2018-06-25 14:33:14 +02:00
shortcutme
f671e699e6
Reset after_load actions before plugin reload 2018-06-25 14:30:04 +02:00
shortcutme
05fb60f809
Log plugin load time 2018-06-25 14:29:51 +02:00
shortcutme
e564470490
Remove renamed plugin Mute 2018-06-25 14:29:42 +02:00
shortcutme
c7a8a3933e
Display standard http error instead of exception on path security error 2018-06-25 14:28:42 +02:00
shortcutme
e1fdb90da6
Reset filters.json before tests 2018-06-25 14:25:19 +02:00
shortcutme
df0562d6b4
Make sure to sanitize request url 2018-06-25 14:23:38 +02:00
shortcutme
9afc39d5f1
Add signing parameters to sitePublish 2018-06-25 14:22:24 +02:00
shortcutme
4a1c4df861
Prefer PEP8 style 2018-06-25 14:13:05 +02:00
shortcutme
b054ed6e03
SiteAdd admin API call 2018-06-25 14:12:13 +02:00
shortcutme
8a02a51d0c
Rev3478 2018-06-21 21:57:35 +02:00
shortcutme
da64785ea4
Only announce site on http request if not paused 2018-06-21 21:57:25 +02:00
shortcutme
8b91abd0dc
Use FileServer to avoid plugin incompatiblity problems 2018-06-21 21:57:06 +02:00
shortcutme
b6364941a0
Don't start file server twice 2018-06-21 21:56:20 +02:00
shortcutme
4fdd362ed5
Avoid starting multiple discover request for same unknown client 2018-06-21 21:55:32 +02:00
shortcutme
7bff5f562c
Rev3477 2018-06-03 12:47:24 +02:00
shortcutme
3de13a2e6d
Fix tracker statistics 2018-06-03 12:47:17 +02:00
shortcutme
329e885da7
Wait tor connections until tor client startup 2018-06-03 12:46:47 +02:00
shortcutme
d125551c0d
Proritize currently requested site update 2018-06-03 12:46:00 +02:00
shortcutme
250741e431
Fix firefox websocket disconnect on download link click 2018-06-03 12:35:12 +02:00
ZeroNet
22d6a32e4e
Merge pull request #1445 from JeremyRand/trans-proxy
Support accessing ZeroNet via a transparent proxy.
2018-06-02 17:52:12 +02:00
ZeroNet
11c66f6ce4
Merge pull request #1444 from JeremyRand/port-80
Fix 403 error when listening on 127.0.0.1:80.
2018-06-02 17:50:07 +02:00
JeremyRand
4ffd642732
Support accessing ZeroNet via a transparent proxy. 2018-06-02 12:17:10 +00:00
JeremyRand
f7f6b15ef1
Fix 403 error when listening on 127.0.0.1:80. 2018-06-02 10:24:00 +00:00
shortcutme
efcb1715ee
Rev3470 2018-06-01 02:44:10 +02:00
shortcutme
8f5bcdff99
Start file server for cli commands for Tor support. 2018-06-01 02:43:53 +02:00
shortcutme
a0b2a8ba74
Optional connection timeout checker 2018-05-31 19:43:39 +02:00
shortcutme
3013ee083d
Longer timeouts in tor always mode 2018-05-31 19:43:09 +02:00
shortcutme
0ae14f673c
Change skyts tracker address 2018-05-31 19:40:37 +02:00
shortcutme
b4eb09d5e9
Rev3468, Ignore newsfeed items with invalid date_added value 2018-05-30 17:16:45 +02:00
ZeroNet
49d1bc08c3
Merge pull request #1437 from imachug/patch-1
Allow fileQuery as CORS command
2018-05-28 10:47:09 +02:00
ZeroNet
e9e5c41f79
Merge pull request #1439 from imachug/fix-sign-zeroid
Fix signing&publishing file owned by ZeroID/other provider user
2018-05-28 10:38:26 +02:00
Ivanq
fac3721dfd Fix signing&publishing file owned by ZeroID/other provider user. Fixes my old PR lol 2018-05-26 12:15:23 +03:00
Ivanq
e687d5db69
Allow fileQuery as CORS command 2018-05-24 13:16:18 +03:00
ZeroNet
4fa48f7940
Merge pull request #1435 from Radtoo/master
Support dumping sites larger than 2GB by allowing zip64
2018-05-23 13:40:07 +02:00
Radtoo
f7fa770fc5 Support dumping sites larger than 2GB by allowing zip64 2018-05-23 03:48:25 +02:00
ZeroNet
a311366ee7
Merge pull request #1432 from imachug/cors-fix
Add fileList, dirList as CORS commands
2018-05-22 12:16:30 +02:00
ZeroNet
9675ef1293
Merge pull request #1421 from ppsfassa/master
add Japanese
2018-05-22 12:14:42 +02:00
ZeroNet
f004000d5c
Merge pull request #1424 from rwv/patch-1
Update README-zh-cn.md docker conf to port 26552
2018-05-22 12:10:28 +02:00
ZeroNet
9fb7e1b46d
Merge pull request #1413 from saber28/patch-1
Improve Orbot Compatibility
2018-05-22 11:24:27 +02:00
Ivanq
c2f5a12ce1 Add fileList, dirList as CORS commands 2018-05-19 12:15:13 +03:00
Takumi
671fb3476c Re add jp 2018-05-19 17:10:11 +09:00
seedgou
c28a168868
Update README-zh-cn.md docker conf to port 26552 2018-05-17 10:37:45 +08:00
Takumi
3057302baa add Japanese 2018-05-12 17:36:57 +09:00
saber28
94bc33f61c
Improve Orbot Compatibility
Use password auth first to work with orbot
2018-05-05 09:58:14 +08:00
shortcutme
e874730679
Rev3464, Download site as zip 2018-05-02 02:31:31 +02:00
shortcutme
1ae84c11ad
Remove tor files 2018-04-29 15:31:30 +02:00
shortcutme
9cb2bc4825
Rev3465 2018-04-29 14:54:19 +02:00
shortcutme
2bd69b2681
Force reannounce to all trackers after meek bridges enabled 2018-04-29 14:53:31 +02:00
shortcutme
f3b17d4896
Force reannounce if announce is enabled on update 2018-04-29 14:52:56 +02:00
shortcutme
8f5a1ce1b6
Ignore tor data only 2018-04-29 14:52:02 +02:00
shortcutme
2aa0021a08
Rev3463 2018-04-29 13:06:25 +02:00
shortcutme
81ec684025
Show tracker error message on high error percentage 2018-04-29 13:06:07 +02:00
shortcutme
247b89aec5
Fix non-ascii tracker error message logging 2018-04-29 13:05:02 +02:00
shortcutme
8b09a02028
Start ConnectinServer before loading site list 2018-04-29 13:04:38 +02:00
shortcutme
597c5063f3
Rev3462, Fix ConnectionServer testcases 2018-04-29 03:05:36 +02:00
shortcutme
4843719c58
Rev3461 2018-04-29 02:46:11 +02:00
shortcutme
d7c1c0d04c
Tor subprocess check separate function 2018-04-29 02:45:56 +02:00
shortcutme
4fa43fdf60
Trust that shutdown signal will kill tor 2018-04-29 02:45:39 +02:00
shortcutme
cafb9ddcf4
No need to announce if no peer as checkModifications will do 2018-04-29 02:45:10 +02:00
shortcutme
3f6b8def05
Move ConnectionServer listen to separate function to allow TorManager start before connections 2018-04-29 02:44:46 +02:00
shortcutme
40f0ea95ce
Rev3459 2018-04-29 01:02:59 +02:00
shortcutme
ca3b02229f
Fix announcer typo 2018-04-29 01:02:39 +02:00
shortcutme
8039aa3eb1
Report port 1 to trackers as not connectable to improve compatibility 2018-04-29 01:02:24 +02:00
shortcutme
5a494ca50e
Less verbose tracker logging 2018-04-29 01:01:13 +02:00
shortcutme
ef8e8c5a30
New tracker 2018-04-29 01:00:50 +02:00
shortcutme
a19629d105
Start tor_manager with ConnectionServer 2018-04-29 01:00:37 +02:00
shortcutme
6e598c74f5
Fake utorrent peer_id to avoid possible tracker ban 2018-04-29 00:59:45 +02:00
shortcutme
35cf4f3009
Rev3456, Fix SiteAnnouncer import 2018-04-28 22:31:54 +02:00
shortcutme
150d3df9b5
Rev3455 2018-04-28 22:10:26 +02:00
shortcutme
ceff73ee5b
Make AnnounceLocalPlugin and AnnounceZeroPlugin compatible with SiteAnnouncer class 2018-04-28 22:10:16 +02:00
shortcutme
595b2e40d9
Merge ui js, css 2018-04-28 22:08:43 +02:00
shortcutme
9d09401dc1
Rename Permisson Grant to Accept 2018-04-28 22:08:34 +02:00
shortcutme
d9ad3ae2c9
Disabled button formatting 2018-04-28 22:05:51 +02:00
shortcutme
26cb600ae3
Display tor bridge enable button if all tracker connection fails 2018-04-28 22:05:38 +02:00
shortcutme
435210b73c
Add tracker info to loading screen 2018-04-28 22:04:58 +02:00
shortcutme
8dc465f244
Don't readd wrapper_nonce of site size error as we generate a new one on reload 2018-04-28 22:02:29 +02:00
shortcutme
8e708dc02a
Log wrapper nonce errors 2018-04-28 22:02:10 +02:00
shortcutme
b53b6723cc
Allow tor_use_bridges and trackers_proxy to be set with configSet 2018-04-28 22:01:48 +02:00
shortcutme
af4b4ae85c
Get new wrapper nonce API command to proper reload iframe content 2018-04-28 22:01:12 +02:00
shortcutme
0e84bf95da
AnnouncerInfo API command for tracker status 2018-04-28 22:00:15 +02:00
shortcutme
8e93470b94
Add tor bridge info to serverinfo 2018-04-28 21:59:39 +02:00
shortcutme
7cdb1caaf2
Fix websocket sending on error 2018-04-28 21:59:27 +02:00
shortcutme
bf346a6ed1
AnnouncerChanges event channel for websocket for tracker changes 2018-04-28 21:59:12 +02:00
shortcutme
c0101933bd
Call pex announce from announcer class 2018-04-28 21:54:03 +02:00
shortcutme
24a7c26819
Fix tor status logging with foreign languages 2018-04-28 21:53:36 +02:00
shortcutme
13019941b3
Make sure to shutdown tor client if we started it 2018-04-28 21:53:12 +02:00
shortcutme
a0451065a2
Start with bridges if tor_use_bridges enabled 2018-04-28 21:52:01 +02:00
shortcutme
54b87c19b1
Fix TorManager without main module loaded 2018-04-28 21:51:35 +02:00
shortcutme
8828f21f2e
Always create TorManager object with ConnectionServer, move tormanager start to sperate function 2018-04-28 21:51:14 +02:00
shortcutme
7fee135bf5
Check if we can enable meek bridges 2018-04-28 21:50:01 +02:00
shortcutme
b69e466de0
Add loading of new SiteAnnounce class 2018-04-28 21:49:31 +02:00
shortcutme
37fcf2fed7
Fix deletion with missing content.json files 2018-04-28 21:49:12 +02:00
shortcutme
8f69575b95
Fix SiteManager logging message 2018-04-28 21:48:36 +02:00
shortcutme
2f71c2b784
Refactor and move announcer code to separate class 2018-04-28 21:48:21 +02:00
shortcutme
f3a809a495
Fix publish logging message 2018-04-28 21:47:43 +02:00
shortcutme
ad955b157b
My port and ip is no longer necessary for updates 2018-04-28 21:47:33 +02:00
shortcutme
a87b6c7022
Announce on update if no peers 2018-04-28 21:47:11 +02:00
shortcutme
5104d0d250
Always have connectionserver for site 2018-04-28 21:46:50 +02:00
shortcutme
add83c4c7a
Missing content.json is a debug message 2018-04-28 21:45:28 +02:00
shortcutme
42b9ec819b
More verbose dbdict json loading logging 2018-04-28 21:45:13 +02:00
shortcutme
e93f9eb080
Use tor connection for trackers if trackers_proxy enabled 2018-04-28 21:44:06 +02:00
shortcutme
0244db9182
Fix config save line parsing without values 2018-04-28 21:43:22 +02:00
shortcutme
461f9c7ad6
New settings: trackers_proxy, tor_use_bridges 2018-04-28 21:42:57 +02:00
shortcutme
fd8e1ed623
Rev3417 2018-04-18 22:07:14 +02:00
shortcutme
79b89f8a1b
Don't create new user on websocket event 2018-04-18 22:06:58 +02:00
shortcutme
6b33ad8a32
Handle cases when the user does not have site added yet 2018-04-18 22:06:18 +02:00
shortcutme
40cf4f2c2a
Don't override create_user parameter 2018-04-18 22:06:00 +02:00
shortcutme
d5ef1488b2
Merge branch 'master' of https://github.com/HelloZeroNet/ZeroNet 2018-04-18 21:40:33 +02:00
shortcutme
3beab611a3
Rev3415, Fix FireFox wrapper_nonce url injection 2018-04-18 21:40:29 +02:00
ZeroNet
89a67c0749
Merge pull request #1377 from rllola/docker-port
Force the use of port 15441 inside the container
2018-04-18 13:31:34 +02:00
shortcutme
fd842c43a6
Rev3412, Change no longer working trackers 2018-04-18 13:13:20 +02:00
shortcutme
e51788ac05
Make sure that we close UDP sockets of local peer discovery 2018-04-18 13:11:50 +02:00
rllola
9b046ecc75 Change to port 26552 2018-04-18 04:10:11 +02:00
shortcutme
aa68e69a18
Rev3411 2018-04-12 19:28:59 +02:00
shortcutme
2e573e95e5
Fix multiuser plugin deauth 2018-04-12 19:26:44 +02:00
shortcutme
e95bc31def
Fix logging and shutdown 2018-04-12 19:25:50 +02:00
shortcutme
4eb843fd8c
Delay saving users.json 2018-04-12 19:25:13 +02:00
shortcutme
05db08c8d2
Move new site auth address generation to separate function 2018-04-12 19:24:21 +02:00
shortcutme
513de18af5
Remove unused code 2018-04-12 19:22:38 +02:00
shortcutme
151a6ce9e3
UserManager exclusive logging 2018-04-12 19:22:06 +02:00
shortcutme
d4a1764d20
Rev3408, Use fixed 15441 port in tor always mode 2018-04-06 18:18:10 +02:00
ZeroNet
59c6ee7ade
Merge pull request #1378 from imachug/security
Fix mergerSiteAdd typo
2018-04-06 10:48:11 +02:00
Ivanq
4fbfa1d579 Fix mergerSiteAdd typo 2018-04-06 11:40:23 +03:00
shortcutme
5285699a21
Rev3407, Fix connection timeout checker 2018-04-06 00:51:14 +02:00
rllola
75879de47a Force the use of port 15441 inside the container 2018-04-06 00:25:53 +02:00
shortcutme
e23dc5bda3
Rev3406 2018-04-04 15:34:21 +02:00
shortcutme
8998bf85bd
Handle connection errors when running peerPing command 2018-04-04 15:34:07 +02:00
shortcutme
7b1601c840
Ping port 15441 by default 2018-04-04 15:33:39 +02:00
shortcutme
026b6a4b01
Handle shutdown request properly if not file server is running 2018-04-04 15:33:25 +02:00
shortcutme
d927e85eca
ConnectionServer is not running by default 2018-04-04 15:33:02 +02:00
shortcutme
a877a9fd91
Proper cleanup local announcer listener after testcase 2018-04-04 15:31:55 +02:00
shortcutme
abc481604f
Rev3404, Fix bigfile upload 2018-04-04 12:39:46 +02:00
shortcutme
c703458e00
Rev3403, Fix uploading small files with bigfile plugin 2018-04-04 10:24:38 +02:00
tangdou1
75861db84b Update Chinese translation (#1370)
* Update zh.json

* Update zh.json
2018-04-04 03:50:04 +02:00
shortcutme
223957084a
Rev3402 2018-04-03 14:51:11 +02:00
shortcutme
8c0c0868e3
Add SiteCmd CLI command for ZeroFrame API calls 2018-04-03 14:50:58 +02:00
shortcutme
a65d21d7e4
Fix site cleanup after test 2018-04-03 14:50:09 +02:00
shortcutme
82e6bc5d31
Use websocket connection instead of fileserver to execute commands from CLI 2018-04-03 14:49:40 +02:00
shortcutme
09f1ad0625
Add websocket client to allow API command requests from CLI 2018-04-03 14:47:43 +02:00
shortcutme
852aaae52e
Randomize fileserver port 2018-04-03 14:45:04 +02:00
shortcutme
270922b460
Fix implicit ssl connection typo 2018-04-03 14:43:41 +02:00
shortcutme
b39da7e356
Change unreliable trackers 2018-04-03 14:43:12 +02:00
shortcutme
a438803a5a
Change zero.booth.moe tracker to https port 2018-04-03 14:42:16 +02:00
shortcutme
1b8b3cf1ee
Fix site loading with Zeroname plugin 2018-04-03 14:40:47 +02:00
shortcutme
c2176ba27d
Add current fileserver port to stats page 2018-04-03 14:40:29 +02:00
dqwyy
a69f898e12 Update zh-tw.json (#1360)
* Update zh-tw.json

* Update zh-tw.json
2018-03-31 18:21:28 +02:00
shortcutme
0139d862b5
Rev3395 2018-03-29 03:20:08 +02:00
shortcutme
0459c75dc0
Make file verification process handle correctly different files with same has_id by using new isDownloaded function 2018-03-29 03:19:26 +02:00
shortcutme
547242b1cb
Make siteVerify CLI command compatible with new verifyFiles return value 2018-03-29 03:17:45 +02:00
shortcutme
b8d83c7ec4
Mark site with has_bigfile if new bigfile found 2018-03-29 03:16:47 +02:00
shortcutme
5c644d1b36
Make Bigfile plugin compatible with optionalDownloaded changes 2018-03-29 03:15:49 +02:00
shortcutme
7d3d0f7ceb
Add test for different files with same hash_id 2018-03-29 03:13:37 +02:00
shortcutme
101d2ea9b6
Check optional file downloaded status from sql if optionalmanager is present 2018-03-29 02:59:59 +02:00
shortcutme
af7c7da735
Optional file downloaded checking by separate function 2018-03-29 02:59:11 +02:00
shortcutme
c1397bbaf7
Attach optionalmanager events to ContentManager instead of WorkerManager 2018-03-29 02:58:24 +02:00
shortcutme
16a9f38844
Use renamed optionalRemoved function 2018-03-29 02:57:06 +02:00
shortcutme
508d2472e9
Only verify content after valid signiture 2018-03-29 02:55:53 +02:00
shortcutme
f162987a4f
Rename optionalRemove to optionalRemoved and accept hash only by id 2018-03-29 02:54:52 +02:00
shortcutme
17be72e55e
Process delayed queries every second 2018-03-29 02:50:23 +02:00
shortcutme
d61cd96d8f
VerifyFiles call returns more detailed statistics 2018-03-29 02:49:06 +02:00
shortcutme
6daf583b4b
Only log detailed message type error with debug_socket argument 2018-03-29 02:45:33 +02:00
shortcutme
b23a4c8288
Only apply outline to iframe when sidebar opened 2018-03-29 02:44:43 +02:00
shortcutme
b1240426cd
For 3d rending to progress bar 2018-03-29 02:44:00 +02:00
shortcutme
30ab2cf9a7
Transform progressbar with scale instead of changing width 2018-03-29 02:42:57 +02:00
shortcutme
0c985a5fda
Use current user cert to query file rules for non-existent files 2018-03-29 02:41:30 +02:00
shortcutme
049d326836
Test optionalmanager with travis 2018-03-29 02:39:51 +02:00
ZeroNet
960bf3f3bf
Merge pull request #1328 from tangdou1/patch-1
update Chinese translation (simplified) for new functions
2018-03-22 01:30:18 +01:00
ZeroNet
edf959f26d
Merge pull request #1329 from tangdou1/patch-2
update Chinese translation (traditional) for new functions
2018-03-22 01:29:59 +01:00
shortcutme
077d9d3918
Increase selenium test timeouts 2018-03-21 21:40:44 +01:00
shortcutme
76c4a6bb7c
Rev3377, Fix sidebar animation 2018-03-21 18:05:22 +01:00
shortcutme
ee81aea2fa
Wait until title in link security test 2018-03-20 22:27:32 +01:00
shortcutme
0cf6fb2c9d
Rev3376 2018-03-20 21:59:34 +01:00
shortcutme
9d3913ed70
Also delete piecemap on bigfile deletion 2018-03-20 21:58:51 +01:00
shortcutme
d275dfea2f
Log 403 error as error 2018-03-20 21:55:45 +01:00
shortcutme
11d8485399
Move file modification permission check to separate function 2018-03-20 21:55:12 +01:00
shortcutme
6b926b12a4
Don't try to delete optional file twice on fileDelete API command 2018-03-20 21:54:33 +01:00
shortcutme
9adec79401
Formatting 2018-03-20 21:53:39 +01:00
shortcutme
c3b146611b
Rev3372, Cosmetic changes on open site directory button 2018-03-19 16:05:14 +01:00
ZeroNet
a454f3de6e
Merge pull request #1325 from imachug/show-directory
Add "Open site directory" button
2018-03-19 15:56:02 +01:00
shortcutme
b29d17d39a
Rev3371 2018-03-19 02:58:53 +01:00
shortcutme
ff3fdd4c72
Get privatekey from master seed CLI action 2018-03-19 02:58:38 +01:00
shortcutme
0533f29e7a
Only recover file piecefield if we already hashed it 2018-03-19 02:57:54 +01:00
shortcutme
75adfebf9f
Rev3370 2018-03-18 21:27:35 +01:00
shortcutme
e96435378a
Fix typo 2018-03-18 21:27:26 +01:00
shortcutme
ccdfe77356
Display more detailed info on content sign error 2018-03-18 21:27:04 +01:00
shortcutme
adf39b6f6a
Avoid loading user content.json file on isArchived check 2018-03-18 21:26:20 +01:00
shortcutme
ad1d81dccf
Cache inner_path to sha512 hash for bigfiles to avoid loading content.json every time 2018-03-18 21:25:28 +01:00
shortcutme
8828629a30
Merge branch 'master' of https://github.com/HelloZeroNet/ZeroNet 2018-03-14 22:34:48 +01:00
shortcutme
1ead9b59ba
Rev3367 2018-03-14 22:34:27 +01:00
shortcutme
c401cabee7
Only start separate HS for every site in tor always mode 2018-03-14 22:33:41 +01:00
shortcutme
1549f2aa4d
Don't share global HS with any site 2018-03-14 22:33:21 +01:00
shortcutme
89beb12d59
Set up HS for global at startup 2018-03-14 22:32:49 +01:00
shortcutme
4083e552fd
Formatting 2018-03-14 22:32:28 +01:00
shortcutme
3d7dea52a0
Always load my sites from sites.json 2018-03-14 22:32:15 +01:00
shortcutme
c5f77a1c38
Handle global onion address correctly in needConnections 2018-03-14 22:31:58 +01:00
shortcutme
3561ddf7d3
Do check needConnection for evey site after startup to have up to date protected ip list 2018-03-14 22:31:21 +01:00
shortcutme
81e96d25ba
Handle request using global onion address 2018-03-14 22:30:08 +01:00
shortcutme
1ad966bd80
In passive mode if we have send onion address for every connection not just for tor network 2018-03-14 22:29:00 +01:00
shortcutme
4f472982da
Use broken ssl ip list instead of peer_id 2018-03-14 22:26:59 +01:00
shortcutme
f1396b65b9
Blacklist myself on peer id match 2018-03-14 22:26:08 +01:00
shortcutme
ba12489c34
Log my and remote handshake 2018-03-14 22:25:53 +01:00
shortcutme
4586d3be78
Send my local time as int in the handshake 2018-03-14 22:25:27 +01:00
shortcutme
2204e0cf9c
Fix message parsing after data left in unpacker 2018-03-14 22:24:38 +01:00
shortcutme
8787774764
Use implicit ssl for connections 2018-03-14 22:24:06 +01:00
shortcutme
feb00d5b8a
Option to force encryption to all outgoing connection 2018-03-14 22:22:45 +01:00
shortcutme
660fc982ca
Fix packed file request 2018-03-14 22:22:04 +01:00
shortcutme
1189c76691
Add existing bigfiles to piecefield if they were downloaded outside of ZeroNet 2018-03-14 22:21:45 +01:00
tangdou1
27a3414a27
Update zh-tw.json for new function 2018-03-13 16:12:04 +08:00
tangdou1
4d717a5c19
Update zh.json for new functions
Update zh.json for new functions --"Sign and publish" and incoming function "Open site directory"
2018-03-13 15:17:58 +08:00
tangdou1
e7744eace9
update zh.json
update zh.json for incoming "Open site directory" function
2018-03-13 15:05:44 +08:00
ZeroNet
3bdb6a237f
Merge pull request #1326 from imachug/siteinfo-cors
'siteInfo' can be used as 'actionAs' argument for CORS sites
2018-03-11 09:47:05 +01:00
Ivanq
98dc46e01a 'siteInfo' can be used as 'actionAs' argument for CORS sites 2018-03-11 11:21:54 +03:00
Ivanq
a88f56bec3 Add 'Open site directory' button 2018-03-11 11:14:17 +03:00
shortcutme
fbc10b8e32
Rev3356 2018-03-10 02:06:09 +01:00
shortcutme
42fd7b216d
Don't allow siteSetAutodownloadBigfileLimit for proxies 2018-03-10 02:05:03 +01:00
shortcutme
511731f0b4
Add current timestamp to handshake for future time consensus feature 2018-03-10 02:04:14 +01:00
shortcutme
ad23021b29
More correct title for bad files on sidebar 2018-03-10 02:03:30 +01:00
shortcutme
05a37b3a9c
Display local peers number in sidebar 2018-03-10 02:03:12 +01:00
shortcutme
8ca368f9c7
Bigfile autodownload size limit field to sidebar 2018-03-10 02:02:58 +01:00
shortcutme
dd924f389f
Display and change per-site bigfile autodownload with sidebar 2018-03-10 02:01:49 +01:00
shortcutme
bbb54d6a6a
Support per site max autodownload bigfile size limit changing via API 2018-03-10 02:00:51 +01:00
shortcutme
96e9cc9c32
Correct cli settings help 2018-03-10 02:00:12 +01:00
shortcutme
b1f16857fc
Support per-site auto download bigfile size limit 2018-03-10 01:59:55 +01:00
shortcutme
738fd1a09b
Rev3354, Fix ajax loading files from archives 2018-03-09 15:01:45 +01:00
shortcutme
645249afa9
Rev3353, Pass arguments of storage walk, Email notify of build fail 2018-03-08 14:27:40 +01:00
shortcutme
a51d794885
Rev3352 2018-03-08 14:20:18 +01:00
shortcutme
9d1f491a89
More visible sidebar scrollbar 2018-03-08 14:19:42 +01:00
shortcutme
e8a0d56ff8
Support fileList command of archives 2018-03-08 14:18:55 +01:00
shortcutme
7048987157
Rev3351, Fix sites with utf8 title 2018-03-07 10:23:13 +01:00
shortcutme
e03731fd24
Allow html formatting in wrapper prompt display 2018-03-07 03:10:13 +01:00
shortcutme
7097859b79
Rev3350 2018-03-06 12:09:54 +01:00
shortcutme
e87df8a57a
NOSANDBOX is as dangerous as ADMIN command 2018-03-06 12:09:39 +01:00
shortcutme
982fb27f58
Close notification on input enter 2018-03-06 12:07:07 +01:00
shortcutme
0d1a5846a1
Merge sidebar js 2018-03-06 12:06:21 +01:00
shortcutme
b9e79f8d98
Fix sidebar navigation error 2018-03-06 12:05:58 +01:00
shortcutme
666ef49924
sidebarGetHtmlTag is an admin command 2018-03-06 12:05:08 +01:00
shortcutme
d2ea8a001f
Remove unused private key input field from sidebar 2018-03-06 12:04:49 +01:00
shortcutme
16efba2b91
Merge wrapper js 2018-03-06 12:03:10 +01:00
shortcutme
e93b5c3c1c
Create wrapper html tags based on attributes instead of raw html 2018-03-06 12:02:39 +01:00
shortcutme
9dabd1f344
Wrapper escape apos characters 2018-03-06 12:01:39 +01:00
shortcutme
e96dd14e0d
Display wrapper security errors and fix Firefox navigation blank pages 2018-03-06 12:01:21 +01:00
shortcutme
3e970df09b
Simple replace wrapper template variables instead of python formatting to allow use braces 2018-03-06 12:00:30 +01:00
shortcutme
b0a8c4d278
Change http headers from list to dict 2018-03-06 11:58:56 +01:00
shortcutme
b55832df34
Fix local peer discovery SO_REUSEPORT exception on older kernels 2018-03-06 11:51:49 +01:00
shortcutme
4c7013644f
Rev3340 2018-02-27 02:49:04 +01:00
shortcutme
4859ffdf54
We are compatible with every msgpack version again 2018-02-27 02:48:34 +01:00
shortcutme
bca5d8a6c5
Use msgpack pip package everywhere 2018-02-27 02:48:15 +01:00
shortcutme
af57083afd
Handle ip change on onion connection correctly 2018-02-27 02:46:56 +01:00
shortcutme
f10233a0a6
New msgpack compatible stream handling 2018-02-27 02:46:26 +01:00
shortcutme
4b9455e84d
Still not works on latest msgpack 2018-02-23 16:26:27 +01:00
shortcutme
9305612419
Use renamed msgpack pip package instead msgpack-python 2018-02-23 16:05:03 +01:00
shortcutme
357fd895bf
Add msgpack test 2018-02-23 15:44:07 +01:00
shortcutme
d7ae583473
msgpack bug fixed in 0.5.6 2018-02-23 15:43:40 +01:00
shortcutme
f8f4718474
List pip package versions after install 2018-02-23 15:43:21 +01:00
shortcutme
304d2f0874
Due to a bug it does not works on msgpack 0.5.5 2018-02-23 02:25:50 +01:00
shortcutme
bda31aea59
Rev3337, Fix big site download button 2018-02-22 23:34:18 +01:00
shortcutme
dea669ac26
Rev3335 2018-02-21 03:15:16 +01:00
shortcutme
40693471e9
Merge sidebar and wrapper js 2018-02-21 03:15:04 +01:00
shortcutme
bee8aac0cc
Don't allow NOSANDBOX permission on a proxy as it can leak cookies 2018-02-21 03:14:43 +01:00
shortcutme
2f2c49cc47
Make multiuser plugin compatible with wrapper modifications 2018-02-21 03:14:15 +01:00
shortcutme
b57a9f5c58
Make cert selection compatible with wrapper modifications 2018-02-21 03:13:27 +01:00
shortcutme
6afe2dd720
New NOSANDBOX permission to remove sandboxed iframe restrictions 2018-02-21 03:12:51 +01:00
shortcutme
aef3ecc3f2
Stop page load if opener is present 2018-02-21 03:11:50 +01:00
shortcutme
01ce86ce18
Don't display permission request if site already has 2018-02-21 03:10:23 +01:00
shortcutme
99362c78bf
Move handleMessage to separate function 2018-02-21 03:09:48 +01:00
shortcutme
c0bf9a9a76
Add cmd function to Wrapper 2018-02-21 03:09:36 +01:00
shortcutme
1833b3e89f
Remove logging injected html 2018-02-21 03:09:01 +01:00
shortcutme
6b71f91775
Verify mouse and keyboard events to avoid non-user verification on notification prompts 2018-02-21 03:08:52 +01:00
shortcutme
5275988f37
Move isProxyRequest and gotoSite to minimal ZeroFrame wrapper 2018-02-21 03:06:48 +01:00
shortcutme
93162beaa0
Allow to set get parameter to reload 2018-02-21 03:06:21 +01:00
shortcutme
61699c7477
Allow small tag in messages 2018-02-21 03:05:11 +01:00
shortcutme
a1a2434d98
Rename wrapper onLoad to onPageLoad 2018-02-21 03:05:02 +01:00
shortcutme
fd56ddaa54
Remove wrapper object reference before loading iframe to enhance security 2018-02-21 03:03:01 +01:00
shortcutme
c438b9f8a5
Create a restricted ZeroFrame wrapper 2018-02-21 03:02:00 +01:00
shortcutme
91e83b3397
Fix missing earth on sidebar 2018-02-21 03:00:07 +01:00
shortcutme
50bfc8db09
Sidebar save sidebar object to local variable 2018-02-21 02:59:41 +01:00
shortcutme
3d0a20452f
Fix site archived download test 2018-02-20 10:18:35 +01:00
shortcutme
b60e6a7d85
Version 0.6.2 changelog 2018-02-18 06:38:42 +01:00
shortcutme
c5b8495477
Rev3329 2018-02-18 05:49:35 +01:00
shortcutme
809632794f
Allow broadcast to fail 2018-02-18 05:49:26 +01:00
shortcutme
62ecc1cbc1
Rename Unique to site to No certificate 2018-02-18 05:46:49 +01:00
shortcutme
cd822156c9
Rev3328, Fix CLI siteDownload, siteAnnounce, siteNeedFile commands 2018-02-13 13:18:40 +01:00
shortcutme
e85c5e3b36
Rev3327, Add compatbility with new msgpack version 2018-02-13 01:35:21 +01:00
shortcutme
194d57c85f
Run plugin tests until first fail 2018-02-13 00:30:24 +01:00
shortcutme
02ab6d8f59
Rev3326 2018-02-12 17:07:50 +01:00
shortcutme
a548426c39
Formatting 2018-02-12 17:06:36 +01:00
shortcutme
5f851c7880
Maximum 10 findhash in one round 2018-02-12 17:06:18 +01:00
shortcutme
f91e264889
Only try peers that is not working currently 2018-02-12 17:05:58 +01:00
shortcutme
514f8396b7
Add missing import for port checking 2018-02-12 17:05:20 +01:00
shortcutme
d5eac963a9
Increase local peer timeout 2018-02-12 17:04:40 +01:00
shortcutme
c39ff89fab
Read only what we need 2018-02-12 14:28:45 +01:00
shortcutme
3f19f64efd
Properly recover extra data from unpacker 2018-02-12 14:27:38 +01:00
shortcutme
9135a1a1cc
Merge branch 'master' of https://github.com/HelloZeroNet/ZeroNet 2018-02-11 01:48:21 +01:00
shortcutme
39366bfbf1
Rev3323, Fix bigfile download to non-existent directory 2018-02-11 01:48:17 +01:00
ZeroNet
5eeec0a828
Merge pull request #1281 from RedbHawk/master
Added README-ru.md file + new line in original readme.md
2018-02-10 21:19:59 +01:00
RedbHawk
4f28a0f84b Added README-ru.md 2018-02-10 22:51:20 +04:00
shortcutme
56f057143e
Rev3321 2018-02-10 15:34:01 +01:00
shortcutme
39568737dd
Tor connect error and uPnP punch error are not critical 2018-02-10 15:33:54 +01:00
shortcutme
13e0d9b306
Configurable file logging level 2018-02-10 15:32:13 +01:00
shortcutme
d6b7159db1
Rev3319 2018-02-10 01:09:16 +01:00
shortcutme
2575476086
Some trackers does not accept port 0, so we send port 1 as not-connectable 2018-02-10 01:08:31 +01:00
shortcutme
211d68f590
Only parse dict result from udp tracker 2018-02-10 01:08:20 +01:00
shortcutme
3e51b888cb
Add left bytes to request to improve tracker compatibility 2018-02-10 01:04:23 +01:00
shortcutme
ff8f41c1eb
Request less peers in update mode 2018-02-10 01:03:49 +01:00
shortcutme
c6fd61ddf3
Don't display warnings if not in debug mode 2018-02-10 01:01:15 +01:00
shortcutme
9ca4b823bb
Add tracker countries 2018-02-10 01:00:50 +01:00
shortcutme
f513737628
Change to more reliable trackers 2018-02-10 01:00:35 +01:00
shortcutme
90051972d4
Don't log BroadcastServer shutdown socket closing 2018-02-10 00:58:42 +01:00
shortcutme
6fa37c618b
Fix announce time limit typo 2018-02-10 00:58:05 +01:00
shortcutme
47db295088
Rev3318 2018-02-09 17:47:58 +01:00
shortcutme
6405ca5cef
Start LocalAnnouncer for testing 2018-02-09 17:47:18 +01:00
shortcutme
2ba74d9232
Don't start broadcast server by default on testing 2018-02-09 17:46:33 +01:00
shortcutme
ed09595a87
More verbose logging on BroadcastServer shutdown 2018-02-09 17:46:09 +01:00
shortcutme
7c35bcdead
Don't response if server is stopped 2018-02-09 17:45:43 +01:00
shortcutme
189627c89e
Handle situation when binding fails 2018-02-09 17:45:12 +01:00
shortcutme
07bf8ef3b1
Allow udp port reuse 2018-02-09 17:44:53 +01:00
shortcutme
32d902d37f
Send discover request delayed on unknown peer discover request to allow the reponse arrive first 2018-02-09 17:43:33 +01:00
shortcutme
3028a8ebc9
Rev3313, Remove local announcer binding to ip to make test pass on linux 2018-02-09 14:15:43 +01:00
shortcutme
5c503203dc
Add automatized test of AnnounceLocal 2018-02-09 11:53:39 +01:00
shortcutme
644f65b5e4
Version 0.6.2, Rev3312 2018-02-09 11:42:44 +01:00
shortcutme
f593199af7
Add metavar to cli argument help 2018-02-09 11:42:31 +01:00
shortcutme
26a5f12a8e
Generalize local announcer logging 2018-02-09 11:42:17 +01:00
shortcutme
f3257a6743
Fix announcing without local announcer 2018-02-09 11:42:08 +01:00
shortcutme
9f35efc31d
Revert "Version 0.6.2, Rev3310"
This reverts commit 98c6add637.
2018-02-09 11:39:36 +01:00
shortcutme
98c6add637
Version 0.6.2, Rev3310 2018-02-08 18:16:50 +01:00
shortcutme
3904dcda39
Add comment for reputation 2018-02-08 18:15:32 +01:00
shortcutme
6376f7dd56
AnnounceLocal plugin 2018-02-08 18:14:33 +01:00
shortcutme
ae0a78dfb1
Message from local peer does not means internet connection 2018-02-08 18:12:08 +01:00
shortcutme
1ad021ffa9
Fix comment formatting 2018-02-08 18:11:56 +01:00
shortcutme
ee6ab8e82a
Store site manager to file server 2018-02-08 18:11:45 +01:00
shortcutme
b56c985a63
FileServer accept plugins 2018-02-08 18:09:57 +01:00
shortcutme
abbf6ae2c8
Fix peer added count 2018-02-08 18:08:08 +01:00
shortcutme
403ec56ef8
Remove from recent peers of peer remove 2018-02-08 18:07:09 +01:00
shortcutme
a6e67fa9c3
Generalized tracker result log format for pex 2018-02-08 18:06:45 +01:00
shortcutme
b6a401d697
Get loading status based on property 2018-02-08 18:06:19 +01:00
shortcutme
23be1d18a4
Store site list change time 2018-02-08 18:05:50 +01:00
shortcutme
d721d459eb
Sites always a dict to keep the reference 2018-02-08 18:05:23 +01:00
shortcutme
e1dd0f0979
Only recover sites from sites.json that had peers 2018-02-08 18:04:41 +01:00
shortcutme
866947c445
Fix symlinked data site deletion 2018-02-08 18:03:55 +01:00
shortcutme
8ff3bbc9a7
Local ip not added to ips 2018-02-08 18:02:40 +01:00
shortcutme
498191261c
Don't log local ips on query 2018-02-08 18:02:25 +01:00
shortcutme
f9091ea951
Don't connect to myself 2018-02-08 18:01:48 +01:00
shortcutme
8b9d75d726
Don't mark passive local connections as not connectable 2018-02-08 18:01:34 +01:00
shortcutme
7e4a4459b4
Don't multiplex local connection 2018-02-08 17:59:27 +01:00
shortcutme
70fd33e587
Message from local peer does not means internet connection 2018-02-08 17:58:44 +01:00
shortcutme
a265c2a7ca
Pass peer discovery source to addPeer 2018-02-08 17:57:26 +01:00
shortcutme
fee5766abf
Move config import to right place 2018-02-08 17:54:38 +01:00
shortcutme
03573e46f5
Use pregenerated address hash 2018-02-08 17:54:27 +01:00
shortcutme
64b4789bc1
Generalize tracker logging 2018-02-08 17:54:09 +01:00
shortcutme
13e651c822
Store and prefer recent peers from trackers and local peer discovery 2018-02-08 17:53:17 +01:00
shortcutme
7d3fd6f5b6
Only add recent peers if there is more 2018-02-08 17:51:44 +01:00
shortcutme
0c91fd396e
De-duplicate peers before publishing 2018-02-08 17:51:10 +01:00
shortcutme
1827e1e033
Force announce on startup 2018-02-08 17:50:40 +01:00
shortcutme
771dce4c8c
Pre-generate site address hash 2018-02-08 17:50:23 +01:00
shortcutme
ab2fe909f0
Prefer connected workers 2018-02-08 17:49:40 +01:00
shortcutme
6fb9c6ef05
Rev3234, Ignore unknown characters from connection logging 2018-01-30 18:59:26 +01:00
shortcutme
9b41950e4c
Rev3233 2018-01-30 14:29:57 +01:00
shortcutme
bc09b6280b
Add index.html as default inner_path to uirequest 2018-01-30 14:29:38 +01:00
shortcutme
3e7a4f593a
Fix tor PEX test as private peers no longer got exchanged 2018-01-30 14:29:10 +01:00
shortcutme
679a88c095
Rev3232 2018-01-30 14:00:39 +01:00
shortcutme
97d1d0d63b
Fix cleanup sites with no modified date 2018-01-30 13:59:59 +01:00
shortcutme
ee30f78ab0
Fix logging utf8 chars in connections 2018-01-30 13:59:39 +01:00
shortcutme
566b689ca6
Don't connect to private ip addresses in tor always mode 2018-01-30 13:59:18 +01:00
shortcutme
c2edbb30b5
Don't send private ip addresses on pex 2018-01-30 13:58:01 +01:00
shortcutme
a6f86329c5
Merge branch 'master' of https://github.com/HelloZeroNet/ZeroNet 2018-01-28 16:44:56 +01:00
shortcutme
05c1df81ad
Rev3230 2018-01-28 16:44:52 +01:00
shortcutme
327badb3ca
Allow dbQuery and userGetSettings for Cors permissioned sites 2018-01-28 16:44:23 +01:00
shortcutme
335a7a76b1
Remove unnecessary imports from cors plugin 2018-01-28 16:43:50 +01:00
shortcutme
1566da1f8f
MergerSite plugin pass other arguments of hasSitePermission 2018-01-28 16:43:23 +01:00
shortcutme
1250b45694
Fix bigfile info on non-existent files 2018-01-28 16:42:56 +01:00
shortcutme
48e8b956d2
Only add myself to connect blacklist if running other cli action 2018-01-28 16:42:23 +01:00
shortcutme
56e80f7c0c
Add per-cmd site permission query 2018-01-28 16:41:42 +01:00
ZeroNet
bd6cb3e5be
Merge pull request #1267 from valkheim/master
Fix git directory name
2018-01-28 13:31:17 +01:00
Charles Paulet
f2db4b2d1b Fix git directory name 2018-01-28 13:26:28 +01:00
shortcutme
4a823c57d5
Rev3229 2018-01-27 12:25:03 +01:00
shortcutme
2f74f64d65
Longer timeout for updates and large files before other peers started working on it 2018-01-27 12:24:50 +01:00
shortcutme
d44677e46f
Don't keep connections for sites that not modified in last week 2018-01-27 12:21:25 +01:00
shortcutme
4afb6b3d9c
Limit connections to 512 by default 2018-01-27 12:20:40 +01:00
shortcutme
18d3e8905e
Longer timeout for tor peers 2018-01-27 12:19:57 +01:00
shortcutme
fd14a4ac80
Don't create connection to blacklisted peer 2018-01-27 12:19:37 +01:00
shortcutme
cc48a0ad86
Turn on gevent block logging by default 2018-01-27 12:15:18 +01:00
shortcutme
aad1a836db
Fix date of 0.6.1 release 2018-01-25 16:24:09 +01:00
shortcutme
3d3bcaba7a
Changelog for 0.6.1 2018-01-25 16:23:05 +01:00
ZeroNet
201169c4d7
Merge pull request #1254 from AceLewis/master
Gratipay shut down so removing
2018-01-22 10:45:02 +01:00
Alexander Lewis
1ff6c701e8 Gratipay shut down so removing
Gratipay shut down so people can't donate to the project through it
anymore.
2018-01-22 10:40:49 +01:00
shortcutme
3fb9f900f6
Rev3225, Handle correctly and test out of range bigfile requests 2018-01-21 18:56:30 +01:00
shortcutme
9c4093dc7c
Rev3224, Small cosmetic changes on sidebar Sign and publish button 2018-01-21 18:14:12 +01:00
ZeroNet
acfe4deacf
Merge pull request #1231 from imachug/issue-1229
Sign & Publish in one button
2018-01-21 17:50:39 +01:00
shortcutme
342f9f6096
Rev3223, Fix error when using ip wihout city entry 2018-01-20 12:11:43 +01:00
shortcutme
f5b4936197
Merge branch 'master' of https://github.com/HelloZeroNet/ZeroNet 2018-01-20 11:49:21 +01:00
shortcutme
0c6c7d2725
Rev 3222, Use eval in bench for older pytyhon compatibility, Remove unnecessary print from chart archive 2018-01-20 11:49:17 +01:00
ZeroNet
136772073d
Merge pull request #1102 from zwgshr/master
Fix the import path
2018-01-20 00:36:35 +01:00
shortcutme
f5846853b3
Bump rev in config 2018-01-19 13:52:27 +01:00
shortcutme
6db011d807
Rev3221, Revert to afterLoad execution immediately after plugins loaded to avoid problems with plugins 2018-01-19 02:51:16 +01:00
shortcutme
fe59352800
Version 0.6.1, Rev3220 2018-01-19 02:34:32 +01:00
shortcutme
dedf6cd92f
Support initial calls for console bench function 2018-01-19 02:32:44 +01:00
shortcutme
99fdbcd1fe
Fix ratelimit test 2018-01-19 02:32:11 +01:00
shortcutme
005358f4bf
Use separate db connection for rebuilding 2018-01-19 02:31:46 +01:00
shortcutme
ea1cd63929
Log hashfield change time on send 2018-01-19 02:30:52 +01:00
shortcutme
c8ac4c0278
Update content update time after successful listmodifications 2018-01-19 02:29:18 +01:00
shortcutme
49a332724e
No connected peers if no connection server 2018-01-19 02:27:40 +01:00
shortcutme
a21c417c0b
Better announce logging 2018-01-19 02:27:19 +01:00
shortcutme
155f05cb63
Trigger onLoaded after config loaded 2018-01-19 02:27:00 +01:00
shortcutme
6d644922d5
Don't display greenlet errors twice 2018-01-19 02:24:29 +01:00
shortcutme
b0a125c113
Ignore case in file merge order 2018-01-19 02:23:33 +01:00
shortcutme
d17cb3fafc
Helper for avg calculation 2018-01-19 02:21:54 +01:00
shortcutme
814fa881d0
skip on invalid received hash ids 2018-01-19 02:20:20 +01:00
shortcutme
fd451ae766
Make indexes and tables optional 2018-01-19 02:18:40 +01:00
shortcutme
089bb92f70
Record last query time on every command 2018-01-19 02:18:19 +01:00
shortcutme
5b6e1f699d
Add db id to logging 2018-01-19 02:17:23 +01:00
shortcutme
03c469ff3a
Formatting 2018-01-19 02:16:50 +01:00
shortcutme
c122dc108a
Record received and sent requests 2018-01-19 02:16:33 +01:00
shortcutme
22c682f393
Move peer location query to separate function, optimize location cache 2018-01-19 02:15:43 +01:00
shortcutme
d7b6c54b08
Move get used optional file size to separate function 2018-01-19 02:14:29 +01:00
shortcutme
a715650af6
Only spawn close archive once 2018-01-19 02:13:59 +01:00
shortcutme
a72da8af56
Chart plugin 2018-01-19 02:13:17 +01:00
ZeroNet
9b3a50c124
Merge pull request #1240 from imachug/issue-1239
Don't handle `open` or `success` in error message as a sign of port being opened
2018-01-14 10:24:21 +01:00
Ivanq
5d7b8cfd48 Return dict object, not single None value 2018-01-14 09:38:55 +03:00
Ivanq
6318c0889a Don't check error message for 'open' when checking port 2018-01-14 09:35:03 +03:00
shortcutme
0aae28e836
Rev3179 2018-01-05 20:23:35 +01:00
shortcutme
b298571395
Change unreliable tracker 2018-01-05 20:23:29 +01:00
shortcutme
4f6a496c36
Test named db select arguments 2018-01-05 20:22:56 +01:00
shortcutme
a3a7af73bd
Fix named db query list parameters when query ends with parameter 2018-01-05 20:22:25 +01:00
ZeroNet
520fd6e063
Merge pull request #1230 from imachug/db-array
Handle :param being an array
2018-01-05 20:19:52 +01:00
Ivanq
bcc3b4d3ac Add sign/publish code 2017-12-31 19:48:28 +03:00
Ivanq
5ff8d6be38 Set font 2017-12-31 19:42:27 +03:00
Ivanq
0f5658e65e Handle clicking ':' 2017-12-31 18:56:17 +03:00
Ivanq
b89eb4f1e8 Make button and style ':' sign 2017-12-31 18:01:54 +03:00
Ivanq
9546817ad2 Add menu 2017-12-31 16:16:02 +03:00
Ivanq
6a31ce3e2e Add vertical line 2017-12-30 22:01:52 +03:00
Ivanq
905095317c Update all.js 2017-12-30 21:46:53 +03:00
Ivanq
d8ff0e1745 Add return false 2017-12-30 21:45:55 +03:00
Ivanq
f9ac614147 Autoscroll 2017-12-30 19:22:49 +03:00
Ivanq
581a18f83d 'Publish' cuts off 2017-12-30 18:39:07 +03:00
Ivanq
f2c76c0a3b Lowercase 2017-12-30 17:45:19 +03:00
Ivanq
7121a96ebd Simple realisation 2017-12-30 17:43:56 +03:00
Ivanq
8986d8037a Typos 2017-12-30 12:16:16 +03:00
Ivanq
d97631fb8c str() 2017-12-30 12:06:07 +03:00
Ivanq
be1eb14fd0 Handle dict value being a list 2017-12-30 10:06:05 +03:00
shortcutme
92e353be40
Rev3178, Skip sites with not database in newsfeed 2017-12-27 11:09:16 +01:00
shortcutme
c595ba3dc0
Send email on failed tests 2017-12-27 11:07:49 +01:00
shortcutme
ccd002b97f
Rev3177, Import missing SafeRe module 2017-12-20 23:35:49 +01:00
shortcutme
c7d067ea3c
Rev3176, Skip listing ignored directories on signing 2017-12-20 23:25:25 +01:00
ZeroNet
adbf787bd4
Merge pull request #1205 from imachug/union
Parse both UNION and UNION ALL
2017-12-19 20:53:21 +01:00
shortcutme
7ee5cbe473
Rev3175, Make getConnectablePeers return not-connected peers by default 2017-12-19 16:14:13 +01:00
shortcutme
c9c1d10ee4
Rev3173, Don't display Cors permission ask if already has, Fix error on Cors request on non-existent site 2017-12-18 02:37:09 +01:00
shortcutme
b5452bce6b
Rev3171, Allow 127.0.0.1 peers for testing reasons 2017-12-15 12:28:48 +01:00
shortcutme
6628b07bba
Rev3170 2017-12-15 12:14:09 +01:00
shortcutme
8f34afc630
Send websocket update on site limit change 2017-12-15 12:13:35 +01:00
shortcutme
1ac69ae315
New UiWebsocket API command to run commands as other site 2017-12-15 12:13:19 +01:00
shortcutme
8a331e7400
UiWebsocket handleRequest takes parsed request intead of raw message 2017-12-15 12:11:27 +01:00
shortcutme
ca42740e1b
Don't add peer 127.0.0.1 and 0.0.0.0 2017-12-15 12:10:36 +01:00
shortcutme
1d5c0597d9
Ignore site list order 2017-12-15 01:58:57 +01:00
Ivanq
7576e60797 Parse both UNION and UNION ALL 2017-12-14 22:15:12 +03:00
shortcutme
acc734d22d
Rev3167, Fix newsfeed queries with multiple params 2017-12-12 23:46:05 +01:00
shortcutme
8ab7d26cd1
Rev3165, Avoid UI block when rubilding a merger site 2017-12-12 11:06:32 +01:00
shortcutme
e86375f721
Rev3164 2017-12-11 19:56:37 +01:00
shortcutme
fde44d78d7
Rev3164, Skip feed if no site for it 2017-12-11 19:35:27 +01:00
shortcutme
a2567277c6
Rev3163 2017-12-11 19:21:41 +01:00
shortcutme
feda6f88ff
Add Newsfeed query time statistics 2017-12-11 19:21:17 +01:00
shortcutme
74e5f5310b
Rev3161 2017-12-07 15:25:50 +01:00
shortcutme
51fdf95295
Allow ajax ranged requests 2017-12-07 15:25:32 +01:00
shortcutme
0009b1b7d1
Allow site fullscreen functions 2017-12-07 15:23:51 +01:00
shortcutme
74e50e209a
Rev3158, Fix site clone with sites larger that 10MB 2017-12-04 16:04:10 +01:00
shortcutme
1208294747
Remove unused variable, more clear comment on state object 2017-12-02 15:35:32 +01:00
shortcutme
3de182a4ed
Rev3157, Fix websocket utf8 error when requesting files from different sites at the same time 2017-12-02 15:31:36 +01:00
shortcutme
90ff9ac7fb
Rev3155, Avoid UI hang during db rebuild 2017-12-02 02:38:17 +01:00
shortcutme
6b92d011d2
Rev3153, Download missing sites from sites.json 2017-11-30 19:38:56 +01:00
shortcutme
8b9a8997ac
Rev3151 2017-11-29 13:50:03 +01:00
shortcutme
9df86ecaa9
Show proxy user seed on certficate added instead of first visit 2017-11-29 13:49:41 +01:00
shortcutme
cfeb2797e3
Merge wrapper js 2017-11-29 13:48:30 +01:00
shortcutme
06a50b189d
Use empty placeholder if not specified 2017-11-29 13:48:20 +01:00
shortcutme
7c1a4e353d
Allow inject html command from ui server 2017-11-29 13:48:07 +01:00
shortcutme
2b611ae798
Rev3148, Fix big site size calculation 2017-11-28 18:16:37 +01:00
shortcutme
fdd82f7ac4
Rev3146, Limit noparallel queue to one call 2017-11-20 03:13:58 +01:00
shortcutme
ea9d345548
Rev3144 2017-11-19 18:22:28 +01:00
shortcutme
24372470f6
My_ip no longer required to be sent via updates 2017-11-19 18:21:47 +01:00
shortcutme
51f1781df4
Move bad file checking to separate function, root content.json does not requires file_info 2017-11-19 18:21:10 +01:00
shortcutme
972bef4f7d
Add invalid content.json to bad files 2017-11-19 18:19:45 +01:00
shortcutme
a2da8eca68
Master startup by waiting less between site update checks 2017-11-19 18:18:26 +01:00
shortcutme
620d8caea9
Always use peer's real ip instead of reported one using update parameter 2017-11-19 18:18:08 +01:00
ZeroNet
4ddaa9b57f
Merge pull request #1188 from FARHZ/master
Fix logic BigfilePlugin.py
2017-11-19 14:54:36 +01:00
FARHZ
22bb77e7a0
Fix logic BigfilePlugin.py 2017-11-19 10:43:30 -02:00
ZeroNet
3582b2c114
OS X is macOS now 2017-11-19 10:56:53 +01:00
ZeroNet
9db715ee17
Merge pull request #1172 from ajmeese7/master
Update README.md
2017-11-19 10:55:29 +01:00
shortcutme
1aaa1ba975
Issue template for Github 2017-11-18 00:49:44 +01:00
shortcutme
35bd5e8595
UPnP formatting 2017-11-17 18:09:02 +01:00
shortcutme
86e607c403
Catch all exception on uPnP port opening 2017-11-17 18:08:45 +01:00
ZeroNet
c7247fc462
Merge pull request #1179 from Biosias/master
Adding Slovak translation (sk.json)
2017-11-12 18:41:43 +01:00
Biosias
25add764e4
Add files via upload
Adding Slovak translation (sk.json)
2017-11-11 17:26:29 +01:00
shortcutme
7d8490bdcb
Rev3139 2017-11-10 11:16:30 +01:00
shortcutme
f8fe426f70
Filter search query by type 2017-11-10 11:16:08 +01:00
shortcutme
9b61ae44ab
Store search query parameters in separate variable 2017-11-10 11:15:57 +01:00
shortcutme
991e59d0fc
Filter search by site 2017-11-10 11:15:10 +01:00
shortcutme
7f3cf9583c
Find filters in search query 2017-11-10 11:15:01 +01:00
shortcutme
ff7ac90785
Rev3137 2017-11-09 13:33:18 +01:00
shortcutme
b01e381087
Async port opening using different nic ips 2017-11-09 13:33:02 +01:00
shortcutme
5026f1b0a8
Delay RateLimit call after delayed call triggered 2017-11-09 13:32:21 +01:00
shortcutme
9d09890457
Rev3135, Add fileNeed command compatibility to merger sites 2017-11-06 13:16:46 +01:00
shortcutme
4483180569
Rev3134 2017-11-05 23:45:08 +01:00
shortcutme
4465146615
Update server_info on port open status change 2017-11-05 23:43:51 +01:00
shortcutme
3b7750c24e
Send serverChanged event on Tor status change 2017-11-05 23:43:03 +01:00
shortcutme
7962baa2da
Also join to serverChanged channel by default 2017-11-05 23:42:33 +01:00
shortcutme
6f37654303
Send serverChanged event on server_info changes 2017-11-05 23:42:14 +01:00
shortcutme
2781e31be0
Keep track of websocket connections 2017-11-05 23:40:59 +01:00
shortcutme
b39d86d020
serverChanged channel 2017-11-05 23:37:53 +01:00
shortcutme
754a3db1b9
Allow multiple channel joins by one command 2017-11-05 23:37:32 +01:00
shortcutme
bc1d79a07d
Fix pice_size typo 2017-11-05 23:34:31 +01:00
ZeroNet
8242e91238
Merge pull request #1165 from imachug/dbquery
DbQuery and Newsfeed bug
2017-11-04 13:01:05 +01:00
Aaron Meese
ff24899a62
Update README.md
Added proper hyphenation and changed OSX to OS X
2017-10-30 11:04:56 -05:00
shortcutme
c3250378ee
Rev3128, Allow modals for sites 2017-10-30 15:15:40 +01:00
shortcutme
9d4515954b
Rev3127, Fix UiWebsocket async message response skip 2017-10-29 23:39:36 +01:00
shortcutme
46455737cc
Rev3126 2017-10-28 02:40:42 +02:00
shortcutme
09413f5fc7
Only zoom sidebar globe if mouse button is pressed down 2017-10-28 02:40:35 +02:00
shortcutme
2e74b73ba0
Verify signatures using CLI 2017-10-28 02:39:49 +02:00
Ivanq
818983831a Newsfeed: Add brackets around WHERE 2017-10-26 18:34:53 +03:00
Ivanq
c64e97f0d6 DbQuery: WHERE without AND is still WHERE 2017-10-26 18:32:05 +03:00
shortcutme
9034449e96
Fix fileInfo test 2017-10-26 10:50:56 +02:00
shortcutme
00b6842f35
Rev3125 2017-10-26 10:43:51 +02:00
shortcutme
99e5af67b7
Make BigfileUploadInit merger sites compatible 2017-10-26 10:43:45 +02:00
shortcutme
e8f049a765
Strip / from content.json location of file_info 2017-10-26 10:43:10 +02:00
shortcutme
53afd97346
Alway start workers for slow tasks 2017-10-26 10:40:41 +02:00
shortcutme
604792a4dd
Call response function for return values of UiWebsocket actions 2017-10-26 10:40:02 +02:00
shortcutme
9b83c683b5
Reload content.json info after bigfile upload 2017-10-26 10:35:46 +02:00
shortcutme
9d511ba165
Rev3122, Auto ignore database file 2017-10-22 11:13:09 +02:00
shortcutme
c519239d87
Add more detail on cli signing error 2017-10-22 11:11:26 +02:00
shortcutme
9f39bee486
Merge branch 'master' of https://github.com/HelloZeroNet/ZeroNet 2017-10-21 11:03:17 +02:00
shortcutme
fa409e63f8
Rev3120 2017-10-21 11:03:09 +02:00
shortcutme
e048fa6c6a
Target 6 connections per site 2017-10-21 11:02:40 +02:00
shortcutme
940d583f9a
Fix site violation bug when using Tor 2017-10-21 11:02:27 +02:00
shortcutme
ed965041e6
Report progress on GeoLite2 download 2017-10-21 11:01:57 +02:00
ZeroNet
1a5e661e14 Merge pull request #1155 from xfq/patch-1
Update README-zh-cn.md
2017-10-18 09:58:25 +02:00
Fuqiao Xue
0f7ed0e04d Update README-zh-cn.md 2017-10-18 12:53:10 +08:00
shortcutme
d50603f722
Rev3114, Add details to permission requests 2017-10-17 17:02:56 +02:00
shortcutme
e3931e8892
Changelog for 0.6.0 2017-10-17 10:52:16 +02:00
张文广
11463dbba5 Fix the import path 2017-08-31 11:45:47 +08:00
467 changed files with 16699 additions and 46864 deletions

View file

@ -0,0 +1,40 @@
name: Build Docker Image on Commit
on:
push:
branches:
- main
tags:
- '!' # Exclude tags
jobs:
build-and-publish:
runs-on: docker-builder
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set REPO_VARS
id: repo-url
run: |
echo "REPO_HOST=$(echo "${{ github.server_url }}" | sed 's~http[s]*://~~g')" >> $GITHUB_ENV
echo "REPO_PATH=${{ github.repository }}" >> $GITHUB_ENV
- name: Login to OCI registry
run: |
echo "${{ secrets.OCI_TOKEN }}" | docker login $REPO_HOST -u "${{ secrets.OCI_USER }}" --password-stdin
- name: Build and push Docker images
run: |
# Build Docker image with commit SHA
docker build -t $REPO_HOST/$REPO_PATH:${{ github.sha }} .
docker push $REPO_HOST/$REPO_PATH:${{ github.sha }}
# Build Docker image with nightly tag
docker tag $REPO_HOST/$REPO_PATH:${{ github.sha }} $REPO_HOST/$REPO_PATH:nightly
docker push $REPO_HOST/$REPO_PATH:nightly
# Remove local images to save storage
docker rmi $REPO_HOST/$REPO_PATH:${{ github.sha }}
docker rmi $REPO_HOST/$REPO_PATH:nightly

View file

@ -0,0 +1,37 @@
name: Build and Publish Docker Image on Tag
on:
push:
tags:
- '*'
jobs:
build-and-publish:
runs-on: docker-builder
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set REPO_VARS
id: repo-url
run: |
echo "REPO_HOST=$(echo "${{ github.server_url }}" | sed 's~http[s]*://~~g')" >> $GITHUB_ENV
echo "REPO_PATH=${{ github.repository }}" >> $GITHUB_ENV
- name: Login to OCI registry
run: |
echo "${{ secrets.OCI_TOKEN }}" | docker login $REPO_HOST -u "${{ secrets.OCI_USER }}" --password-stdin
- name: Build and push Docker image
run: |
TAG=${{ github.ref_name }} # Get the tag name from the context
# Build and push multi-platform Docker images
docker build -t $REPO_HOST/$REPO_PATH:$TAG --push .
# Tag and push latest
docker tag $REPO_HOST/$REPO_PATH:$TAG $REPO_HOST/$REPO_PATH:latest
docker push $REPO_HOST/$REPO_PATH:latest
# Remove the local image to save storage
docker rmi $REPO_HOST/$REPO_PATH:$TAG
docker rmi $REPO_HOST/$REPO_PATH:latest

10
.github/FUNDING.yml vendored Normal file
View file

@ -0,0 +1,10 @@
github: canewsin
patreon: # Replace with a single Patreon username e.g., user1
open_collective: # Replace with a single Open Collective username e.g., user1
ko_fi: canewsin
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: canewsin
issuehunt: # Replace with a single IssueHunt username e.g., user1
otechie: # Replace with a single Otechie username e.g., user1
custom: ['https://paypal.me/PramUkesh', 'https://zerolink.ml/1DeveLopDZL1cHfKi8UXHh2UBEhzH6HhMp/help_zeronet/donate/']

33
.github/ISSUE_TEMPLATE/bug-report.md vendored Normal file
View file

@ -0,0 +1,33 @@
---
name: Bug report
about: Create a report to help us improve ZeroNet
title: ''
labels: ''
assignees: ''
---
### Step 1: Please describe your environment
* ZeroNet version: _____
* Operating system: _____
* Web browser: _____
* Tor status: not available/always/disabled
* Opened port: yes/no
* Special configuration: ____
### Step 2: Describe the problem:
#### Steps to reproduce:
1. _____
2. _____
3. _____
#### Observed Results:
* What happened? This could be a screenshot, a description, log output (you can send log/debug.log file to hello@zeronet.io if necessary), etc.
#### Expected Results:
* What did you expect to happen?

View file

@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for ZeroNet
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

72
.github/workflows/codeql-analysis.yml vendored Normal file
View file

@ -0,0 +1,72 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ py3-latest ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ py3-latest ]
schedule:
- cron: '32 19 * * 2'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'javascript', 'python' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2

51
.github/workflows/tests.yml vendored Normal file
View file

@ -0,0 +1,51 @@
name: tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-20.04
strategy:
max-parallel: 16
matrix:
python-version: ["3.7", "3.8", "3.9"]
steps:
- name: Checkout ZeroNet
uses: actions/checkout@v2
with:
submodules: "true"
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python-version }}
- name: Prepare for installation
run: |
python3 -m pip install setuptools
python3 -m pip install --upgrade pip wheel
python3 -m pip install --upgrade codecov coveralls flake8 mock pytest==4.6.3 pytest-cov selenium
- name: Install
run: |
python3 -m pip install --upgrade -r requirements.txt
python3 -m pip list
- name: Prepare for tests
run: |
openssl version -a
echo 0 | sudo tee /proc/sys/net/ipv6/conf/all/disable_ipv6
- name: Test
run: |
catchsegv python3 -m pytest src/Test --cov=src --cov-config src/Test/coverage.ini
export ZERONET_LOG_DIR="log/CryptMessage"; catchsegv python3 -m pytest -x plugins/CryptMessage/Test
export ZERONET_LOG_DIR="log/Bigfile"; catchsegv python3 -m pytest -x plugins/Bigfile/Test
export ZERONET_LOG_DIR="log/AnnounceLocal"; catchsegv python3 -m pytest -x plugins/AnnounceLocal/Test
export ZERONET_LOG_DIR="log/OptionalManager"; catchsegv python3 -m pytest -x plugins/OptionalManager/Test
export ZERONET_LOG_DIR="log/Multiuser"; mv plugins/disabled-Multiuser plugins/Multiuser && catchsegv python -m pytest -x plugins/Multiuser/Test
export ZERONET_LOG_DIR="log/Bootstrapper"; mv plugins/disabled-Bootstrapper plugins/Bootstrapper && catchsegv python -m pytest -x plugins/Bootstrapper/Test
find src -name "*.json" | xargs -n 1 python3 -c "import json, sys; print(sys.argv[1], end=' '); json.load(open(sys.argv[1])); print('[OK]')"
find plugins -name "*.json" | xargs -n 1 python3 -c "import json, sys; print(sys.argv[1], end=' '); json.load(open(sys.argv[1])); print('[OK]')"
flake8 . --count --select=E9,F63,F72,F82 --show-source --statistics --exclude=src/lib/pyaes/

12
.gitignore vendored
View file

@ -7,9 +7,14 @@ __pycache__/
# Hidden files
.*
!/.forgejo
!/.github
!/.gitignore
!/.travis.yml
!/.gitlab-ci.yml
# Temporary files
*.bak
# Data dir
data/*
@ -18,13 +23,14 @@ data/*
# Virtualenv
env/*
# Tor, downloaded automatically
# Tor data
tools/tor/data
tools/tor/*exe
tools/tor/*dll
# PhantomJS, downloaded manually for unit tests
tools/phantomjs
# ZeroNet config file
zeronet.conf
# ZeroNet log files
log/*

48
.gitlab-ci.yml Normal file
View file

@ -0,0 +1,48 @@
stages:
- test
.test_template: &test_template
stage: test
before_script:
- pip install --upgrade pip wheel
# Selenium and requests can't be installed without a requests hint on Python 3.4
- pip install --upgrade requests>=2.22.0
- pip install --upgrade codecov coveralls flake8 mock pytest==4.6.3 pytest-cov selenium
- pip install --upgrade -r requirements.txt
script:
- pip list
- openssl version -a
- python -m pytest -x plugins/CryptMessage/Test --color=yes
- python -m pytest -x plugins/Bigfile/Test --color=yes
- python -m pytest -x plugins/AnnounceLocal/Test --color=yes
- python -m pytest -x plugins/OptionalManager/Test --color=yes
- python -m pytest src/Test --cov=src --cov-config src/Test/coverage.ini --color=yes
- mv plugins/disabled-Multiuser plugins/Multiuser
- python -m pytest -x plugins/Multiuser/Test --color=yes
- mv plugins/disabled-Bootstrapper plugins/Bootstrapper
- python -m pytest -x plugins/Bootstrapper/Test --color=yes
- flake8 . --count --select=E9,F63,F72,F82 --show-source --statistics --exclude=src/lib/pyaes/
test:py3.4:
image: python:3.4.3
<<: *test_template
test:py3.5:
image: python:3.5.7
<<: *test_template
test:py3.6:
image: python:3.6.9
<<: *test_template
test:py3.7-openssl1.1.0:
image: python:3.7.0b5
<<: *test_template
test:py3.7-openssl1.1.1:
image: python:3.7.4
<<: *test_template
test:py3.8:
image: python:3.8.0b3
<<: *test_template

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "plugins"]
path = plugins
url = https://github.com/ZeroNetX/ZeroNet-Plugins.git

View file

@ -1,26 +1,47 @@
language: python
python:
- 2.7
- 3.4
- 3.5
- 3.6
- 3.7
- 3.8
services:
- docker
cache: pip
before_install:
- pip install --upgrade pip wheel
- pip install --upgrade codecov coveralls flake8 mock pytest==4.6.3 pytest-cov selenium
# - docker build -t zeronet .
# - docker run -d -v $PWD:/root/data -p 15441:15441 -p 127.0.0.1:43110:43110 zeronet
install:
- pip install -U pip wheel
- pip install -r requirements.txt
- pip install --upgrade -r requirements.txt
- pip list
before_script:
- openssl version -a
# Add an IPv6 config - see the corresponding Travis issue
# https://github.com/travis-ci/travis-ci/issues/8361
- if [ "${TRAVIS_OS_NAME}" == "linux" ]; then
sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6';
fi
script:
- python -m pytest plugins/CryptMessage/Test
- python -m pytest plugins/Bigfile/Test
- python -m pytest src/Test --cov=src --cov-config src/Test/coverage.ini
before_install:
- pip install -U pytest mock pytest-cov selenium
- pip install codecov
- pip install coveralls
- docker build -t zeronet .
- docker run -d -v $PWD:/root/data -p 15441:15441 -p 127.0.0.1:43110:43110 zeronet
- catchsegv python -m pytest src/Test --cov=src --cov-config src/Test/coverage.ini
- export ZERONET_LOG_DIR="log/CryptMessage"; catchsegv python -m pytest -x plugins/CryptMessage/Test
- export ZERONET_LOG_DIR="log/Bigfile"; catchsegv python -m pytest -x plugins/Bigfile/Test
- export ZERONET_LOG_DIR="log/AnnounceLocal"; catchsegv python -m pytest -x plugins/AnnounceLocal/Test
- export ZERONET_LOG_DIR="log/OptionalManager"; catchsegv python -m pytest -x plugins/OptionalManager/Test
- export ZERONET_LOG_DIR="log/Multiuser"; mv plugins/disabled-Multiuser plugins/Multiuser && catchsegv python -m pytest -x plugins/Multiuser/Test
- export ZERONET_LOG_DIR="log/Bootstrapper"; mv plugins/disabled-Bootstrapper plugins/Bootstrapper && catchsegv python -m pytest -x plugins/Bootstrapper/Test
- find src -name "*.json" | xargs -n 1 python3 -c "import json, sys; print(sys.argv[1], end=' '); json.load(open(sys.argv[1])); print('[OK]')"
- find plugins -name "*.json" | xargs -n 1 python3 -c "import json, sys; print(sys.argv[1], end=' '); json.load(open(sys.argv[1])); print('[OK]')"
- flake8 . --count --select=E9,F63,F72,F82 --show-source --statistics --exclude=src/lib/pyaes/
after_failure:
- zip -r log.zip log/
- curl --upload-file ./log.zip https://transfer.sh/log.zip
after_success:
- codecov
- coveralls --rcfile=src/Test/coverage.ini
cache:
directories:
- $HOME/.cache/pip
notifications:
email:
recipients:
hello@zeronet.io
on_success: change

View file

@ -1,134 +0,0 @@
## ZeroNet 0.5.1 (2016-11-18)
### 新增
- 多语言界面
- 新插件:为站点 HTML 与 JS 文件提供的翻译助手
- 每个站点独立的 favicon
### 修复
- 并行可选文件下载
## ZeroNet 0.5.0 (2016-11-08)
### 新增
- 新插件:允许在 ZeroHello 列出/删除/固定/管理文件
- 新的 API 命令来关注用户的可选文件,与可选文件的请求统计
- 新的可选文件总大小限制
- 新插件:保存节点到数据库并在重启时保持它们,使得更快的可选文件搜索以及在没有 Tracker 的情况下工作
- 重写 UPnP 端口打开器 + 退出时关闭端口(感谢 sirMackk!
- 通过懒惰 PeerHashfield 创建来减少内存占用
- 在 /Stats 页面加载 JSON 文件统计与数据库信息
### 更改
- 独立的锁定文件来获得更好的 Windows 兼容性
- 当执行 start.py 时,即使 ZeroNet 已经运行也打开浏览器
- 在重载时保持插件顺序来允许插件扩展另一个插件
- 只在完整加载 sites.json 时保存来避免数据丢失
- 将更多的 Tracker 更改为更可靠的 Tracker
- 更少的 findhashid CPU 使用率
- 合并下载大量可选文件
- 更多对于可选文件的其他优化
- 如果一个站点有 1000 个节点,更积极地清理
- 为验证错误使用警告而不是错误
- 首先推送更新到更新的客户端
- 损坏文件重置改进
### 修复
- 修复启动时出现的站点删除错误
- 延迟 WebSocket 消息直到连接上
- 修复如果文件包含额外数据时的数据库导入
- 修复大站点下载
- 修复 diff 发送 bug (跟踪它好长时间了)
- 修复当 JSON 文件包含 [] 字符时随机出现的发布错误
- 修复 siteDelete 与 siteCreate bug
- 修复文件写入确认对话框
## ZeroNet 0.4.1 (2016-09-05)
### 新增
- 更快启动与更少内存使用的内核改变
- 尝试连接丢失时重新连接 Tor
- 侧边栏滑入
- 尝试避免不完整的数据文件被覆盖
- 更快地打开数据库
- 在侧边栏显示用户文件大小
- 依赖 --connection_limit 的并发 worker 数量
### 更改
- 在空闲 5 分钟后关闭数据库
- 更好的站点大小计算
- 允许在域名中使用“-”符号
- 总是尝试为站点保持连接
- 移除已合并站点的合并权限
- 只扫描最后 3 天的新闻源来加快数据库请求
- 更新 ZeroBundle-win 到 Python 2.7.12
### 修复
- 修复重要的安全问题:允许任意用户无需有效的来自 ID 提供者的证书发布新内容,感谢 Kaffie 指出
- 修复在没有选择提供证书提供者时的侧边栏错误
- 在数据库重建时跳过无效文件
- 修复随机弹出的 WebSocket 连接错误
- 修复新的 siteCreate 命令
- 修复站点大小计算
- 修复计算机唤醒后的端口打开检查
- 修复 --size_limit 的命令行解析
## ZeroNet 0.4.0 (2016-08-11)
### 新增
- 合并站点插件
- Live source code reloading: Faster core development by allowing me to make changes in ZeroNet source code without restarting it.
- 为合并站点设计的新 JSON 表
- 从侧边栏重建数据库
- 允许直接在 JSON 表中存储自定义数据:更简单与快速的 SQL 查询
- 用户文件存档:允许站点拥有者存档不活跃的用户内容到单个文件(减少初始同步的时间/CPU/内存使用率)
- 在文件删除时同时触发数据库 onUpdated/update
- 从 ZeroFrame API 请求权限
- 允许使用 fileWrite API 命令在 content.json 存储额外数据
- 更快的可选文件下载
- 使用替代源 (Gogs, Gitlab) 来下载更新
- Track provided sites/connection and prefer to keep the ones with more sites to reduce connection number
### 更改
- 保持每个站点至少 5 个连接
- 将目标站点连接从 10 更改到 15
- ZeroHello 搜索功能稳定性/速度改进
- 提升机械硬盘下的客户端性能
### 修复
- 修复 IE11 wrapper nonce 错误
- 修复在移动设备上的侧边栏
- 修复站点大小计算
- 修复 IE10 兼容性
- Windows XP ZeroBundle 兼容性(感谢中国人民)
## ZeroNet 0.3.7 (2016-05-27)
### 更改
- 通过只传输补丁来减少带宽使用
- 其他 CPU /内存优化
## ZeroNet 0.3.6 (2016-05-27)
### 新增
- 新的 ZeroHello
- Newsfeed 函数
### 修复
- 安全性修复
## ZeroNet 0.3.5 (2016-02-02)
### 新增
- 带有 .onion 隐藏服务的完整 Tor 支持
- 使用 ZeroNet 协议的 Bootstrap
### 修复
- 修复 Gevent 1.0.2 兼容性
## ZeroNet 0.3.4 (2015-12-28)
### 新增
- AES, ECIES API 函数支持
- PushState 与 ReplaceState URL 通过 API 的操作支持
- 多用户 localstorage

View file

@ -1,3 +1,380 @@
### ZeroNet 0.9.0 (2023-07-12) Rev4630
- Fix RDos Issue in Plugins https://github.com/ZeroNetX/ZeroNet-Plugins/pull/9
- Add trackers to Config.py for failsafety incase missing trackers.txt
- Added Proxy links
- Fix pysha3 dep installation issue
- FileRequest -> Remove Unnecessary check, Fix error wording
- Fix Response when site is missing for `actionAs`
### ZeroNet 0.8.5 (2023-02-12) Rev4625
- Fix(https://github.com/ZeroNetX/ZeroNet/pull/202) for SSL cert gen failed on Windows.
- default theme-class for missing value in `users.json`.
- Fetch Stats Plugin changes.
### ZeroNet 0.8.4 (2022-12-12) Rev4620
- Increase Minimum Site size to 25MB.
### ZeroNet 0.8.3 (2022-12-11) Rev4611
- main.py -> Fix accessing unassigned varible
- ContentManager -> Support for multiSig
- SiteStrorage.py -> Fix accessing unassigned varible
- ContentManager.py Improve Logging of Valid Signers
### ZeroNet 0.8.2 (2022-11-01) Rev4610
- Fix Startup Error when plugins dir missing
- Move trackers to seperate file & Add more trackers
- Config:: Skip loading missing tracker files
- Added documentation for getRandomPort fn
### ZeroNet 0.8.1 (2022-10-01) Rev4600
- fix readdress loop (cherry-pick previously added commit from conservancy)
- Remove Patreon badge
- Update README-ru.md (#177)
- Include inner_path of failed request for signing in error msg and response
- Don't Fail Silently When Cert is Not Selected
- Console Log Updates, Specify min supported ZeroNet version for Rust version Protocol Compatibility
- Update FUNDING.yml
### ZeroNet 0.8.0 (2022-05-27) Rev4591
- Revert File Open to catch File Access Errors.
### ZeroNet 0.7.9-patch (2022-05-26) Rev4586
- Use xescape(s) from zeronet-conservancy
- actionUpdate response Optimisation
- Fetch Plugins Repo Updates
- Fix Unhandled File Access Errors
- Create codeql-analysis.yml
### ZeroNet 0.7.9 (2022-05-26) Rev4585
- Rust Version Compatibility for update Protocol msg
- Removed Non Working Trakers.
- Dynamically Load Trackers from Dashboard Site.
- Tracker Supply Improvements.
- Fix Repo Url for Bug Report
- First Party Tracker Update Service using Dashboard Site.
- remove old v2 onion service [#158](https://github.com/ZeroNetX/ZeroNet/pull/158)
### ZeroNet 0.7.8 (2022-03-02) Rev4580
- Update Plugins with some bug fixes and Improvements
### ZeroNet 0.7.6 (2022-01-12) Rev4565
- Sync Plugin Updates
- Clean up tor v3 patch [#115](https://github.com/ZeroNetX/ZeroNet/pull/115)
- Add More Default Plugins to Repo
- Doubled Site Publish Limits
- Update ZeroNet Repo Urls [#103](https://github.com/ZeroNetX/ZeroNet/pull/103)
- UI/UX: Increases Size of Notifications Close Button [#106](https://github.com/ZeroNetX/ZeroNet/pull/106)
- Moved Plugins to Seperate Repo
- Added `access_key` variable in Config, this used to access restrited plugins when multiuser plugin is enabled. When MultiUserPlugin is enabled we cannot access some pages like /Stats, this key will remove such restriction with access key.
- Added `last_connection_id_current_version` to ConnectionServer, helpful to estimate no of connection from current client version.
- Added current version: connections to /Stats page. see the previous point.
### ZeroNet 0.7.5 (2021-11-28) Rev4560
- Add more default trackers
- Change default homepage address to `1HELLoE3sFD9569CLCbHEAVqvqV7U2Ri9d`
- Change default update site address to `1Update8crprmciJHwp2WXqkx2c4iYp18`
### ZeroNet 0.7.3 (2021-11-28) Rev4555
- Fix xrange is undefined error
- Fix Incorrect viewport on mobile while loading
- Tor-V3 Patch by anonymoose
### ZeroNet 0.7.1 (2019-07-01) Rev4206
### Added
- Built-in logging console in the web UI to see what's happening in the background. (pull down top-right 0 button to see it)
- Display database rebuild errors [Thanks to Lola]
- New plugin system that allows to install and manage builtin/third party extensions to the ZeroNet client using the web interface.
- Support multiple trackers_file
- Add OpenSSL 1.1 support to CryptMessage plugin based on Bitmessage modifications [Thanks to radfish]
- Display visual error message on startup errors
- Fix max opened files changing on Windows platform
- Display TLS1.3 compatibility on /Stats page
- Add fake SNI and ALPN to peer connections to make it more like standard https connections
- Hide and ignore tracker_proxy setting in Tor: Always mode as it's going to use Tor anyway.
- Deny websocket connections from unknown origins
- Restrict open_browser values to avoid RCE on sandbox escape
- Offer access web interface by IP address in case of unknown host
- Link to site's sidebar with "#ZeroNet:OpenSidebar" hash
### Changed
- Allow .. in file names [Thanks to imachug]
- Change unstable trackers
- More clean errors on sites.json/users.json load error
- Various tweaks for tracker rating on unstable connections
- Use OpenSSL 1.1 dlls from default Python Windows distribution if possible
- Re-factor domain resolving for easier domain plugins
- Disable UDP connections if --proxy is used
- New, decorator-based Websocket API permission system to avoid future typo mistakes
### Fixed
- Fix parsing config lines that have no value
- Fix start.py [Thanks to imachug]
- Allow multiple values of the same key in the config file [Thanks ssdifnskdjfnsdjk for reporting]
- Fix parsing config file lines that has % in the value [Thanks slrslr for reporting]
- Fix bootstrapper plugin hash reloads [Thanks geekless for reporting]
- Fix CryptMessage plugin OpenSSL dll loading on Windows (ZeroMail errors) [Thanks cxgreat2014 for reporting]
- Fix startup error when using OpenSSL 1.1 [Thanks to imachug]
- Fix a bug that did not loaded merged site data for 5 sec after the merged site got added
- Fix typo that allowed to add new plugins in public proxy mode. [Thanks styromaniac for reporting]
- Fix loading non-big files with "|all" postfix [Thanks to krzotr]
- Fix OpenSSL cert generation error crash by change Windows console encoding to utf8
#### Wrapper html injection vulnerability [Reported by ivanq]
In ZeroNet before rev4188 the wrapper template variables was rendered incorrectly.
Result: The opened site was able to gain WebSocket connection with unrestricted ADMIN/NOSANDBOX access, change configuration values and possible RCE on client's machine.
Fix: Fixed the template rendering code, disallowed WebSocket connections from unknown locations, restricted open_browser configuration values to avoid possible RCE in case of sandbox escape.
Note: The fix is also back ported to ZeroNet Py 2.x version (Rev3870)
### ZeroNet 0.7.0 (2019-06-12) Rev4106 (First release targeting Python 3.4+)
### Added
- 5-10x faster signature verification by using libsecp256k1 (Thanks to ZeroMux)
- Generated SSL certificate randomization to avoid protocol filters (Thanks to ValdikSS)
- Offline mode
- P2P source code update using ZeroNet protocol
- ecdsaSign/Verify commands to CryptMessage plugin (Thanks to imachug)
- Efficient file rename: change file names instead of re-downloading the file.
- Make redirect optional on site cloning (Thanks to Lola)
- EccPrivToPub / EccPubToPriv functions (Thanks to imachug)
- Detect and change dark/light theme based on OS setting (Thanks to filips123)
### Changed
- Re-factored code to Python3 runtime (compatible with Python 3.4-3.8)
- More safe database sync mode
- Removed bundled third-party libraries where it's possible
- Use lang=en instead of lang={lang} in urls to avoid url encode problems
- Remove environment details from error page
- Don't push content.json updates larger than 10kb to significantly reduce bw usage for site with many files
### Fixed
- Fix sending files with \0 characters
- Security fix: Escape error detail to avoid XSS (reported by krzotr)
- Fix signature verification using libsecp256k1 for compressed addresses (mostly certificates generated in the browser)
- Fix newsfeed if you have more than 1000 followed topic/post on one site.
- Fix site download as zip file
- Fix displaying sites with utf8 title
- Error message if dbRebuild fails (Thanks to Lola)
- Fix browser reopen if executing start.py again. (Thanks to imachug)
### ZeroNet 0.6.5 (2019-02-16) Rev3851 (Last release targeting Python 2.7.x)
### Added
- IPv6 support in peer exchange, bigfiles, optional file finding, tracker sharing, socket listening and connecting (based on tangdou1 modifications)
- New tracker database format with IPv6 support
- Display notification if there is an unpublished modification for your site
- Listen and shut down normally for SIGTERM (Thanks to blurHY)
- Support tilde `~` in filenames (by d14na)
- Support map for Namecoin subdomain names (Thanks to lola)
- Add log level to config page
- Support `{data}` for data dir variable in trackers_file value
- Quick check content.db on startup and rebuild if necessary
- Don't show meek proxy option if the tor client does not supports it
### Changed
- Refactored port open checking with IPv6 support
- Consider non-local IPs as external even is the open port check fails (for CJDNS and Yggdrasil support)
- Add IPv6 tracker and change unstable tracker
- Don't correct sent local time with the calculated time correction
- Disable CSP for Edge
- Only support CREATE commands in dbschema indexes node and SELECT from storage.query
### Fixed
- Check the length of master seed when executing cryptGetPrivatekey CLI command
- Only reload source code on file modification / creation
- Detection and issue warning for latest no-script plugin
- Fix atomic write of a non-existent file
- Fix sql queries with lots of variables and sites with lots of content.json
- Fix multi-line parsing of zeronet.conf
- Fix site deletion from users.json
- Fix site cloning before site downloaded (Reported by unsystemizer)
- Fix queryJson for non-list nodes (Reported by MingchenZhang)
## ZeroNet 0.6.4 (2018-10-20) Rev3660
### Added
- New plugin: UiConfig. A web interface that allows changing ZeroNet settings.
- New plugin: AnnounceShare. Share trackers between users, automatically announce client's ip as tracker if Bootstrapper plugin is enabled.
- Global tracker stats on ZeroHello: Include statistics from all served sites instead of displaying request statistics only for one site.
- Support custom proxy for trackers. (Configurable with /Config)
- Adding peers to sites manually using zeronet_peers get parameter
- Copy site address with peers link on the sidebar.
- Zip file listing and streaming support for Bigfiles.
- Tracker statistics on /Stats page
- Peer reputation save/restore to speed up sync time after startup.
- Full support fileGet, fileList, dirList calls on tar.gz/zip files.
- Archived_before support to user content rules to allow deletion of all user files before the specified date
- Show and manage "Connecting" sites on ZeroHello
- Add theme support to ZeroNet sites
- Dark theme for ZeroHello, ZeroBlog, ZeroTalk
### Changed
- Dynamic big file allocation: More efficient storage usage by don't pre-allocate the whole file at the beginning, but expand the size as the content downloads.
- Reduce the request frequency to unreliable trackers.
- Only allow 5 concurrent checkSites to run in parallel to reduce load under Tor/slow connection.
- Stop site downloading if it reached 95% of site limit to avoid download loop for sites out of limit
- The pinned optional files won't be removed from download queue after 30 retries and won't be deleted even if the site owner removes it.
- Don't remove incomplete (downloading) sites on startup
- Remove --pin_bigfile argument as big files are automatically excluded from optional files limit.
### Fixed
- Trayicon compatibility with latest gevent
- Request number counting for zero:// trackers
- Peer reputation boost for zero:// trackers.
- Blocklist of peers loaded from peerdb (Thanks tangdou1 for report)
- Sidebar map loading on foreign languages (Thx tangdou1 for report)
- FileGet on non-existent files (Thanks mcdev for reporting)
- Peer connecting bug for sites with low amount of peers
#### "The Vacation" Sandbox escape bug [Reported by GitCenter / Krixano / ZeroLSTN]
In ZeroNet 0.6.3 Rev3615 and earlier as a result of invalid file type detection, a malicious site could escape the iframe sandbox.
Result: Browser iframe sandbox escape
Applied fix: Replaced the previous, file extension based file type identification with a proper one.
Affected versions: All versions before ZeroNet Rev3616
## ZeroNet 0.6.3 (2018-06-26)
### Added
- New plugin: ContentFilter that allows to have shared site and user block list.
- Support Tor meek proxies to avoid tracker blocking of GFW
- Detect network level tracker blocking and easy setting meek proxy for tracker connections.
- Support downloading 2GB+ sites as .zip (Thx to Radtoo)
- Support ZeroNet as a transparent proxy (Thx to JeremyRand)
- Allow fileQuery as CORS command (Thx to imachug)
- Windows distribution includes Tor and meek client by default
- Download sites as zip link to sidebar
- File server port randomization
- Implicit SSL for all connection
- fileList API command for zip files
- Auto download bigfiles size limit on sidebar
- Local peer number to the sidebar
- Open site directory button in sidebar
### Changed
- Switched to Azure Tor meek proxy as Amazon one became unavailable
- Refactored/rewritten tracker connection manager
- Improved peer discovery for optional files without opened port
- Also delete Bigfile's piecemap on deletion
### Fixed
- Important security issue: Iframe sandbox escape [Reported by Ivanq / gitcenter]
- Local peer discovery when running multiple clients on the same machine
- Uploading small files with Bigfile plugin
- Ctrl-c shutdown when running CLI commands
- High CPU/IO usage when Multiuser plugin enabled
- Firefox back button
- Peer discovery on older Linux kernels
- Optional file handling when multiple files have the same hash_id (first 4 chars of the hash)
- Msgpack 0.5.5 and 0.5.6 compatibility
## ZeroNet 0.6.2 (2018-02-18)
### Added
- New plugin: AnnounceLocal to make ZeroNet work without an internet connection on the local network.
- Allow dbQuey and userGetSettings using the `as` API command on different sites with Cors permission
- New config option: `--log_level` to reduce log verbosity and IO load
- Prefer to connect to recent peers from trackers first
- Mark peers with port 1 is also unconnectable for future fix for trackers that do not support port 0 announce
### Changed
- Don't keep connection for sites that have not been modified in the last week
- Change unreliable trackers to new ones
- Send maximum 10 findhash request in one find optional files round (15sec)
- Change "Unique to site" to "No certificate" for default option in cert selection dialog.
- Dont print warnings if not in debug mode
- Generalized tracker logging format
- Only recover sites from sites.json if they had peers
- Message from local peers does not means internet connection
- Removed `--debug_gevent` and turned on Gevent block logging by default
### Fixed
- Limit connections to 512 to avoid reaching 1024 limit on windows
- Exception when logging foreign operating system socket errors
- Don't send private (local) IPs on pex
- Don't connect to private IPs in tor always mode
- Properly recover data from msgpack unpacker on file stream start
- Symlinked data directory deletion when deleting site using Windows
- De-duplicate peers before publishing
- Bigfile info for non-existing files
## ZeroNet 0.6.1 (2018-01-25)
### Added
- New plugin: Chart
- Collect and display charts about your contribution to ZeroNet network
- Allow list as argument replacement in sql queries. (Thanks to imachug)
- Newsfeed query time statistics (Click on "From XX sites in X.Xs on ZeroHello)
- New UiWebsocket API command: As to run commands as other site
- Ranged ajax queries for big files
- Filter feed by type and site address
- FileNeed, Bigfile upload command compatibility with merger sites
- Send event on port open / tor status change
- More description on permission request
### Changed
- Reduce memory usage of sidebar geoip database cache
- Change unreliable tracker to new one
- Don't display Cors permission ask if it already granted
- Avoid UI blocking when rebuilding a merger site
- Skip listing ignored directories on signing
- In Multiuser mode show the seed welcome message when adding new certificate instead of first visit
- Faster async port opening on multiple network interfaces
- Allow javascript modals
- Only zoom sidebar globe if mouse button is pressed down
### Fixed
- Open port checking error reporting (Thanks to imachug)
- Out-of-range big file requests
- Don't output errors happened on gevent greenlets twice
- Newsfeed skip sites with no database
- Newsfeed queries with multiple params
- Newsfeed queries with UNION and UNION ALL
- Fix site clone with sites larger that 10MB
- Unreliable Websocket connection when requesting files from different sites at the same time
## ZeroNet 0.6.0 (2017-10-17)
### Added
- New plugin: Big file support
- Automatic pinning on Big file download
- Enable TCP_NODELAY for supporting sockets
- actionOptionalFileList API command arguments to list non-downloaded files or only big files
- serverShowdirectory API command arguments to allow to display site's directory in OS file browser
- fileNeed API command to initialize optional file downloading
- wrapperGetAjaxKey API command to request nonce for AJAX request
- Json.gz support for database files
- P2P port checking (Thanks for grez911)
- `--download_optional auto` argument to enable automatic optional file downloading for newly added site
- Statistics for big files and protocol command requests on /Stats
- Allow to set user limitation based on auth_address
### Changed
- More aggressive and frequent connection timeout checking
- Use out of msgpack context file streaming for files larger than 512KB
- Allow optional files workers over the worker limit
- Automatic redirection to wrapper on nonce_error
- Send websocket event on optional file deletion
- Optimize sites.json saving
- Enable faster C-based msgpack packer by default
- Major optimization on Bootstrapper plugin SQL queries
- Don't reset bad file counter on restart, to allow easier give up on unreachable files
- Incoming connection limit changed from 1000 to 500 to avoid reaching socket limit on Windows
- Changed tracker boot.zeronet.io domain, because zeronet.io got banned in some countries
#### Fixed
- Sub-directories in user directories
## ZeroNet 0.5.7 (2017-07-19)
### Added
- New plugin: CORS to request read permission to other site's content

View file

@ -1,7 +1,7 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@ -645,7 +645,7 @@ the "copyright" line and a pointer to where the full notice is found.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
@ -664,11 +664,11 @@ might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
<https://www.gnu.org/licenses/why-not-lgpl.html>.

View file

@ -1,28 +1,33 @@
FROM alpine:3.6
FROM alpine:3.15
#Base settings
ENV HOME /root
COPY requirements.txt /root/requirements.txt
#Install ZeroNet
RUN apk --update upgrade \
&& apk --no-cache --no-progress add musl-dev gcc python python-dev py2-pip tor \
&& pip install gevent msgpack-python \
&& apk del musl-dev gcc python-dev py2-pip \
&& rm -rf /var/cache/apk/* /tmp/* /var/tmp/* \
&& echo "ControlPort 9051" >> /etc/tor/torrc \
&& echo "CookieAuthentication 1" >> /etc/tor/torrc
RUN apk --update --no-cache --no-progress add python3 python3-dev py3-pip gcc g++ autoconf automake libtool libffi-dev musl-dev make tor openssl \
&& pip3 install -r /root/requirements.txt \
&& apk del python3-dev gcc g++ autoconf automake libtool libffi-dev musl-dev make \
&& echo "ControlPort 9051" >> /etc/tor/torrc \
&& echo "CookieAuthentication 1" >> /etc/tor/torrc
RUN python3 -V \
&& python3 -m pip list \
&& tor --version \
&& openssl version
#Add Zeronet source
COPY . /root
VOLUME /root/data
#Control if Tor proxy is started
ENV ENABLE_TOR false
ENV ENABLE_TOR true
WORKDIR /root
#Set upstart command
CMD (! ${ENABLE_TOR} || tor&) && python zeronet.py --ui_ip 0.0.0.0
CMD (! ${ENABLE_TOR} || tor&) && python3 zeronet.py --ui_ip 0.0.0.0 --fileserver_port 26117
#Expose ports
EXPOSE 43110 15441
EXPOSE 43110 26117

34
Dockerfile.arm64v8 Normal file
View file

@ -0,0 +1,34 @@
FROM alpine:3.12
#Base settings
ENV HOME /root
COPY requirements.txt /root/requirements.txt
#Install ZeroNet
RUN apk --update --no-cache --no-progress add python3 python3-dev gcc libffi-dev musl-dev make tor openssl \
&& pip3 install -r /root/requirements.txt \
&& apk del python3-dev gcc libffi-dev musl-dev make \
&& echo "ControlPort 9051" >> /etc/tor/torrc \
&& echo "CookieAuthentication 1" >> /etc/tor/torrc
RUN python3 -V \
&& python3 -m pip list \
&& tor --version \
&& openssl version
#Add Zeronet source
COPY . /root
VOLUME /root/data
#Control if Tor proxy is started
ENV ENABLE_TOR false
WORKDIR /root
#Set upstart command
CMD (! ${ENABLE_TOR} || tor&) && python3 zeronet.py --ui_ip 0.0.0.0 --fileserver_port 26552
#Expose ports
EXPOSE 43110 26552

367
LICENSE
View file

@ -1,340 +1,27 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{description}
Copyright (C) {year} {fullname}
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, version 3.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Additional Conditions :
Contributing to this repo
This repo is governed by GPLv3, same is located at the root of the ZeroNet git repo,
unless specified separately all code is governed by that license, contributions to this repo
are divided into two key types, key contributions and non-key contributions, key contributions
are which, directly affects the code performance, quality and features of software,
non key contributions include things like translation datasets, image, graphic or video
contributions that does not affect the main usability of software but improves the existing
usability of certain thing or feature, these also include tests written with code, since their
purpose is to check, whether something is working or not as intended. All the non-key contributions
are governed by [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/), unless specified
above, a contribution is ruled by the type of contribution if there is a conflict between two
contributing parties of repo in any case.

133
README-ru.md Normal file
View file

@ -0,0 +1,133 @@
# ZeroNet [![tests](https://github.com/ZeroNetX/ZeroNet/actions/workflows/tests.yml/badge.svg)](https://github.com/ZeroNetX/ZeroNet/actions/workflows/tests.yml) [![Documentation](https://img.shields.io/badge/docs-faq-brightgreen.svg)](https://docs.zeronet.dev/1DeveLopDZL1cHfKi8UXHh2UBEhzH6HhMp/faq/) [![Help](https://img.shields.io/badge/keep_this_project_alive-donate-yellow.svg)](https://docs.zeronet.dev/1DeveLopDZL1cHfKi8UXHh2UBEhzH6HhMp/help_zeronet/donate/) [![Docker Pulls](https://img.shields.io/docker/pulls/canewsin/zeronet)](https://hub.docker.com/r/canewsin/zeronet)
[简体中文](./README-zh-cn.md)
[English](./README.md)
Децентрализованные вебсайты, использующие криптографию Bitcoin и протокол BitTorrent — https://zeronet.dev ([Зеркало в ZeroNet](http://127.0.0.1:43110/1ZeroNetyV5mKY9JF1gsm82TuBXHpfdLX/)). В отличии от Bitcoin, ZeroNet'у не требуется блокчейн для работы, однако он использует ту же криптографию, чтобы обеспечить сохранность и проверку данных.
## Зачем?
- Мы верим в открытую, свободную, и неподдающуюся цензуре сеть и связь.
- Нет единой точки отказа: Сайт остаётся онлайн, пока его обслуживает хотя бы 1 пир.
- Нет затрат на хостинг: Сайты обслуживаются посетителями.
- Невозможно отключить: Он нигде, потому что он везде.
- Скорость и возможность работать без Интернета: Вы сможете получить доступ к сайту, потому что его копия хранится на вашем компьютере и у ваших пиров.
## Особенности
- Обновление сайтов в реальном времени
- Поддержка доменов `.bit` ([Namecoin](https://www.namecoin.org))
- Легкая установка: просто распакуйте и запустите
- Клонирование сайтов "в один клик"
- Беспарольная [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)
авторизация: Ваша учетная запись защищена той же криптографией, что и ваш Bitcoin-кошелек
- Встроенный SQL-сервер с синхронизацией данных P2P: Позволяет упростить разработку сайта и ускорить загрузку страницы
- Анонимность: Полная поддержка сети Tor, используя скрытые службы `.onion` вместо адресов IPv4
- Зашифрованное TLS подключение
- Автоматическое открытие UPnPпорта
- Плагин для поддержки нескольких пользователей (openproxy)
- Работа с любыми браузерами и операционными системами
## Текущие ограничения
- Файловые транзакции не сжаты
- Нет приватных сайтов
## Как это работает?
- После запуска `zeronet.py` вы сможете посещать сайты в ZeroNet, используя адрес
`http://127.0.0.1:43110/{zeronet_адрес}`
(Например: `http://127.0.0.1:43110/1HELLoE3sFD9569CLCbHEAVqvqV7U2Ri9d`).
- Когда вы посещаете новый сайт в ZeroNet, он пытается найти пиров с помощью протокола BitTorrent,
чтобы скачать у них файлы сайта (HTML, CSS, JS и т.д.).
- После посещения сайта вы тоже становитесь его пиром.
- Каждый сайт содержит файл `content.json`, который содержит SHA512 хеши всех остальные файлы
и подпись, созданную с помощью закрытого ключа сайта.
- Если владелец сайта (тот, кто владеет закрытым ключом для адреса сайта) изменяет сайт, он
подписывает новый `content.json` и публикует его для пиров. После этого пиры проверяют целостность `content.json`
(используя подпись), скачвают изменённые файлы и распространяют новый контент для других пиров.
[Презентация о криптографии ZeroNet, обновлениях сайтов, многопользовательских сайтах »](https://docs.google.com/presentation/d/1_2qK1IuOKJ51pgBvllZ9Yu7Au2l551t3XBgyTSvilew/pub?start=false&loop=false&delayms=3000)
[Часто задаваемые вопросы »](https://docs.zeronet.dev/1DeveLopDZL1cHfKi8UXHh2UBEhzH6HhMp/faq/)
[Документация разработчика ZeroNet »](https://docs.zeronet.dev/1DeveLopDZL1cHfKi8UXHh2UBEhzH6HhMp/site_development/getting_started/)
## Скриншоты
![Screenshot](https://i.imgur.com/H60OAHY.png)
![ZeroTalk](https://zeronet.io/docs/img/zerotalk.png)
[Больше скриншотов в документации ZeroNet »](https://docs.zeronet.dev/1DeveLopDZL1cHfKi8UXHh2UBEhzH6HhMp/using_zeronet/sample_sites/)
## Как присоединиться?
### Windows
- Скачайте и распакуйте архив [ZeroNet-win.zip](https://github.com/ZeroNetX/ZeroNet/releases/latest/download/ZeroNet-win.zip) (26МБ)
- Запустите `ZeroNet.exe`
### macOS
- Скачайте и распакуйте архив [ZeroNet-mac.zip](https://github.com/ZeroNetX/ZeroNet/releases/latest/download/ZeroNet-mac.zip) (14МБ)
- Запустите `ZeroNet.app`
### Linux (64 бит)
- Скачайте и распакуйте архив [ZeroNet-linux.zip](https://github.com/ZeroNetX/ZeroNet/releases/latest/download/ZeroNet-linux.zip) (14МБ)
- Запустите `./ZeroNet.sh`
> **Note**
> Запустите таким образом: `./ZeroNet.sh --ui_ip '*' --ui_restrict ваш_ip_адрес`, чтобы разрешить удалённое подключение к веб–интерфейсу.
### Docker
Официальный образ находится здесь: https://hub.docker.com/r/canewsin/zeronet/
### Android (arm, arm64, x86)
- Для работы требуется Android как минимум версии 5.0 Lollipop
- [<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png"
alt="Download from Google Play"
height="80">](https://play.google.com/store/apps/details?id=in.canews.zeronetmobile)
- Скачать APK: https://github.com/canewsin/zeronet_mobile/releases
### Android (arm, arm64, x86) Облегчённый клиент только для просмотра (1МБ)
- Для работы требуется Android как минимум версии 4.1 Jelly Bean
- [<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png"
alt="Download from Google Play"
height="80">](https://play.google.com/store/apps/details?id=dev.zeronetx.app.lite)
### Установка из исходного кода
```sh
wget https://github.com/ZeroNetX/ZeroNet/releases/latest/download/ZeroNet-src.zip
unzip ZeroNet-src.zip
cd ZeroNet
sudo apt-get update
sudo apt-get install python3-pip
sudo python3 -m pip install -r requirements.txt
```
- Запустите `python3 zeronet.py`
Откройте приветственную страницу ZeroHello в вашем браузере по ссылке http://127.0.0.1:43110/
## Как мне создать сайт в ZeroNet?
- Кликните на **⋮** > **"Create new, empty site"** в меню на сайте [ZeroHello](http://127.0.0.1:43110/1HELLoE3sFD9569CLCbHEAVqvqV7U2Ri9d).
- Вы будете **перенаправлены** на совершенно новый сайт, который может быть изменён только вами!
- Вы можете найти и изменить контент вашего сайта в каталоге **data/[адресашего_сайта]**
- После изменений откройте ваш сайт, переключите влево кнопку "0" в правом верхнем углу, затем нажмите кнопки **sign** и **publish** внизу
Следующие шаги: [Документация разработчика ZeroNet](https://docs.zeronet.dev/1DeveLopDZL1cHfKi8UXHh2UBEhzH6HhMp/site_development/getting_started/)
## Поддержите проект
- Bitcoin: 1ZeroNetyV5mKY9JF1gsm82TuBXHpfdLX (Рекомендуем)
- LiberaPay: https://liberapay.com/PramUkesh
- Paypal: https://paypal.me/PramUkesh
- Другие способы: [Donate](!https://docs.zeronet.dev/1DeveLopDZL1cHfKi8UXHh2UBEhzH6HhMp/help_zeronet/donate/#help-to-keep-zeronet-development-alive)
#### Спасибо!
- Здесь вы можете получить больше информации, помощь, прочитать список изменений и исследовать ZeroNet сайты: https://www.reddit.com/r/zeronetx/
- Общение происходит на канале [#zeronet @ FreeNode](https://kiwiirc.com/client/irc.freenode.net/zeronet) или в [Gitter](https://gitter.im/canewsin/ZeroNet)
- Электронная почта: canews.in@gmail.com

View file

@ -1,189 +1,132 @@
# ZeroNet [![Build Status](https://travis-ci.org/HelloZeroNet/ZeroNet.svg?branch=master)](https://travis-ci.org/HelloZeroNet/ZeroNet) [![Documentation](https://img.shields.io/badge/docs-faq-brightgreen.svg)](https://zeronet.readthedocs.org/en/latest/faq/) [![Help](https://img.shields.io/badge/keep_this_project_alive-donate-yellow.svg)](https://zeronet.readthedocs.org/en/latest/help_zeronet/donate/)
# ZeroNet [![tests](https://github.com/ZeroNetX/ZeroNet/actions/workflows/tests.yml/badge.svg)](https://github.com/ZeroNetX/ZeroNet/actions/workflows/tests.yml) [![Documentation](https://img.shields.io/badge/docs-faq-brightgreen.svg)](https://docs.zeronet.dev/1DeveLopDZL1cHfKi8UXHh2UBEhzH6HhMp/faq/) [![Help](https://img.shields.io/badge/keep_this_project_alive-donate-yellow.svg)](https://docs.zeronet.dev/1DeveLopDZL1cHfKi8UXHh2UBEhzH6HhMp/help_zeronet/donate/) [![Docker Pulls](https://img.shields.io/docker/pulls/canewsin/zeronet)](https://hub.docker.com/r/canewsin/zeronet)
[English](./README.md)
使用 Bitcoin 加密和 BitTorrent 网络的去中心化网络 - https://zeronet.io
使用 Bitcoin 加密和 BitTorrent 网络的去中心化网络 - https://zeronet.dev
## 为什么?
## 为什么
* 我们相信开放,自由,无审查的网络
* 我们相信开放,自由,无审查的网络和通讯
* 不会受单点故障影响:只要有在线的节点,站点就会保持在线
* 无托管费用: 站点由访问者托管
* 无法关闭: 因为节点无处不在
* 快速并可离线运行: 即使没有互联网连接也可以使用
* 无托管费用站点由访问者托管
* 无法关闭因为节点无处不在
* 快速并可离线运行即使没有互联网连接也可以使用
## 功能
* 实时站点更新
* 支持 Namecoin 的 .bit 域名
* 安装方便: 只需解压并运行
* 安装方便只需解压并运行
* 一键克隆存在的站点
* 无需密码、基于 [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) 的认证:用与比特币钱包相同的加密方法用来保护你的账户
你的账户被使用和比特币钱包相同的加密方法
* 内建 SQL 服务器和 P2P 数据同步: 让开发更简单并提升加载速度
* 匿名性: 完整的 Tor 网络支持,支持通过 .onion 隐藏服务相互连接而不是通过IPv4地址连接
* 无需密码、基于 [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)
的认证:您的账户被与比特币钱包相同的加密方法保护
* 内建 SQL 服务器和 P2P 数据同步让开发更简单并提升加载速度
* 匿名性完整的 Tor 网络支持,支持通过 .onion 隐藏服务相互连接而不是通过 IPv4 地址连接
* TLS 加密连接
* 自动打开 uPnP 端口
* 插件和多用户 (开放式代理) 支持
* 全平台兼容
* 多用户openproxy支持的插件
* 适用于任何浏览器 / 操作系统
## 原理
* 在你运行`zeronet.py`后你将可以通过`http://127.0.0.1:43110/{zeronet_address}` (比如.
`http://127.0.0.1:43110/1HeLLo4uzjaLetFx6NH3PMwFP3qbRbTf3D`)。访问 zeronet 中的站点。
* 在运行 `zeronet.py` 后,您将可以通过
`http://127.0.0.1:43110/{zeronet_address}`(例如:
`http://127.0.0.1:43110/1HELLoE3sFD9569CLCbHEAVqvqV7U2Ri9d`)访问 zeronet 中的站点
* 在您浏览 zeronet 站点时,客户端会尝试通过 BitTorrent 网络来寻找可用的节点从而下载需要的文件htmlcssjs...
* 您将会储存每一个浏览过的站点
* 每个站点都包含一个名为 `content.json` 的文件,它储存了其他所有文件的 sha512 散列值以及一个通过站点私钥生成的签名
* 如果站点的所有者(拥有站点地址的私钥)修改了站点,并且他 / 她签名了新的 `content.json` 然后推送至其他节点,
那么这些节点将会在使用签名验证 `content.json` 的真实性后,下载修改后的文件并将新内容推送至另外的节点
* 在你浏览 zeronet 站点时,客户端会尝试通过 BitTorrent 网络来寻找可用的节点,从而下载需要的文件 (html, css, js...)
#### [关于 ZeroNet 加密,站点更新,多用户站点的幻灯片 »](https://docs.google.com/presentation/d/1_2qK1IuOKJ51pgBvllZ9Yu7Au2l551t3XBgyTSvilew/pub?start=false&loop=false&delayms=3000)
#### [常见问题 »](https://docs.zeronet.dev/1DeveLopDZL1cHfKi8UXHh2UBEhzH6HhMp/faq/)
* 你将会储存每一个浏览过的站点
* 每个站点都包含一个名为 `content.json` ,它储存了其他所有文件的 sha512 hash 值
和一个通过站点私钥建立的签名
* 如果站点的所有者 (拥有私钥的那个人) 修改了站点, 并且他/她签名了新的 `content.json` 然后推送至其他节点,
那么所有节点将会在验证 `content.json` 的真实性 (使用签名)后, 下载修改后的文件并推送至其他节点。
#### [有关于 ZeroNet 加密, 站点更新, 多用户站点的幻灯片 »](https://docs.google.com/presentation/d/1qBxkroB_iiX2zHEn0dt-N-qRZgyEzui46XS2hEa3AA4/pub?start=false&loop=false&delayms=3000)
#### [常见问题 »](https://zeronet.readthedocs.org/en/latest/faq/)
#### [ZeroNet开发者文档 »](https://zeronet.readthedocs.org/en/latest/site_development/getting_started/)
#### [ZeroNet 开发者文档 »](https://docs.zeronet.dev/1DeveLopDZL1cHfKi8UXHh2UBEhzH6HhMp/site_development/getting_started/)
## 屏幕截图
![Screenshot](https://i.imgur.com/H60OAHY.png)
![ZeroTalk](https://zeronet.readthedocs.org/en/latest/img/zerotalk.png)
![ZeroTalk](https://zeronet.io/docs/img/zerotalk.png)
#### [在 ZeroNet 文档里查看更多的屏幕截图 »](https://zeronet.readthedocs.org/en/latest/using_zeronet/sample_sites/)
#### [ZeroNet 文档中的更多屏幕截图 »](https://docs.zeronet.dev/1DeveLopDZL1cHfKi8UXHh2UBEhzH6HhMp/using_zeronet/sample_sites/)
## 如何加入
## 如何加入
* 下载 ZeroBundle 文件包:
* [Microsoft Windows](https://github.com/HelloZeroNet/ZeroNet-win/archive/dist/ZeroNet-win.zip)
* [Apple macOS](https://github.com/HelloZeroNet/ZeroNet-mac/archive/dist/ZeroNet-mac.zip)
* [Linux 64bit](https://github.com/HelloZeroNet/ZeroBundle/raw/master/dist/ZeroBundle-linux64.tar.gz)
* [Linux 32bit](https://github.com/HelloZeroNet/ZeroBundle/raw/master/dist/ZeroBundle-linux32.tar.gz)
* 解压缩
* 运行 `ZeroNet.exe` (win), `ZeroNet(.app)` (osx), `ZeroNet.sh` (linux)
### Windows
### Linux 命令行
- 下载 [ZeroNet-win.zip](https://github.com/ZeroNetX/ZeroNet/releases/latest/download/ZeroNet-win.zip) (26MB)
- 在任意位置解压缩
- 运行 `ZeroNet.exe`
### macOS
* `wget https://github.com/HelloZeroNet/ZeroBundle/raw/master/dist/ZeroBundle-linux64.tar.gz`
* `tar xvpfz ZeroBundle-linux64.tar.gz`
* `cd ZeroBundle`
* 执行 `./ZeroNet.sh` 来启动
- 下载 [ZeroNet-mac.zip](https://github.com/ZeroNetX/ZeroNet/releases/latest/download/ZeroNet-mac.zip) (14MB)
- 在任意位置解压缩
- 运行 `ZeroNet.app`
### Linux (x86-64bit)
在你打开时他将会自动下载最新版本的 ZeroNet 。
- `wget https://github.com/ZeroNetX/ZeroNet/releases/latest/download/ZeroNet-linux.zip`
- `unzip ZeroNet-linux.zip`
- `cd ZeroNet-linux`
- 使用以下命令启动 `./ZeroNet.sh`
- 在浏览器打开 http://127.0.0.1:43110/ 即可访问 ZeroHello 页面
__提示__ 若要允许在 Web 界面上的远程连接,使用以下命令启动 `./ZeroNet.sh --ui_ip '*' --ui_restrict your.ip.address`
#### 在 Debian Linux 中手动安装
### 从源代码安装
* `sudo apt-get update`
* `sudo apt-get install msgpack-python python-gevent`
* `wget https://github.com/HelloZeroNet/ZeroNet/archive/master.tar.gz`
* `tar xvpfz master.tar.gz`
* `cd ZeroNet-master`
* 执行 `python zeronet.py` 来启动
* 在你的浏览器中打开 http://127.0.0.1:43110/
- `wget https://github.com/ZeroNetX/ZeroNet/releases/latest/download/ZeroNet-src.zip`
- `unzip ZeroNet-src.zip`
- `cd ZeroNet`
- `sudo apt-get update`
- `sudo apt-get install python3-pip`
- `sudo python3 -m pip install -r requirements.txt`
- 使用以下命令启动 `python3 zeronet.py`
- 在浏览器打开 http://127.0.0.1:43110/ 即可访问 ZeroHello 页面
### [FreeBSD](https://www.freebsd.org/)
### Android (arm, arm64, x86)
- minimum Android version supported 21 (Android 5.0 Lollipop)
- [<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png"
alt="Download from Google Play"
height="80">](https://play.google.com/store/apps/details?id=in.canews.zeronetmobile)
- APK download: https://github.com/canewsin/zeronet_mobile/releases
* `pkg install zeronet` 或者 `cd /usr/ports/security/zeronet/ && make install clean`
* `sysrc zeronet_enable="YES"`
* `service zeronet start`
* 在你的浏览器中打开 http://127.0.0.1:43110/
### [Vagrant](https://www.vagrantup.com/)
* `vagrant up`
* 通过 `vagrant ssh` 连接到 VM
* `cd /vagrant`
* 运行 `python zeronet.py --ui_ip 0.0.0.0`
* 在你的浏览器中打开 http://127.0.0.1:43110/
### [Docker](https://www.docker.com/)
* `docker run -d -v <local_data_folder>:/root/data -p 15441:15441 -p 43110:43110 nofish/zeronet`
* 这个 Docker 镜像包含了 Tor ,但默认是禁用的,因为一些托管商不允许你在他们的服务器上运行 Tor。如果你希望启用它
设置 `ENABLE_TOR` 环境变量为 `true` (默认: `false`). E.g.:
`docker run -d -e "ENABLE_TOR=true" -v <local_data_folder>:/root/data -p 15441:15441 -p 43110:43110 nofish/zeronet`
* 在你的浏览器中打开 http://127.0.0.1:43110/
### [Virtualenv](https://virtualenv.readthedocs.org/en/latest/)
* `virtualenv env`
* `source env/bin/activate`
* `pip install msgpack-python gevent`
* `python zeronet.py`
* 在你的浏览器中打开 http://127.0.0.1:43110/
### Android (arm, arm64, x86) Thin Client for Preview Only (Size 1MB)
- minimum Android version supported 16 (JellyBean)
- [<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png"
alt="Download from Google Play"
height="80">](https://play.google.com/store/apps/details?id=dev.zeronetx.app.lite)
## 现有限制
* 没有类似于 BitTorrent 的文件拆分来支持大文件
* ~~没有比 BitTorrent 更好的匿名性~~ (已添加内置的完整 Tor 支持)
* 传输文件时没有压缩~~和加密~~ (已添加 TLS 支持)
* 传输文件时没有压缩
* 不支持私有站点
## 如何创建一个 ZeroNet 站点?
## 如何创建一个 ZeroNet 站点?
* 点击 [ZeroHello](http://127.0.0.1:43110/1HELLoE3sFD9569CLCbHEAVqvqV7U2Ri9d) 站点的 **⋮** > **「新建空站点」** 菜单项
* 您将被**重定向**到一个全新的站点,该站点只能由您修改
* 您可以在 **data/[您的站点地址]** 目录中找到并修改网站的内容
* 修改后打开您的网站将右上角的「0」按钮拖到左侧然后点击底部的**签名**并**发布**按钮
如果 zeronet 在运行,把它关掉
执行:
```bash
$ zeronet.py siteCreate
...
- Site private key: 23DKQpzxhbVBrAtvLEc2uvk7DZweh4qL3fn3jpM3LgHDczMK2TtYUq
- Site address: 13DNDkMUExRf9Xa9ogwPKqp7zyHFEqbhC2
...
- Site created!
$ zeronet.py
...
```
你已经完成了! 现在任何人都可以通过
`http://localhost:43110/13DNDkMUExRf9Xa9ogwPKqp7zyHFEqbhC2`
来访问你的站点
下一步: [ZeroNet 开发者文档](https://zeronet.readthedocs.org/en/latest/site_development/getting_started/)
## 我要如何修改 ZeroNet 站点?
* 修改位于 data/13DNDkMUExRf9Xa9ogwPKqp7zyHFEqbhC2 的目录.
在你改好之后:
```bash
$ zeronet.py siteSign 13DNDkMUExRf9Xa9ogwPKqp7zyHFEqbhC2
- Signing site: 13DNDkMUExRf9Xa9ogwPKqp7zyHFEqbhC2...
Private key (input hidden):
```
* 输入你在创建站点时获得的私钥
```bash
$ zeronet.py sitePublish 13DNDkMUExRf9Xa9ogwPKqp7zyHFEqbhC2
...
Site:13DNDk..bhC2 Publishing to 3/10 peers...
Site:13DNDk..bhC2 Successfuly published to 3 peers
- Serving files....
```
* 就是这样! 你现在已经成功的签名并推送了你的更改。
接下来的步骤:[ZeroNet 开发者文档](https://docs.zeronet.dev/1DeveLopDZL1cHfKi8UXHh2UBEhzH6HhMp/site_development/getting_started/)
## 帮助这个项目
- Bitcoin: 1ZeroNetyV5mKY9JF1gsm82TuBXHpfdLX (Preferred)
- LiberaPay: https://liberapay.com/PramUkesh
- Paypal: https://paypal.me/PramUkesh
- Others: [Donate](!https://docs.zeronet.dev/1DeveLopDZL1cHfKi8UXHh2UBEhzH6HhMp/help_zeronet/donate/#help-to-keep-zeronet-development-alive)
- Bitcoin: 1QDhxQ6PraUZa21ET5fYUCPgdrwBomnFgX
- Paypal: https://zeronet.readthedocs.org/en/latest/help_zeronet/donate/
- Gratipay: https://gratipay.com/zeronet/
### 赞助商
#### 感谢您!
* 在 OSX/Safari 下 [BrowserStack.com](https://www.browserstack.com) 带来更好的兼容性
#### 感谢!
* 更多信息, 帮助, 变更记录和 zeronet 站点: https://www.reddit.com/r/zeronet/
* 在: [#zeronet @ FreeNode](https://kiwiirc.com/client/irc.freenode.net/zeronet) 和我们聊天,或者使用 [gitter](https://gitter.im/HelloZeroNet/ZeroNet)
* [这里](https://gitter.im/ZeroNet-zh/Lobby)是一个 gitter 上的中文聊天室
* Email: hello@noloop.me
* 更多信息,帮助,变更记录和 zeronet 站点https://www.reddit.com/r/zeronetx/
* 前往 [#zeronet @ FreeNode](https://kiwiirc.com/client/irc.freenode.net/zeronet) 或 [gitter](https://gitter.im/canewsin/ZeroNet) 和我们聊天
* [这里](https://gitter.im/canewsin/ZeroNet)是一个 gitter 上的中文聊天室
* Email: canews.in@gmail.com

203
README.md
View file

@ -1,8 +1,6 @@
# ZeroNet [![Build Status](https://travis-ci.org/HelloZeroNet/ZeroNet.svg?branch=master)](https://travis-ci.org/HelloZeroNet/ZeroNet) [![Documentation](https://img.shields.io/badge/docs-faq-brightgreen.svg)](https://zeronet.readthedocs.org/en/latest/faq/) [![Help](https://img.shields.io/badge/keep_this_project_alive-donate-yellow.svg)](https://zeronet.readthedocs.org/en/latest/help_zeronet/donate/)
[简体中文](./README-zh-cn.md)
Decentralized websites using Bitcoin crypto and the BitTorrent network - https://zeronet.io
# ZeroNet [![tests](https://github.com/ZeroNetX/ZeroNet/actions/workflows/tests.yml/badge.svg)](https://github.com/ZeroNetX/ZeroNet/actions/workflows/tests.yml) [![Documentation](https://img.shields.io/badge/docs-faq-brightgreen.svg)](https://docs.zeronet.dev/1DeveLopDZL1cHfKi8UXHh2UBEhzH6HhMp/faq/) [![Help](https://img.shields.io/badge/keep_this_project_alive-donate-yellow.svg)](https://docs.zeronet.dev/1DeveLopDZL1cHfKi8UXHh2UBEhzH6HhMp/help_zeronet/donate/) [![Docker Pulls](https://img.shields.io/docker/pulls/canewsin/zeronet)](https://hub.docker.com/r/canewsin/zeronet)
<!--TODO: Update Onion Site -->
Decentralized websites using Bitcoin crypto and the BitTorrent network - https://zeronet.dev / [ZeroNet Site](http://127.0.0.1:43110/1ZeroNetyV5mKY9JF1gsm82TuBXHpfdLX/), Unlike Bitcoin, ZeroNet Doesn't need a blockchain to run, But uses cryptography used by BTC, to ensure data integrity and validation.
## Why?
@ -35,181 +33,124 @@ Decentralized websites using Bitcoin crypto and the BitTorrent network - https:/
* After starting `zeronet.py` you will be able to visit zeronet sites using
`http://127.0.0.1:43110/{zeronet_address}` (eg.
`http://127.0.0.1:43110/1HeLLo4uzjaLetFx6NH3PMwFP3qbRbTf3D`).
`http://127.0.0.1:43110/1HELLoE3sFD9569CLCbHEAVqvqV7U2Ri9d`).
* When you visit a new zeronet site, it tries to find peers using the BitTorrent
network so it can download the site files (html, css, js...) from them.
* Each visited site is also served by you.
* Every site contains a `content.json` file which holds all other files in a sha512 hash
and a signature generated using the site's private key.
* If the site owner (who has the private key for the site address) modifies the
site, then he/she signs the new `content.json` and publishes it to the peers.
site and signs the new `content.json` and publishes it to the peers.
Afterwards, the peers verify the `content.json` integrity (using the
signature), they download the modified files and publish the new content to
other peers.
#### [Slideshow about ZeroNet cryptography, site updates, multi-user sites »](https://docs.google.com/presentation/d/1_2qK1IuOKJ51pgBvllZ9Yu7Au2l551t3XBgyTSvilew/pub?start=false&loop=false&delayms=3000)
#### [Frequently asked questions »](https://zeronet.readthedocs.org/en/latest/faq/)
#### [Frequently asked questions »](https://docs.zeronet.dev/1DeveLopDZL1cHfKi8UXHh2UBEhzH6HhMp/faq/)
#### [ZeroNet Developer Documentation »](https://zeronet.readthedocs.org/en/latest/site_development/getting_started/)
#### [ZeroNet Developer Documentation »](https://docs.zeronet.dev/1DeveLopDZL1cHfKi8UXHh2UBEhzH6HhMp/site_development/getting_started/)
## Screenshots
![Screenshot](https://i.imgur.com/H60OAHY.png)
![ZeroTalk](https://zeronet.readthedocs.org/en/latest/img/zerotalk.png)
![ZeroTalk](https://zeronet.io/docs/img/zerotalk.png)
#### [More screenshots in ZeroNet docs »](https://zeronet.readthedocs.org/en/latest/using_zeronet/sample_sites/)
#### [More screenshots in ZeroNet docs »](https://docs.zeronet.dev/1DeveLopDZL1cHfKi8UXHh2UBEhzH6HhMp/using_zeronet/sample_sites/)
## How to join
* Download ZeroBundle package:
* [Microsoft Windows](https://github.com/HelloZeroNet/ZeroNet-win/archive/dist/ZeroNet-win.zip)
* [Apple macOS](https://github.com/HelloZeroNet/ZeroNet-mac/archive/dist/ZeroNet-mac.zip)
* [Linux 64bit](https://github.com/HelloZeroNet/ZeroBundle/raw/master/dist/ZeroBundle-linux64.tar.gz)
* [Linux 32bit](https://github.com/HelloZeroNet/ZeroBundle/raw/master/dist/ZeroBundle-linux32.tar.gz)
* Unpack anywhere
* Run `ZeroNet.exe` (win), `ZeroNet(.app)` (osx), `ZeroNet.sh` (linux)
### Windows
### Linux terminal
- Download [ZeroNet-win.zip](https://github.com/ZeroNetX/ZeroNet/releases/latest/download/ZeroNet-win.zip) (26MB)
- Unpack anywhere
- Run `ZeroNet.exe`
### macOS
* `wget https://github.com/HelloZeroNet/ZeroBundle/raw/master/dist/ZeroBundle-linux64.tar.gz`
* `tar xvpfz ZeroBundle-linux64.tar.gz`
* `cd ZeroBundle`
* Start with `./ZeroNet.sh`
- Download [ZeroNet-mac.zip](https://github.com/ZeroNetX/ZeroNet/releases/latest/download/ZeroNet-mac.zip) (14MB)
- Unpack anywhere
- Run `ZeroNet.app`
### Linux (x86-64bit)
- `wget https://github.com/ZeroNetX/ZeroNet/releases/latest/download/ZeroNet-linux.zip`
- `unzip ZeroNet-linux.zip`
- `cd ZeroNet-linux`
- Start with: `./ZeroNet.sh`
- Open the ZeroHello landing page in your browser by navigating to: http://127.0.0.1:43110/
__Tip:__ Start with `./ZeroNet.sh --ui_ip '*' --ui_restrict your.ip.address` to allow remote connections on the web interface.
### Android (arm, arm64, x86)
- minimum Android version supported 21 (Android 5.0 Lollipop)
- [<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png"
alt="Download from Google Play"
height="80">](https://play.google.com/store/apps/details?id=in.canews.zeronetmobile)
- APK download: https://github.com/canewsin/zeronet_mobile/releases
It downloads the latest version of ZeroNet then starts it automatically.
### Android (arm, arm64, x86) Thin Client for Preview Only (Size 1MB)
- minimum Android version supported 16 (JellyBean)
- [<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png"
alt="Download from Google Play"
height="80">](https://play.google.com/store/apps/details?id=dev.zeronetx.app.lite)
#### Manual install for Debian Linux
* `sudo apt-get update`
* `sudo apt-get install msgpack-python python-gevent`
* `wget https://github.com/HelloZeroNet/ZeroNet/archive/master.tar.gz`
* `tar xvpfz master.tar.gz`
* `cd ZeroNet-master`
* Start with `python2 zeronet.py`
* Open http://127.0.0.1:43110/ in your browser
#### Docker
There is an official image, built from source at: https://hub.docker.com/r/canewsin/zeronet/
### [Arch Linux](https://www.archlinux.org)
### Online Proxies
Proxies are like seed boxes for sites(i.e ZNX runs on a cloud vps), you can try zeronet experience from proxies. Add your proxy below if you have one.
* `git clone https://aur.archlinux.org/zeronet.git`
* `cd zeronet-git`
* `makepkg -srci`
* `systemctl start zeronet`
* Open http://127.0.0.1:43110/ in your browser
#### Official ZNX Proxy :
See [ArchWiki](https://wiki.archlinux.org)'s [ZeroNet
article](https://wiki.archlinux.org/index.php/ZeroNet) for further assistance.
https://proxy.zeronet.dev/
### [Gentoo Linux](https://www.gentoo.org)
https://zeronet.dev/
* [`layman -a raiagent`](https://github.com/leycec/raiagent)
* `echo '>=net-vpn/zeronet-0.5.4' >> /etc/portage/package.accept_keywords`
* *(Optional)* Enable Tor support: `echo 'net-vpn/zeronet tor' >>
/etc/portage/package.use`
* `emerge zeronet`
* `rc-service zeronet start`
* Open http://127.0.0.1:43110/ in your browser
#### From Community
See `/usr/share/doc/zeronet-*/README.gentoo.bz2` for further assistance.
https://0net-preview.com/
### [FreeBSD](https://www.freebsd.org/)
https://portal.ngnoid.tv/
* `pkg install zeronet` or `cd /usr/ports/security/zeronet/ && make install clean`
* `sysrc zeronet_enable="YES"`
* `service zeronet start`
* Open http://127.0.0.1:43110/ in your browser
https://zeronet.ipfsscan.io/
### [Vagrant](https://www.vagrantup.com/)
* `vagrant up`
* Access VM with `vagrant ssh`
* `cd /vagrant`
* Run `python2 zeronet.py --ui_ip 0.0.0.0`
* Open http://127.0.0.1:43110/ in your browser
### Install from source
### [Docker](https://www.docker.com/)
* `docker run -d -v <local_data_folder>:/root/data -p 15441:15441 -p 127.0.0.1:43110:43110 nofish/zeronet`
* This Docker image includes the Tor proxy, which is disabled by default. Beware that some
hosting providers may not allow you running Tor in their servers. If you want to enable it,
set `ENABLE_TOR` environment variable to `true` (Default: `false`). E.g.:
`docker run -d -e "ENABLE_TOR=true" -v <local_data_folder>:/root/data -p 15441:15441 -p 127.0.0.1:43110:43110 nofish/zeronet`
* Open http://127.0.0.1:43110/ in your browser
### [Virtualenv](https://virtualenv.readthedocs.org/en/latest/)
* `virtualenv env`
* `source env/bin/activate`
* `pip install msgpack-python gevent`
* `python2 zeronet.py`
* Open http://127.0.0.1:43110/ in your browser
- `wget https://github.com/ZeroNetX/ZeroNet/releases/latest/download/ZeroNet-src.zip`
- `unzip ZeroNet-src.zip`
- `cd ZeroNet`
- `sudo apt-get update`
- `sudo apt-get install python3-pip`
- `sudo python3 -m pip install -r requirements.txt`
- Start with: `python3 zeronet.py`
- Open the ZeroHello landing page in your browser by navigating to: http://127.0.0.1:43110/
## Current limitations
* ~~No torrent-like file splitting for big file support~~ (big file support added)
* ~~No more anonymous than Bittorrent~~ (built-in full Tor support added)
* File transactions are not compressed ~~or encrypted yet~~ (TLS encryption added)
* File transactions are not compressed
* No private sites
## How can I create a ZeroNet site?
Shut down zeronet if you are running it already
```bash
$ zeronet.py siteCreate
...
- Site private key: 23DKQpzxhbVBrAtvLEc2uvk7DZweh4qL3fn3jpM3LgHDczMK2TtYUq
- Site address: 13DNDkMUExRf9Xa9ogwPKqp7zyHFEqbhC2
...
- Site created!
$ zeronet.py
...
```
Congratulations, you're finished! Now anyone can access your site using
`http://localhost:43110/13DNDkMUExRf9Xa9ogwPKqp7zyHFEqbhC2`
Next steps: [ZeroNet Developer Documentation](https://zeronet.readthedocs.org/en/latest/site_development/getting_started/)
## How can I modify a ZeroNet site?
* Modify files located in data/13DNDkMUExRf9Xa9ogwPKqp7zyHFEqbhC2 directory.
After you're finished:
```bash
$ zeronet.py siteSign 13DNDkMUExRf9Xa9ogwPKqp7zyHFEqbhC2
- Signing site: 13DNDkMUExRf9Xa9ogwPKqp7zyHFEqbhC2...
Private key (input hidden):
```
* Enter the private key you got when you created the site, then:
```bash
$ zeronet.py sitePublish 13DNDkMUExRf9Xa9ogwPKqp7zyHFEqbhC2
...
Site:13DNDk..bhC2 Publishing to 3/10 peers...
Site:13DNDk..bhC2 Successfuly published to 3 peers
- Serving files....
```
* That's it! You've successfully signed and published your modifications.
* Click on **⋮** > **"Create new, empty site"** menu item on the site [ZeroHello](http://127.0.0.1:43110/1HELLoE3sFD9569CLCbHEAVqvqV7U2Ri9d).
* You will be **redirected** to a completely new site that is only modifiable by you!
* You can find and modify your site's content in **data/[yoursiteaddress]** directory
* After the modifications open your site, drag the topright "0" button to left, then press **sign** and **publish** buttons on the bottom
Next steps: [ZeroNet Developer Documentation](https://docs.zeronet.dev/1DeveLopDZL1cHfKi8UXHh2UBEhzH6HhMp/site_development/getting_started/)
## Help keep this project alive
- Bitcoin: 1QDhxQ6PraUZa21ET5fYUCPgdrwBomnFgX
- Paypal: https://zeronet.readthedocs.org/en/latest/help_zeronet/donate/
- Gratipay: https://gratipay.com/zeronet/
### Sponsors
* Better OSX/Safari compatibility made possible by [BrowserStack.com](https://www.browserstack.com)
- Bitcoin: 1ZeroNetyV5mKY9JF1gsm82TuBXHpfdLX (Preferred)
- LiberaPay: https://liberapay.com/PramUkesh
- Paypal: https://paypal.me/PramUkesh
- Others: [Donate](!https://docs.zeronet.dev/1DeveLopDZL1cHfKi8UXHh2UBEhzH6HhMp/help_zeronet/donate/#help-to-keep-zeronet-development-alive)
#### Thank you!
* More info, help, changelog, zeronet sites: https://www.reddit.com/r/zeronet/
* Come, chat with us: [#zeronet @ FreeNode](https://kiwiirc.com/client/irc.freenode.net/zeronet) or on [gitter](https://gitter.im/HelloZeroNet/ZeroNet)
* Email: hello@zeronet.io (PGP: CB9613AE)
* More info, help, changelog, zeronet sites: https://www.reddit.com/r/zeronetx/
* Come, chat with us: [#zeronet @ FreeNode](https://kiwiirc.com/client/irc.freenode.net/zeronet) or on [gitter](https://gitter.im/canewsin/ZeroNet)
* Email: canews.in@gmail.com

2
Vagrantfile vendored
View file

@ -40,6 +40,6 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.provision "shell",
inline: "sudo apt-get install msgpack-python python-gevent python-pip python-dev -y"
config.vm.provision "shell",
inline: "sudo pip install msgpack-python --upgrade"
inline: "sudo pip install msgpack --upgrade"
end

1
plugins Submodule

@ -0,0 +1 @@
Subproject commit 689d9309f73371f4681191b125ec3f2e14075eeb

View file

@ -1,126 +0,0 @@
import hashlib
import time
from Plugin import PluginManager
from util import helper
from Crypt import CryptRsa
allow_reload = False # No source reload supported in this plugin
time_full_announced = {} # Tracker address: Last announced all site to tracker
connection_pool = {} # Tracker address: Peer object
# We can only import plugin host clases after the plugins are loaded
@PluginManager.afterLoad
def importErrors():
global Peer
from Peer import Peer
# Process result got back from tracker
def processPeerRes(site, peers):
added = 0
# Ip4
found_ip4 = 0
for packed_address in peers["ip4"]:
found_ip4 += 1
peer_ip, peer_port = helper.unpackAddress(packed_address)
if site.addPeer(peer_ip, peer_port):
added += 1
# Onion
found_onion = 0
for packed_address in peers["onion"]:
found_onion += 1
peer_onion, peer_port = helper.unpackOnionAddress(packed_address)
if site.addPeer(peer_onion, peer_port):
added += 1
if added:
site.worker_manager.onPeers()
site.updateWebsocket(peers_added=added)
site.log.debug("Found %s ip4, %s onion peers, new: %s" % (found_ip4, found_onion, added))
@PluginManager.registerTo("Site")
class SitePlugin(object):
def announceTracker(self, tracker_protocol, tracker_address, fileserver_port=0, add_types=[], my_peer_id="", mode="start"):
if tracker_protocol != "zero":
return super(SitePlugin, self).announceTracker(
tracker_protocol, tracker_address, fileserver_port, add_types, my_peer_id, mode
)
s = time.time()
need_types = ["ip4"]
if self.connection_server and self.connection_server.tor_manager and self.connection_server.tor_manager.enabled:
need_types.append("onion")
if mode == "start" or mode == "more": # Single: Announce only this site
sites = [self]
full_announce = False
else: # Multi: Announce all currently serving site
full_announce = True
if time.time() - time_full_announced.get(tracker_address, 0) < 60 * 5: # No reannounce all sites within 5 minute
return True
time_full_announced[tracker_address] = time.time()
from Site import SiteManager
sites = [site for site in SiteManager.site_manager.sites.values() if site.settings["serving"]]
# Create request
request = {
"hashes": [], "onions": [], "port": fileserver_port, "need_types": need_types, "need_num": 20, "add": add_types
}
for site in sites:
if "onion" in add_types:
onion = self.connection_server.tor_manager.getOnion(site.address)
request["onions"].append(onion)
request["hashes"].append(hashlib.sha256(site.address).digest())
# Tracker can remove sites that we don't announce
if full_announce:
request["delete"] = True
# Sent request to tracker
tracker = connection_pool.get(tracker_address) # Re-use tracker connection if possible
if not tracker:
tracker_ip, tracker_port = tracker_address.split(":")
tracker = Peer(tracker_ip, tracker_port, connection_server=self.connection_server)
connection_pool[tracker_address] = tracker
res = tracker.request("announce", request)
if not res or "peers" not in res:
self.log.debug("Announce to %s failed: %s" % (tracker_address, res))
if full_announce:
time_full_announced[tracker_address] = 0
return False
# Add peers from response to site
site_index = 0
for site_res in res["peers"]:
site = sites[site_index]
processPeerRes(site, site_res)
site_index += 1
# Check if we need to sign prove the onion addresses
if "onion_sign_this" in res:
self.log.debug("Signing %s for %s to add %s onions" % (res["onion_sign_this"], tracker_address, len(sites)))
request["onion_signs"] = {}
request["onion_sign_this"] = res["onion_sign_this"]
request["need_num"] = 0
for site in sites:
onion = self.connection_server.tor_manager.getOnion(site.address)
publickey = self.connection_server.tor_manager.getPublickey(onion)
if publickey not in request["onion_signs"]:
sign = CryptRsa.sign(res["onion_sign_this"], self.connection_server.tor_manager.getPrivatekey(onion))
request["onion_signs"][publickey] = sign
res = tracker.request("announce", request)
if not res or "onion_sign_this" in res:
self.log.debug("Announce onion address to %s failed: %s" % (tracker_address, res))
if full_announce:
time_full_announced[tracker_address] = 0
return False
if full_announce:
tracker.remove() # Close connection, we don't need it in next 5 minute
return time.time() - s

View file

@ -1 +0,0 @@
import AnnounceZeroPlugin

View file

@ -1,158 +0,0 @@
import array
def packPiecefield(data):
res = []
if not data:
return array.array("H", "")
if data[0] == "0":
res.append(0)
find = "1"
else:
find = "0"
last_pos = 0
pos = 0
while 1:
pos = data.find(find, pos)
if find == "0":
find = "1"
else:
find = "0"
if pos == -1:
res.append(len(data) - last_pos)
break
res.append(pos - last_pos)
last_pos = pos
return array.array("H", res)
def unpackPiecefield(data):
if not data:
return ""
res = []
char = "1"
for times in data:
if times > 10000:
return ""
res.append(char * times)
if char == "1":
char = "0"
else:
char = "1"
return "".join(res)
class BigfilePiecefield(object):
__slots__ = ["data"]
def __init__(self):
self.data = ""
def fromstring(self, s):
self.data = s
def tostring(self):
return self.data
def pack(self):
return packPiecefield(self.data).tostring()
def unpack(self, s):
self.data = unpackPiecefield(array.array("H", s))
def __getitem__(self, key):
try:
return int(self.data[key])
except IndexError:
return False
def __setitem__(self, key, value):
data = self.data
if len(data) < key:
data = data.ljust(key+1, "0")
data = data[:key] + str(int(value)) + data[key + 1:]
self.data = data
class BigfilePiecefieldPacked(object):
__slots__ = ["data"]
def __init__(self):
self.data = ""
def fromstring(self, data):
self.data = packPiecefield(data).tostring()
def tostring(self):
return unpackPiecefield(array.array("H", self.data))
def pack(self):
return array.array("H", self.data).tostring()
def unpack(self, data):
self.data = data
def __getitem__(self, key):
try:
return int(self.tostring()[key])
except IndexError:
return False
def __setitem__(self, key, value):
data = self.tostring()
if len(data) < key:
data = data.ljust(key+1, "0")
data = data[:key] + str(int(value)) + data[key + 1:]
self.fromstring(data)
if __name__ == "__main__":
import os
import psutil
import time
testdata = "1" * 100 + "0" * 900 + "1" * 4000 + "0" * 4999 + "1"
meminfo = psutil.Process(os.getpid()).memory_info
for storage in [BigfilePiecefieldPacked, BigfilePiecefield]:
print "-- Testing storage: %s --" % storage
m = meminfo()[0]
s = time.time()
piecefields = {}
for i in range(10000):
piecefield = storage()
piecefield.fromstring(testdata[:i] + "0" + testdata[i + 1:])
piecefields[i] = piecefield
print "Create x10000: +%sKB in %.3fs (len: %s)" % ((meminfo()[0] - m) / 1024, time.time() - s, len(piecefields[0].data))
m = meminfo()[0]
s = time.time()
for piecefield in piecefields.values():
val = piecefield[1000]
print "Query one x10000: +%sKB in %.3fs" % ((meminfo()[0] - m) / 1024, time.time() - s)
m = meminfo()[0]
s = time.time()
for piecefield in piecefields.values():
piecefield[1000] = True
print "Change one x10000: +%sKB in %.3fs" % ((meminfo()[0] - m) / 1024, time.time() - s)
m = meminfo()[0]
s = time.time()
for piecefield in piecefields.values():
packed = piecefield.pack()
print "Pack x10000: +%sKB in %.3fs (len: %s)" % ((meminfo()[0] - m) / 1024, time.time() - s, len(packed))
m = meminfo()[0]
s = time.time()
for piecefield in piecefields.values():
piecefield.unpack(packed)
print "Unpack x10000: +%sKB in %.3fs (len: %s)" % ((meminfo()[0] - m) / 1024, time.time() - s, len(piecefields[0].data))
piecefields = {}

View file

@ -1,690 +0,0 @@
import time
import os
import subprocess
import shutil
import collections
import gevent
import math
import msgpack
from Plugin import PluginManager
from Debug import Debug
from Crypt import CryptHash
from lib import merkletools
from util import helper
import util
from BigfilePiecefield import BigfilePiecefield, BigfilePiecefieldPacked
# We can only import plugin host clases after the plugins are loaded
@PluginManager.afterLoad
def importPluginnedClasses():
global VerifyError, config
from Content.ContentManager import VerifyError
from Config import config
if "upload_nonces" not in locals():
upload_nonces = {}
@PluginManager.registerTo("UiRequest")
class UiRequestPlugin(object):
def isCorsAllowed(self, path):
if path == "/ZeroNet-Internal/BigfileUpload":
return True
else:
return super(UiRequestPlugin, self).isCorsAllowed(path)
def actionBigfileUpload(self):
nonce = self.get.get("upload_nonce")
if nonce not in upload_nonces:
return self.error403("Upload nonce error.")
upload_info = upload_nonces[nonce]
del upload_nonces[nonce]
self.sendHeader(200, "text/html", noscript=True, extra_headers=[
("Access-Control-Allow-Origin", "null"),
("Access-Control-Allow-Credentials", "true")
])
self.readMultipartHeaders(self.env['wsgi.input']) # Skip http headers
site = upload_info["site"]
inner_path = upload_info["inner_path"]
with site.storage.open(inner_path, "wb", create_dirs=True) as out_file:
merkle_root, piece_size, piecemap_info = site.content_manager.hashBigfile(
self.env['wsgi.input'], upload_info["size"], upload_info["piece_size"], out_file
)
if len(piecemap_info["sha512_pieces"]) == 1: # Small file, don't split
hash = piecemap_info["sha512_pieces"][0].encode("hex")
site.content_manager.optionalDownloaded(inner_path, hash, upload_info["size"], own=True)
else: # Big file
file_name = helper.getFilename(inner_path)
msgpack.pack({file_name: piecemap_info}, site.storage.open(upload_info["piecemap"], "wb"))
# Find piecemap and file relative path to content.json
file_info = site.content_manager.getFileInfo(inner_path)
content_inner_path_dir = helper.getDirname(file_info["content_inner_path"])
piecemap_relative_path = upload_info["piecemap"][len(content_inner_path_dir):]
file_relative_path = inner_path[len(content_inner_path_dir):]
# Add file to content.json
if site.storage.isFile(file_info["content_inner_path"]):
content = site.storage.loadJson(file_info["content_inner_path"])
else:
content = {}
if "files_optional" not in content:
content["files_optional"] = {}
content["files_optional"][file_relative_path] = {
"sha512": merkle_root,
"size": upload_info["size"],
"piecemap": piecemap_relative_path,
"piece_size": piece_size
}
site.content_manager.optionalDownloaded(inner_path, merkle_root, upload_info["size"], own=True)
site.storage.writeJson(file_info["content_inner_path"], content)
return {
"merkle_root": merkle_root,
"piece_num": len(piecemap_info["sha512_pieces"]),
"piece_size": piece_size,
"inner_path": inner_path
}
def readMultipartHeaders(self, wsgi_input):
for i in range(100):
line = wsgi_input.readline()
if line == "\r\n":
break
return i
def actionFile(self, file_path, *args, **kwargs):
if kwargs.get("file_size", 0) > 1024 * 1024 and kwargs.get("path_parts"): # Only check files larger than 1MB
path_parts = kwargs["path_parts"]
site = self.server.site_manager.get(path_parts["address"])
kwargs["file_obj"] = site.storage.openBigfile(path_parts["inner_path"], prebuffer=2 * 1024 * 1024)
return super(UiRequestPlugin, self).actionFile(file_path, *args, **kwargs)
@PluginManager.registerTo("UiWebsocket")
class UiWebsocketPlugin(object):
def actionBigfileUploadInit(self, to, inner_path, size):
valid_signers = self.site.content_manager.getValidSigners(inner_path)
auth_address = self.user.getAuthAddress(self.site.address)
if not self.site.settings["own"] and auth_address not in valid_signers:
self.log.error("FileWrite forbidden %s not in valid_signers %s" % (auth_address, valid_signers))
return self.response(to, {"error": "Forbidden, you can only modify your own files"})
nonce = CryptHash.random()
piece_size = 1024 * 1024
inner_path = self.site.content_manager.sanitizePath(inner_path)
file_info = self.site.content_manager.getFileInfo(inner_path, new_file=True)
content_inner_path_dir = helper.getDirname(file_info["content_inner_path"])
file_relative_path = inner_path[len(content_inner_path_dir):]
upload_nonces[nonce] = {
"added": time.time(),
"site": self.site,
"inner_path": inner_path,
"websocket_client": self,
"size": size,
"piece_size": piece_size,
"piecemap": inner_path + ".piecemap.msgpack"
}
self.response(to, {
"url": "/ZeroNet-Internal/BigfileUpload?upload_nonce=" + nonce,
"pice_size": piece_size,
"inner_path": inner_path,
"file_relative_path": file_relative_path
})
@PluginManager.registerTo("ContentManager")
class ContentManagerPlugin(object):
def getFileInfo(self, inner_path, *args, **kwargs):
if "|" not in inner_path:
return super(ContentManagerPlugin, self).getFileInfo(inner_path, *args, **kwargs)
inner_path, file_range = inner_path.split("|")
pos_from, pos_to = map(int, file_range.split("-"))
file_info = super(ContentManagerPlugin, self).getFileInfo(inner_path, *args, **kwargs)
return file_info
def readFile(self, file_in, size, buff_size=1024 * 64):
part_num = 0
recv_left = size
while 1:
part_num += 1
read_size = min(buff_size, recv_left)
part = file_in.read(read_size)
if not part:
break
yield part
if part_num % 100 == 0: # Avoid blocking ZeroNet execution during upload
time.sleep(0.001)
recv_left -= read_size
if recv_left <= 0:
break
def hashBigfile(self, file_in, size, piece_size=1024 * 1024, file_out=None):
self.site.settings["has_bigfile"] = True
recv = 0
try:
piece_hash = CryptHash.sha512t()
piece_hashes = []
piece_recv = 0
mt = merkletools.MerkleTools()
mt.hash_function = CryptHash.sha512t
part = ""
for part in self.readFile(file_in, size):
if file_out:
file_out.write(part)
recv += len(part)
piece_recv += len(part)
piece_hash.update(part)
if piece_recv >= piece_size:
piece_digest = piece_hash.digest()
piece_hashes.append(piece_digest)
mt.leaves.append(piece_digest)
piece_hash = CryptHash.sha512t()
piece_recv = 0
if len(piece_hashes) % 100 == 0 or recv == size:
self.log.info("- [HASHING:%.0f%%] Pieces: %s, %.1fMB/%.1fMB" % (
float(recv) / size * 100, len(piece_hashes), recv / 1024 / 1024, size / 1024 / 1024
))
part = ""
if len(part) > 0:
piece_digest = piece_hash.digest()
piece_hashes.append(piece_digest)
mt.leaves.append(piece_digest)
except Exception as err:
raise err
finally:
if file_out:
file_out.close()
mt.make_tree()
return mt.get_merkle_root(), piece_size, {
"sha512_pieces": piece_hashes
}
def hashFile(self, dir_inner_path, file_relative_path, optional=False):
inner_path = dir_inner_path + file_relative_path
file_size = self.site.storage.getSize(inner_path)
# Only care about optional files >1MB
if not optional or file_size < 1 * 1024 * 1024:
return super(ContentManagerPlugin, self).hashFile(dir_inner_path, file_relative_path, optional)
back = {}
content = self.contents.get(dir_inner_path + "content.json")
hash = None
piecemap_relative_path = None
piece_size = None
# Don't re-hash if it's already in content.json
if content and file_relative_path in content.get("files_optional", {}):
file_node = content["files_optional"][file_relative_path]
if file_node["size"] == file_size:
self.log.info("- [SAME SIZE] %s" % file_relative_path)
hash = file_node.get("sha512")
piecemap_relative_path = file_node.get("piecemap")
piece_size = file_node.get("piece_size")
if not hash or not piecemap_relative_path: # Not in content.json yet
if file_size < 5 * 1024 * 1024: # Don't create piecemap automatically for files smaller than 5MB
return super(ContentManagerPlugin, self).hashFile(dir_inner_path, file_relative_path, optional)
self.log.info("- [HASHING] %s" % file_relative_path)
merkle_root, piece_size, piecemap_info = self.hashBigfile(self.site.storage.open(inner_path, "rb"), file_size)
if not hash:
hash = merkle_root
if not piecemap_relative_path:
file_name = helper.getFilename(file_relative_path)
piecemap_relative_path = file_relative_path + ".piecemap.msgpack"
piecemap_inner_path = inner_path + ".piecemap.msgpack"
msgpack.pack({file_name: piecemap_info}, self.site.storage.open(piecemap_inner_path, "wb"))
back.update(super(ContentManagerPlugin, self).hashFile(dir_inner_path, piecemap_relative_path, True))
piece_num = int(math.ceil(float(file_size) / piece_size))
# Add the merkle root to hashfield
self.optionalDownloaded(inner_path, hash, file_size, own=True)
self.site.storage.piecefields[hash].fromstring("1" * piece_num)
back[file_relative_path] = {"sha512": hash, "size": file_size, "piecemap": piecemap_relative_path, "piece_size": piece_size}
return back
def getPiecemap(self, inner_path):
file_info = self.site.content_manager.getFileInfo(inner_path)
piecemap_inner_path = helper.getDirname(file_info["content_inner_path"]) + file_info["piecemap"]
self.site.needFile(piecemap_inner_path, priority=20)
piecemap = msgpack.unpack(self.site.storage.open(piecemap_inner_path))[helper.getFilename(inner_path)]
piecemap["piece_size"] = file_info["piece_size"]
return piecemap
def verifyPiece(self, inner_path, pos, piece):
piecemap = self.getPiecemap(inner_path)
piece_i = pos / piecemap["piece_size"]
if CryptHash.sha512sum(piece, format="digest") != piecemap["sha512_pieces"][piece_i]:
raise VerifyError("Invalid hash")
return True
def verifyFile(self, inner_path, file, ignore_same=True):
if "|" not in inner_path:
return super(ContentManagerPlugin, self).verifyFile(inner_path, file, ignore_same)
inner_path, file_range = inner_path.split("|")
pos_from, pos_to = map(int, file_range.split("-"))
return self.verifyPiece(inner_path, pos_from, file)
def optionalDownloaded(self, inner_path, hash, size=None, own=False):
if "|" in inner_path:
inner_path, file_range = inner_path.split("|")
pos_from, pos_to = map(int, file_range.split("-"))
file_info = self.getFileInfo(inner_path)
# Mark piece downloaded
piece_i = pos_from / file_info["piece_size"]
self.site.storage.piecefields[file_info["sha512"]][piece_i] = True
# Only add to site size on first request
if hash in self.hashfield:
size = 0
return super(ContentManagerPlugin, self).optionalDownloaded(inner_path, hash, size, own)
def optionalRemove(self, inner_path, hash, size=None):
if size and size > 1024 * 1024:
file_info = self.getFileInfo(inner_path)
sha512 = file_info["sha512"]
if sha512 in self.site.storage.piecefields:
del self.site.storage.piecefields[sha512]
# Also remove other pieces of the file from download queue
for key in self.site.bad_files.keys():
if key.startswith(inner_path + "|"):
del self.site.bad_files[key]
return super(ContentManagerPlugin, self).optionalRemove(inner_path, hash, size)
@PluginManager.registerTo("SiteStorage")
class SiteStoragePlugin(object):
def __init__(self, *args, **kwargs):
super(SiteStoragePlugin, self).__init__(*args, **kwargs)
self.piecefields = collections.defaultdict(BigfilePiecefield)
if "piecefields" in self.site.settings.get("cache", {}):
for sha512, piecefield_packed in self.site.settings["cache"].get("piecefields").iteritems():
if piecefield_packed:
self.piecefields[sha512].unpack(piecefield_packed.decode("base64"))
self.site.settings["cache"]["piecefields"] = {}
def createSparseFile(self, inner_path, size, sha512=None):
file_path = self.getPath(inner_path)
f = open(file_path, 'wb')
f.truncate(size)
f.close()
if os.name == "nt":
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
subprocess.call(["fsutil", "sparse", "setflag", file_path], close_fds=True, startupinfo=startupinfo)
if sha512 and sha512 in self.piecefields:
self.log.debug("%s: File not exists, but has piecefield. Deleting piecefield." % inner_path)
del self.piecefields[sha512]
def write(self, inner_path, content):
if "|" not in inner_path:
return super(SiteStoragePlugin, self).write(inner_path, content)
# Write to specific position by passing |{pos} after the filename
inner_path, file_range = inner_path.split("|")
pos_from, pos_to = map(int, file_range.split("-"))
file_path = self.getPath(inner_path)
# Create dir if not exist
file_dir = os.path.dirname(file_path)
if not os.path.isdir(file_dir):
os.makedirs(file_dir)
if not os.path.isfile(file_path):
file_info = self.site.content_manager.getFileInfo(inner_path)
self.createSparseFile(inner_path, file_info["size"])
# Write file
with open(file_path, "rb+") as file:
file.seek(pos_from)
if hasattr(content, 'read'): # File-like object
shutil.copyfileobj(content, file) # Write buff to disk
else: # Simple string
file.write(content)
del content
self.onUpdated(inner_path)
def openBigfile(self, inner_path, prebuffer=0):
file_info = self.site.content_manager.getFileInfo(inner_path)
if file_info and "piecemap" not in file_info: # It's not a big file
return False
self.site.needFile(inner_path, blocking=False) # Download piecemap
file_path = self.getPath(inner_path)
sha512 = file_info["sha512"]
piece_num = int(math.ceil(float(file_info["size"]) / file_info["piece_size"]))
if os.path.isfile(file_path):
if sha512 not in self.piecefields:
if open(file_path).read(128) == "\0" * 128:
piece_data = "0"
else:
piece_data = "1"
self.log.debug("%s: File exists, but not in piecefield. Filling piecefiled with %s * %s." % (inner_path, piece_num, piece_data))
self.piecefields[sha512].fromstring(piece_data * piece_num)
else:
self.log.debug("Creating bigfile: %s" % inner_path)
self.createSparseFile(inner_path, file_info["size"], sha512)
self.piecefields[sha512].fromstring(piece_data * "0")
return BigFile(self.site, inner_path, prebuffer=prebuffer)
class BigFile(object):
def __init__(self, site, inner_path, prebuffer=0):
self.site = site
self.inner_path = inner_path
file_path = site.storage.getPath(inner_path)
file_info = self.site.content_manager.getFileInfo(inner_path)
self.piece_size = file_info["piece_size"]
self.sha512 = file_info["sha512"]
self.size = file_info["size"]
self.prebuffer = prebuffer
self.read_bytes = 0
self.piecefield = self.site.storage.piecefields[self.sha512]
self.f = open(file_path, "rb+")
def read(self, buff=64 * 1024):
pos = self.f.tell()
read_until = pos + buff
requests = []
# Request all required blocks
while 1:
piece_i = pos / self.piece_size
if piece_i * self.piece_size >= read_until:
break
pos_from = piece_i * self.piece_size
pos_to = pos_from + self.piece_size
if not self.piecefield[piece_i]:
requests.append(self.site.needFile("%s|%s-%s" % (self.inner_path, pos_from, pos_to), blocking=False, update=True, priority=10))
pos += self.piece_size
if not all(requests):
return None
# Request prebuffer
if self.prebuffer:
prebuffer_until = min(self.size, read_until + self.prebuffer)
priority = 3
while 1:
piece_i = pos / self.piece_size
if piece_i * self.piece_size >= prebuffer_until:
break
pos_from = piece_i * self.piece_size
pos_to = pos_from + self.piece_size
if not self.piecefield[piece_i]:
self.site.needFile("%s|%s-%s" % (self.inner_path, pos_from, pos_to), blocking=False, update=True, priority=max(0, priority))
priority -= 1
pos += self.piece_size
gevent.joinall(requests)
self.read_bytes += buff
# Increase buffer for long reads
if self.read_bytes > 7 * 1024 * 1024 and self.prebuffer < 5 * 1024 * 1024:
self.site.log.debug("%s: Increasing bigfile buffer size to 5MB..." % self.inner_path)
self.prebuffer = 5 * 1024 * 1024
return self.f.read(buff)
def seek(self, pos):
return self.f.seek(pos)
def tell(self):
self.f.tell()
def close(self):
self.f.close()
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.close()
@PluginManager.registerTo("WorkerManager")
class WorkerManagerPlugin(object):
def addTask(self, inner_path, *args, **kwargs):
file_info = kwargs.get("file_info")
if file_info and "piecemap" in file_info: # Bigfile
self.site.settings["has_bigfile"] = True
piecemap_inner_path = helper.getDirname(file_info["content_inner_path"]) + file_info["piecemap"]
piecemap_task = None
if not self.site.storage.isFile(piecemap_inner_path):
# Start download piecemap
piecemap_task = super(WorkerManagerPlugin, self).addTask(piecemap_inner_path, priority=30)
if "|" not in inner_path and self.site.isDownloadable(inner_path) and file_info["size"] / 1024 / 1024 <= config.autodownload_bigfile_size_limit:
gevent.spawn_later(0.1, self.site.needFile, inner_path + "|all") # Download all pieces
if "|" in inner_path:
# Start download piece
task = super(WorkerManagerPlugin, self).addTask(inner_path, *args, **kwargs)
inner_path, file_range = inner_path.split("|")
pos_from, pos_to = map(int, file_range.split("-"))
task["piece_i"] = pos_from / file_info["piece_size"]
task["sha512"] = file_info["sha512"]
else:
if inner_path in self.site.bad_files:
del self.site.bad_files[inner_path]
if piecemap_task:
task = piecemap_task
else:
fake_evt = gevent.event.AsyncResult() # Don't download anything if no range specified
fake_evt.set(True)
task = {"evt": fake_evt}
if not self.site.storage.isFile(inner_path):
self.site.storage.createSparseFile(inner_path, file_info["size"], file_info["sha512"])
piece_num = int(math.ceil(float(file_info["size"]) / file_info["piece_size"]))
self.site.storage.piecefields[file_info["sha512"]].fromstring("0" * piece_num)
else:
task = super(WorkerManagerPlugin, self).addTask(inner_path, *args, **kwargs)
return task
def taskAddPeer(self, task, peer):
if "piece_i" in task:
if not peer.piecefields[task["sha512"]][task["piece_i"]]:
if task["sha512"] not in peer.piecefields:
gevent.spawn(peer.updatePiecefields, force=True)
elif not task["peers"]:
gevent.spawn(peer.updatePiecefields)
return False # Deny to add peers to task if file not in piecefield
return super(WorkerManagerPlugin, self).taskAddPeer(task, peer)
@PluginManager.registerTo("FileRequest")
class FileRequestPlugin(object):
def isReadable(self, site, inner_path, file, pos):
# Peek into file
if file.read(10) == "\0" * 10:
# Looks empty, but makes sures we don't have that piece
file_info = site.content_manager.getFileInfo(inner_path)
piece_i = pos / file_info["piece_size"]
if not site.storage.piecefields[file_info["sha512"]][piece_i]:
return False
# Seek back to position we want to read
file.seek(pos)
return super(FileRequestPlugin, self).isReadable(site, inner_path, file, pos)
def actionGetPiecefields(self, params):
site = self.sites.get(params["site"])
if not site or not site.settings["serving"]: # Site unknown or not serving
self.response({"error": "Unknown site"})
return False
# Add peer to site if not added before
peer = site.addPeer(self.connection.ip, self.connection.port, return_peer=True)
if not peer.connection: # Just added
peer.connect(self.connection) # Assign current connection to peer
piecefields_packed = {sha512: piecefield.pack() for sha512, piecefield in site.storage.piecefields.iteritems()}
self.response({"piecefields_packed": piecefields_packed})
def actionSetPiecefields(self, params):
site = self.sites.get(params["site"])
if not site or not site.settings["serving"]: # Site unknown or not serving
self.response({"error": "Unknown site"})
self.connection.badAction(5)
return False
# Add or get peer
peer = site.addPeer(self.connection.ip, self.connection.port, return_peer=True, connection=self.connection)
if not peer.connection:
peer.connect(self.connection)
peer.piecefields = collections.defaultdict(BigfilePiecefieldPacked)
for sha512, piecefield_packed in params["piecefields_packed"].iteritems():
peer.piecefields[sha512].unpack(piecefield_packed)
site.settings["has_bigfile"] = True
self.response({"ok": "Updated"})
@PluginManager.registerTo("Peer")
class PeerPlugin(object):
def __getattr__(self, key):
if key == "piecefields":
self.piecefields = collections.defaultdict(BigfilePiecefieldPacked)
return self.piecefields
elif key == "time_piecefields_updated":
self.time_piecefields_updated = None
return self.time_piecefields_updated
else:
return super(PeerPlugin, self).__getattr__(key)
@util.Noparallel(ignore_args=True)
def updatePiecefields(self, force=False):
if self.connection and self.connection.handshake.get("rev", 0) < 2190:
return False # Not supported
# Don't update piecefield again in 1 min
if self.time_piecefields_updated and time.time() - self.time_piecefields_updated < 60 and not force:
return False
self.time_piecefields_updated = time.time()
res = self.request("getPiecefields", {"site": self.site.address})
if not res or "error" in res:
return False
self.piecefields = collections.defaultdict(BigfilePiecefieldPacked)
try:
for sha512, piecefield_packed in res["piecefields_packed"].iteritems():
self.piecefields[sha512].unpack(piecefield_packed)
except Exception as err:
self.log("Invalid updatePiecefields response: %s" % Debug.formatException(err))
return self.piecefields
def sendMyHashfield(self, *args, **kwargs):
return super(PeerPlugin, self).sendMyHashfield(*args, **kwargs)
def updateHashfield(self, *args, **kwargs):
if self.site.settings.get("has_bigfile"):
thread = gevent.spawn(self.updatePiecefields, *args, **kwargs)
back = super(PeerPlugin, self).updateHashfield(*args, **kwargs)
thread.join()
return back
else:
return super(PeerPlugin, self).updateHashfield(*args, **kwargs)
def getFile(self, site, inner_path, *args, **kwargs):
if "|" in inner_path:
inner_path, file_range = inner_path.split("|")
pos_from, pos_to = map(int, file_range.split("-"))
kwargs["pos_from"] = pos_from
kwargs["pos_to"] = pos_to
return super(PeerPlugin, self).getFile(site, inner_path, *args, **kwargs)
@PluginManager.registerTo("Site")
class SitePlugin(object):
def isFileDownloadAllowed(self, inner_path, file_info):
if "piecemap" in file_info:
file_info = file_info.copy()
file_info["size"] = file_info["piece_size"]
return super(SitePlugin, self).isFileDownloadAllowed(inner_path, file_info)
def getSettingsCache(self):
back = super(SitePlugin, self).getSettingsCache()
if self.storage.piecefields:
back["piecefields"] = {sha512: piecefield.pack().encode("base64") for sha512, piecefield in self.storage.piecefields.iteritems()}
return back
def needFile(self, inner_path, *args, **kwargs):
if inner_path.endswith("|all"):
@util.Pooled(20)
def pooledNeedBigfile(*args, **kwargs):
return self.needFile(*args, **kwargs)
inner_path = inner_path.replace("|all", "")
file_info = self.needFileInfo(inner_path)
file_size = file_info["size"]
piece_size = file_info["piece_size"]
piece_num = int(math.ceil(float(file_size) / piece_size))
file_threads = []
piecefield = self.storage.piecefields.get(file_info["sha512"])
for piece_i in range(piece_num):
piece_from = piece_i * piece_size
piece_to = min(file_size, piece_from + piece_size)
if not piecefield or not piecefield[piece_i]:
res = pooledNeedBigfile("%s|%s-%s" % (inner_path, piece_from, piece_to), blocking=False)
if res is not True and res is not False:
file_threads.append(res)
gevent.joinall(file_threads)
else:
return super(SitePlugin, self).needFile(inner_path, *args, **kwargs)
@PluginManager.registerTo("ConfigPlugin")
class ConfigPlugin(object):
def createArguments(self):
group = self.parser.add_argument_group("Bigfile plugin")
group.add_argument('--autodownload_bigfile_size_limit', help='Also download bigfiles until this limit if help distribute option is checked', default=1, metavar="MB", type=int)
return super(ConfigPlugin, self).createArguments()

View file

@ -1,467 +0,0 @@
import time
import os
from cStringIO import StringIO
import pytest
import msgpack
import mock
from lib import merkletools
from Connection import ConnectionServer
from Content.ContentManager import VerifyError
from File import FileServer
from File import FileRequest
from Worker import WorkerManager
from Peer import Peer
from Bigfile import BigfilePiecefield, BigfilePiecefieldPacked
from Test import Spy
@pytest.mark.usefixtures("resetSettings")
@pytest.mark.usefixtures("resetTempSettings")
class TestBigfile:
privatekey = "5KUh3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMntv"
def createBigfile(self, site, inner_path="data/optional.any.iso", pieces=10):
f = site.storage.open(inner_path, "w")
for i in range(pieces * 100):
f.write(("Test%s" % i).ljust(10, "-") * 1000)
f.close()
assert site.content_manager.sign("content.json", self.privatekey)
return inner_path
def testPiecemapCreate(self, site):
inner_path = self.createBigfile(site)
content = site.storage.loadJson("content.json")
assert "data/optional.any.iso" in content["files_optional"]
file_node = content["files_optional"][inner_path]
assert file_node["size"] == 10 * 1000 * 1000
assert file_node["sha512"] == "47a72cde3be80b4a829e7674f72b7c6878cf6a70b0c58c6aa6c17d7e9948daf6"
assert file_node["piecemap"] == inner_path + ".piecemap.msgpack"
piecemap = msgpack.unpack(site.storage.open(file_node["piecemap"], "rb"))["optional.any.iso"]
assert len(piecemap["sha512_pieces"]) == 10
assert piecemap["sha512_pieces"][0] != piecemap["sha512_pieces"][1]
assert piecemap["sha512_pieces"][0].encode("hex") == "a73abad9992b3d0b672d0c2a292046695d31bebdcb1e150c8410bbe7c972eff3"
def testVerifyPiece(self, site):
inner_path = self.createBigfile(site)
# Verify all 10 piece
f = site.storage.open(inner_path, "rb")
for i in range(10):
piece = StringIO(f.read(1024 * 1024))
piece.seek(0)
site.content_manager.verifyPiece(inner_path, i * 1024 * 1024, piece)
f.close()
# Try to verify piece 0 with piece 1 hash
with pytest.raises(VerifyError) as err:
i = 1
f = site.storage.open(inner_path, "rb")
piece = StringIO(f.read(1024 * 1024))
f.close()
site.content_manager.verifyPiece(inner_path, i * 1024 * 1024, piece)
assert "Invalid hash" in str(err)
def testSparseFile(self, site):
inner_path = "sparsefile"
# Create a 100MB sparse file
site.storage.createSparseFile(inner_path, 100 * 1024 * 1024)
# Write to file beginning
s = time.time()
f = site.storage.write("%s|%s-%s" % (inner_path, 0, 1024 * 1024), "hellostart" * 1024)
time_write_start = time.time() - s
# Write to file end
s = time.time()
f = site.storage.write("%s|%s-%s" % (inner_path, 99 * 1024 * 1024, 99 * 1024 * 1024 + 1024 * 1024), "helloend" * 1024)
time_write_end = time.time() - s
# Verify writes
f = site.storage.open(inner_path)
assert f.read(10) == "hellostart"
f.seek(99 * 1024 * 1024)
assert f.read(8) == "helloend"
f.close()
site.storage.delete(inner_path)
# Writing to end shold not take much longer, than writing to start
assert time_write_end <= max(0.1, time_write_start * 1.1)
def testRangedFileRequest(self, file_server, site, site_temp):
inner_path = self.createBigfile(site)
file_server.sites[site.address] = site
client = FileServer("127.0.0.1", 1545)
client.sites[site_temp.address] = site_temp
site_temp.connection_server = client
connection = client.getConnection("127.0.0.1", 1544)
# Add file_server as peer to client
peer_file_server = site_temp.addPeer("127.0.0.1", 1544)
buff = peer_file_server.getFile(site_temp.address, "%s|%s-%s" % (inner_path, 5 * 1024 * 1024, 6 * 1024 * 1024))
assert len(buff.getvalue()) == 1 * 1024 * 1024 # Correct block size
assert buff.getvalue().startswith("Test524") # Correct data
buff.seek(0)
assert site.content_manager.verifyPiece(inner_path, 5 * 1024 * 1024, buff) # Correct hash
connection.close()
client.stop()
def testRangedFileDownload(self, file_server, site, site_temp):
inner_path = self.createBigfile(site)
# Init source server
site.connection_server = file_server
file_server.sites[site.address] = site
# Make sure the file and the piecemap in the optional hashfield
file_info = site.content_manager.getFileInfo(inner_path)
assert site.content_manager.hashfield.hasHash(file_info["sha512"])
piecemap_hash = site.content_manager.getFileInfo(file_info["piecemap"])["sha512"]
assert site.content_manager.hashfield.hasHash(piecemap_hash)
# Init client server
client = ConnectionServer("127.0.0.1", 1545)
site_temp.connection_server = client
peer_client = site_temp.addPeer("127.0.0.1", 1544)
# Download site
site_temp.download(blind_includes=True).join(timeout=5)
bad_files = site_temp.storage.verifyFiles(quick_check=True)
assert not bad_files
# client_piecefield = peer_client.piecefields[file_info["sha512"]].tostring()
# assert client_piecefield == "1" * 10
# Download 5. and 10. block
site_temp.needFile("%s|%s-%s" % (inner_path, 5 * 1024 * 1024, 6 * 1024 * 1024))
site_temp.needFile("%s|%s-%s" % (inner_path, 9 * 1024 * 1024, 10 * 1024 * 1024))
# Verify 0. block not downloaded
f = site_temp.storage.open(inner_path)
assert f.read(10) == "\0" * 10
# Verify 5. and 10. block downloaded
f.seek(5 * 1024 * 1024)
assert f.read(7) == "Test524"
f.seek(9 * 1024 * 1024)
assert f.read(7) == "943---T"
# Verify hashfield
assert set(site_temp.content_manager.hashfield) == set([18343, 30970]) # 18343: data/optional.any.iso, 30970: data/optional.any.iso.hashmap.msgpack
def testOpenBigfile(self, file_server, site, site_temp):
inner_path = self.createBigfile(site)
# Init source server
site.connection_server = file_server
file_server.sites[site.address] = site
# Init client server
client = ConnectionServer("127.0.0.1", 1545)
site_temp.connection_server = client
site_temp.addPeer("127.0.0.1", 1544)
# Download site
site_temp.download(blind_includes=True).join(timeout=5)
# Open virtual file
assert not site_temp.storage.isFile(inner_path)
with site_temp.storage.openBigfile(inner_path) as f:
with Spy.Spy(FileRequest, "route") as requests:
f.seek(5 * 1024 * 1024)
assert f.read(7) == "Test524"
f.seek(9 * 1024 * 1024)
assert f.read(7) == "943---T"
assert len(requests) == 4 # 1x peicemap + 1x getpiecefield + 2x for pieces
assert set(site_temp.content_manager.hashfield) == set([18343, 30970])
assert site_temp.storage.piecefields[f.sha512].tostring() == "0000010001"
assert f.sha512 in site_temp.getSettingsCache()["piecefields"]
# Test requesting already downloaded
with Spy.Spy(FileRequest, "route") as requests:
f.seek(5 * 1024 * 1024)
assert f.read(7) == "Test524"
assert len(requests) == 0
# Test requesting multi-block overflow reads
with Spy.Spy(FileRequest, "route") as requests:
f.seek(5 * 1024 * 1024) # We already have this block
data = f.read(1024 * 1024 * 3) # Our read overflow to 6. and 7. block
assert data.startswith("Test524")
assert data.endswith("Test838-")
assert "\0" not in data # No null bytes allowed
assert len(requests) == 2 # Two block download
@pytest.mark.parametrize("piecefield_obj", [BigfilePiecefield, BigfilePiecefieldPacked])
def testPiecefield(self, piecefield_obj, site):
testdatas = [
"1" * 100 + "0" * 900 + "1" * 4000 + "0" * 4999 + "1",
"010101" * 10 + "01" * 90 + "10" * 400 + "0" * 4999,
"1" * 10000,
"0" * 10000
]
for testdata in testdatas:
piecefield = piecefield_obj()
piecefield.fromstring(testdata)
assert piecefield.tostring() == testdata
assert piecefield[0] == int(testdata[0])
assert piecefield[100] == int(testdata[100])
assert piecefield[1000] == int(testdata[1000])
assert piecefield[len(testdata)-1] == int(testdata[len(testdata)-1])
packed = piecefield.pack()
piecefield_new = piecefield_obj()
piecefield_new.unpack(packed)
assert piecefield.tostring() == piecefield_new.tostring()
assert piecefield_new.tostring() == testdata
def testFileGet(self, file_server, site, site_temp):
inner_path = self.createBigfile(site)
# Init source server
site.connection_server = file_server
file_server.sites[site.address] = site
# Init client server
site_temp.connection_server = FileServer("127.0.0.1", 1545)
site_temp.connection_server.sites[site_temp.address] = site_temp
site_temp.addPeer("127.0.0.1", 1544)
# Download site
site_temp.download(blind_includes=True).join(timeout=5)
# Download second block
with site_temp.storage.openBigfile(inner_path) as f:
f.seek(1024 * 1024)
assert f.read(1024)[0] != "\0"
# Make sure first block not download
with site_temp.storage.open(inner_path) as f:
assert f.read(1024)[0] == "\0"
peer2 = site.addPeer("127.0.0.1", 1545, return_peer=True)
# Should drop error on first block request
assert not peer2.getFile(site.address, "%s|0-%s" % (inner_path, 1024 * 1024 * 1))
# Should not drop error for second block request
assert peer2.getFile(site.address, "%s|%s-%s" % (inner_path, 1024 * 1024 * 1, 1024 * 1024 * 2))
def benchmarkPeerMemory(self, site, file_server):
# Init source server
site.connection_server = file_server
file_server.sites[site.address] = site
import psutil, os
meminfo = psutil.Process(os.getpid()).memory_info
mem_s = meminfo()[0]
s = time.time()
for i in range(25000):
site.addPeer("127.0.0.1", i)
print "%.3fs MEM: + %sKB" % (time.time() - s, (meminfo()[0] - mem_s) / 1024) # 0.082s MEM: + 6800KB
print site.peers.values()[0].piecefields
def testUpdatePiecefield(self, file_server, site, site_temp):
inner_path = self.createBigfile(site)
server1 = file_server
server1.sites[site.address] = site
server2 = FileServer("127.0.0.1", 1545)
server2.sites[site_temp.address] = site_temp
site_temp.connection_server = server2
# Add file_server as peer to client
server2_peer1 = site_temp.addPeer("127.0.0.1", 1544)
# Testing piecefield sync
assert len(server2_peer1.piecefields) == 0
assert server2_peer1.updatePiecefields() # Query piecefields from peer
assert len(server2_peer1.piecefields) > 0
def testWorkerManagerPiecefieldDeny(self, file_server, site, site_temp):
inner_path = self.createBigfile(site)
server1 = file_server
server1.sites[site.address] = site
server2 = FileServer("127.0.0.1", 1545)
server2.sites[site_temp.address] = site_temp
site_temp.connection_server = server2
# Add file_server as peer to client
server2_peer1 = site_temp.addPeer("127.0.0.1", 1544) # Working
site_temp.downloadContent("content.json", download_files=False)
site_temp.needFile("data/optional.any.iso.piecemap.msgpack")
# Add fake peers with optional files downloaded
for i in range(5):
fake_peer = site_temp.addPeer("127.0.1.%s" % i, 1544)
fake_peer.hashfield = site.content_manager.hashfield
fake_peer.has_hashfield = True
with Spy.Spy(WorkerManager, "addWorker") as requests:
site_temp.needFile("%s|%s-%s" % (inner_path, 5 * 1024 * 1024, 6 * 1024 * 1024))
site_temp.needFile("%s|%s-%s" % (inner_path, 6 * 1024 * 1024, 7 * 1024 * 1024))
# It should only request parts from peer1 as the other peers does not have the requested parts in piecefields
assert len([request[1] for request in requests if request[1] != server2_peer1]) == 0
def testWorkerManagerPiecefieldDownload(self, file_server, site, site_temp):
inner_path = self.createBigfile(site)
server1 = file_server
server1.sites[site.address] = site
server2 = FileServer("127.0.0.1", 1545)
server2.sites[site_temp.address] = site_temp
site_temp.connection_server = server2
sha512 = site.content_manager.getFileInfo(inner_path)["sha512"]
# Create 10 fake peer for each piece
for i in range(10):
peer = Peer("127.0.0.1", 1544, site_temp, server2)
peer.piecefields[sha512][i] = "1"
peer.updateHashfield = mock.MagicMock(return_value=False)
peer.updatePiecefields = mock.MagicMock(return_value=False)
peer.findHashIds = mock.MagicMock(return_value={"nope": []})
peer.hashfield = site.content_manager.hashfield
peer.has_hashfield = True
peer.key = "Peer:%s" % i
site_temp.peers["Peer:%s" % i] = peer
site_temp.downloadContent("content.json", download_files=False)
site_temp.needFile("data/optional.any.iso.piecemap.msgpack")
with Spy.Spy(Peer, "getFile") as requests:
for i in range(10):
site_temp.needFile("%s|%s-%s" % (inner_path, i * 1024 * 1024, (i + 1) * 1024 * 1024))
assert len(requests) == 10
for i in range(10):
assert requests[i][0] == site_temp.peers["Peer:%s" % i] # Every part should be requested from piece owner peer
def testDownloadStats(self, file_server, site, site_temp):
inner_path = self.createBigfile(site)
# Init source server
site.connection_server = file_server
file_server.sites[site.address] = site
# Init client server
client = ConnectionServer("127.0.0.1", 1545)
site_temp.connection_server = client
site_temp.addPeer("127.0.0.1", 1544)
# Download site
site_temp.download(blind_includes=True).join(timeout=5)
# Open virtual file
assert not site_temp.storage.isFile(inner_path)
# Check size before downloads
assert site_temp.settings["size"] < 10 * 1024 * 1024
assert site_temp.settings["optional_downloaded"] == 0
size_piecemap = site_temp.content_manager.getFileInfo(inner_path + ".piecemap.msgpack")["size"]
size_bigfile = site_temp.content_manager.getFileInfo(inner_path)["size"]
with site_temp.storage.openBigfile(inner_path) as f:
assert not "\0" in f.read(1024)
assert site_temp.settings["optional_downloaded"] == size_piecemap + size_bigfile
with site_temp.storage.openBigfile(inner_path) as f:
# Don't count twice
assert not "\0" in f.read(1024)
assert site_temp.settings["optional_downloaded"] == size_piecemap + size_bigfile
# Add second block
assert not "\0" in f.read(1024 * 1024)
assert site_temp.settings["optional_downloaded"] == size_piecemap + size_bigfile
def testPrebuffer(self, file_server, site, site_temp):
inner_path = self.createBigfile(site)
# Init source server
site.connection_server = file_server
file_server.sites[site.address] = site
# Init client server
client = ConnectionServer("127.0.0.1", 1545)
site_temp.connection_server = client
site_temp.addPeer("127.0.0.1", 1544)
# Download site
site_temp.download(blind_includes=True).join(timeout=5)
# Open virtual file
assert not site_temp.storage.isFile(inner_path)
with site_temp.storage.openBigfile(inner_path, prebuffer=1024 * 1024 * 2) as f:
with Spy.Spy(FileRequest, "route") as requests:
f.seek(5 * 1024 * 1024)
assert f.read(7) == "Test524"
# assert len(requests) == 3 # 1x piecemap + 1x getpiecefield + 1x for pieces
assert len([task for task in site_temp.worker_manager.tasks if task["inner_path"].startswith(inner_path)]) == 2
time.sleep(0.5) # Wait prebuffer download
sha512 = site.content_manager.getFileInfo(inner_path)["sha512"]
assert site_temp.storage.piecefields[sha512].tostring() == "0000011100"
# No prebuffer beyond end of the file
f.seek(9 * 1024 * 1024)
assert "\0" not in f.read(7)
assert len([task for task in site_temp.worker_manager.tasks if task["inner_path"].startswith(inner_path)]) == 0
def testDownloadAllPieces(self, file_server, site, site_temp):
inner_path = self.createBigfile(site)
# Init source server
site.connection_server = file_server
file_server.sites[site.address] = site
# Init client server
client = ConnectionServer("127.0.0.1", 1545)
site_temp.connection_server = client
site_temp.addPeer("127.0.0.1", 1544)
# Download site
site_temp.download(blind_includes=True).join(timeout=5)
# Open virtual file
assert not site_temp.storage.isFile(inner_path)
with Spy.Spy(FileRequest, "route") as requests:
site_temp.needFile("%s|all" % inner_path)
assert len(requests) == 12 # piecemap.msgpack, getPiecefields, 10 x piece
# Don't re-download already got pieces
with Spy.Spy(FileRequest, "route") as requests:
site_temp.needFile("%s|all" % inner_path)
assert len(requests) == 0

View file

@ -1 +0,0 @@
from src.Test.conftest import *

View file

@ -1,5 +0,0 @@
[pytest]
python_files = Test*.py
addopts = -rsxX -v --durations=6
markers =
webtest: mark a test as a webtest.

View file

@ -1,2 +0,0 @@
import BigfilePlugin
from BigfilePiecefield import BigfilePiecefield, BigfilePiecefieldPacked

View file

@ -1,84 +0,0 @@
import re
import cgi
import copy
from Plugin import PluginManager
from Translate import Translate
from util import helper
from Debug import Debug
if "_" not in locals():
_ = Translate("plugins/Cors/languages/")
def getCorsPath(site, inner_path):
match = re.match("^cors-([A-Za-z0-9]{26,35})/(.*)", inner_path)
if not match:
raise Exception("Invalid cors path: %s" % inner_path)
cors_address = match.group(1)
cors_inner_path = match.group(2)
if not "Cors:%s" % cors_address in site.settings["permissions"]:
raise Exception("This site has no permission to access site %s" % cors_address)
return cors_address, cors_inner_path
@PluginManager.registerTo("UiWebsocket")
class UiWebsocketPlugin(object):
# Add cors support for file commands
def corsFuncWrapper(self, func_name, to, inner_path, *args, **kwargs):
if inner_path.startswith("cors-"):
cors_address, cors_inner_path = getCorsPath(self.site, inner_path)
req_self = copy.copy(self)
req_self.site = self.server.sites.get(cors_address) # Change the site to the merged one
func = getattr(super(UiWebsocketPlugin, req_self), func_name)
back = func(to, cors_inner_path, *args, **kwargs)
return back
else:
func = getattr(super(UiWebsocketPlugin, self), func_name)
return func(to, inner_path, *args, **kwargs)
def actionFileGet(self, to, inner_path, *args, **kwargs):
return self.corsFuncWrapper("actionFileGet", to, inner_path, *args, **kwargs)
def actionFileRules(self, to, inner_path, *args, **kwargs):
return self.corsFuncWrapper("actionFileRules", to, inner_path, *args, **kwargs)
def actionOptionalFileInfo(self, to, inner_path, *args, **kwargs):
return self.corsFuncWrapper("actionOptionalFileInfo", to, inner_path, *args, **kwargs)
def actionCorsPermission(self, to, address):
site = self.server.sites.get(address)
if site:
site_name = site.content_manager.contents.get("content.json", {}).get("title")
button_title = _["Grant"]
else:
site_name = address
button_title = _["Grant & Add"]
self.cmd(
"confirm",
[_["This site requests <b>read</b> permission to: <b>%s</b>"] % cgi.escape(site_name), button_title],
lambda (res): self.cbCorsPermission(to, address)
)
def cbCorsPermission(self, to, address):
self.actionPermissionAdd(to, "Cors:"+address)
site = self.server.sites.get(address)
if not site:
self.server.site_manager.need(address)
@PluginManager.registerTo("UiRequest")
class UiRequestPlugin(object):
# Allow to load cross origin files using /cors-address/file.jpg
def parsePath(self, path):
path_parts = super(UiRequestPlugin, self).parsePath(path)
if "cors-" not in path: # Optimization
return path_parts
site = self.server.sites[path_parts["address"]]
try:
path_parts["address"], path_parts["inner_path"] = getCorsPath(site, path_parts["inner_path"])
except:
return None
return path_parts

View file

@ -1 +0,0 @@
import CorsPlugin

View file

@ -1,53 +0,0 @@
from lib.pybitcointools import bitcoin as btctools
import hashlib
ecc_cache = {}
def encrypt(data, pubkey, ephemcurve=None, ciphername='aes-256-cbc'):
from lib import pyelliptic
curve, pubkey_x, pubkey_y, i = pyelliptic.ECC._decode_pubkey(pubkey)
if ephemcurve is None:
ephemcurve = curve
ephem = pyelliptic.ECC(curve=ephemcurve)
key = hashlib.sha512(ephem.raw_get_ecdh_key(pubkey_x, pubkey_y)).digest()
key_e, key_m = key[:32], key[32:]
pubkey = ephem.get_pubkey()
iv = pyelliptic.OpenSSL.rand(pyelliptic.OpenSSL.get_cipher(ciphername).get_blocksize())
ctx = pyelliptic.Cipher(key_e, iv, 1, ciphername)
ciphertext = iv + pubkey + ctx.ciphering(data)
mac = pyelliptic.hmac_sha256(key_m, ciphertext)
return key_e, ciphertext + mac
def split(encrypted):
iv = encrypted[0:16]
ciphertext = encrypted[16+70:-32]
return iv, ciphertext
def getEcc(privatekey=None):
from lib import pyelliptic
global eccs
if privatekey not in ecc_cache:
if privatekey:
publickey_bin = btctools.encode_pubkey(btctools.privtopub(privatekey), "bin")
publickey_openssl = toOpensslPublickey(publickey_bin)
privatekey_openssl = toOpensslPrivatekey(privatekey)
ecc_cache[privatekey] = pyelliptic.ECC(curve='secp256k1', privkey=privatekey_openssl, pubkey=publickey_openssl)
else:
ecc_cache[None] = pyelliptic.ECC()
return ecc_cache[privatekey]
def toOpensslPrivatekey(privatekey):
privatekey_bin = btctools.encode_privkey(privatekey, "bin")
return '\x02\xca\x00\x20' + privatekey_bin
def toOpensslPublickey(publickey):
publickey_bin = btctools.encode_pubkey(publickey, "bin")
publickey_bin = publickey_bin[1:]
publickey_openssl = '\x02\xca\x00 ' + publickey_bin[:32] + '\x00 ' + publickey_bin[32:]
return publickey_openssl

View file

@ -1,149 +0,0 @@
import base64
import os
from Plugin import PluginManager
from Crypt import CryptBitcoin
from lib.pybitcointools import bitcoin as btctools
import CryptMessage
@PluginManager.registerTo("UiWebsocket")
class UiWebsocketPlugin(object):
def encrypt(self, text, publickey):
encrypted = CryptMessage.encrypt(text, CryptMessage.toOpensslPublickey(publickey))
return encrypted
def decrypt(self, encrypted, privatekey):
back = CryptMessage.getEcc(privatekey).decrypt(encrypted)
return back.decode("utf8")
# - Actions -
# Returns user's public key unique to site
# Return: Public key
def actionUserPublickey(self, to, index=0):
publickey = self.user.getEncryptPublickey(self.site.address, index)
self.response(to, publickey)
# Encrypt a text using the publickey or user's sites unique publickey
# Return: Encrypted text using base64 encoding
def actionEciesEncrypt(self, to, text, publickey=0, return_aes_key=False):
if type(publickey) is int: # Encrypt using user's publickey
publickey = self.user.getEncryptPublickey(self.site.address, publickey)
aes_key, encrypted = self.encrypt(text.encode("utf8"), publickey.decode("base64"))
if return_aes_key:
self.response(to, [base64.b64encode(encrypted), base64.b64encode(aes_key)])
else:
self.response(to, base64.b64encode(encrypted))
# Decrypt a text using privatekey or the user's site unique private key
# Return: Decrypted text or list of decrypted texts
def actionEciesDecrypt(self, to, param, privatekey=0):
if type(privatekey) is int: # Decrypt using user's privatekey
privatekey = self.user.getEncryptPrivatekey(self.site.address, privatekey)
if type(param) == list:
encrypted_texts = param
else:
encrypted_texts = [param]
texts = [] # Decoded texts
for encrypted_text in encrypted_texts:
try:
text = self.decrypt(encrypted_text.decode("base64"), privatekey)
texts.append(text)
except Exception as err:
texts.append(None)
if type(param) == list:
self.response(to, texts)
else:
self.response(to, texts[0])
# Encrypt a text using AES
# Return: Iv, AES key, Encrypted text
def actionAesEncrypt(self, to, text, key=None, iv=None):
from lib import pyelliptic
if key:
key = key.decode("base64")
else:
key = os.urandom(32)
if iv: # Generate new AES key if not definied
iv = iv.decode("base64")
else:
iv = pyelliptic.Cipher.gen_IV('aes-256-cbc')
if text:
encrypted = pyelliptic.Cipher(key, iv, 1, ciphername='aes-256-cbc').ciphering(text.encode("utf8"))
else:
encrypted = ""
self.response(to, [base64.b64encode(key), base64.b64encode(iv), base64.b64encode(encrypted)])
# Decrypt a text using AES
# Return: Decrypted text
def actionAesDecrypt(self, to, *args):
from lib import pyelliptic
if len(args) == 3: # Single decrypt
encrypted_texts = [(args[0], args[1])]
keys = [args[2]]
else: # Batch decrypt
encrypted_texts, keys = args
texts = [] # Decoded texts
for iv, encrypted_text in encrypted_texts:
encrypted_text = encrypted_text.decode("base64")
iv = iv.decode("base64")
text = None
for key in keys:
ctx = pyelliptic.Cipher(key.decode("base64"), iv, 0, ciphername='aes-256-cbc')
try:
decrypted = ctx.ciphering(encrypted_text)
if decrypted and decrypted.decode("utf8"): # Valid text decoded
text = decrypted
except Exception, err:
pass
texts.append(text)
if len(args) == 3:
self.response(to, texts[0])
else:
self.response(to, texts)
@PluginManager.registerTo("User")
class UserPlugin(object):
def getEncryptPrivatekey(self, address, param_index=0):
assert param_index >= 0 and param_index <= 1000
site_data = self.getSiteData(address)
if site_data.get("cert"): # Different privatekey for different cert provider
index = param_index + self.getAddressAuthIndex(site_data["cert"])
else:
index = param_index
if "encrypt_privatekey_%s" % index not in site_data:
address_index = self.getAddressAuthIndex(address)
crypt_index = address_index + 1000 + index
site_data["encrypt_privatekey_%s" % index] = CryptBitcoin.hdPrivatekey(self.master_seed, crypt_index)
self.log.debug("New encrypt privatekey generated for %s:%s" % (address, index))
return site_data["encrypt_privatekey_%s" % index]
def getEncryptPublickey(self, address, param_index=0):
assert param_index >= 0 and param_index <= 1000
site_data = self.getSiteData(address)
if site_data.get("cert"): # Different privatekey for different cert provider
index = param_index + self.getAddressAuthIndex(site_data["cert"])
else:
index = param_index
if "encrypt_publickey_%s" % index not in site_data:
privatekey = self.getEncryptPrivatekey(address, param_index)
publickey = btctools.encode_pubkey(btctools.privtopub(privatekey), "bin_compressed")
site_data["encrypt_publickey_%s" % index] = base64.b64encode(publickey)
return site_data["encrypt_publickey_%s" % index]

View file

@ -1,106 +0,0 @@
import pytest
from CryptMessage import CryptMessage
@pytest.mark.usefixtures("resetSettings")
class TestCrypt:
def testPublickey(self, ui_websocket):
pub = ui_websocket.testAction("UserPublickey", 0)
assert len(pub) == 44 # Compressed, b64 encoded publickey
# Different pubkey for specificed index
assert ui_websocket.testAction("UserPublickey", 1) != ui_websocket.testAction("UserPublickey", 0)
# Same publickey for same index
assert ui_websocket.testAction("UserPublickey", 2) == ui_websocket.testAction("UserPublickey", 2)
# Different publickey for different cert
pub1 = ui_websocket.testAction("UserPublickey", 0)
site_data = ui_websocket.user.getSiteData(ui_websocket.site.address)
site_data["cert"] = "zeroid.bit"
pub2 = ui_websocket.testAction("UserPublickey", 0)
assert pub1 != pub2
def testEcies(self, ui_websocket):
ui_websocket.actionUserPublickey(0, 0)
pub = ui_websocket.ws.result
ui_websocket.actionEciesEncrypt(0, "hello", pub)
encrypted = ui_websocket.ws.result
assert len(encrypted) == 180
# Don't allow decrypt using other privatekey index
ui_websocket.actionEciesDecrypt(0, encrypted, 123)
decrypted = ui_websocket.ws.result
assert decrypted != "hello"
# Decrypt using correct privatekey
ui_websocket.actionEciesDecrypt(0, encrypted)
decrypted = ui_websocket.ws.result
assert decrypted == "hello"
# Decrypt batch
ui_websocket.actionEciesDecrypt(0, [encrypted, "baad", encrypted])
decrypted = ui_websocket.ws.result
assert decrypted == ["hello", None, "hello"]
def testEciesUtf8(self, ui_websocket):
# Utf8 test
utf8_text = u'\xc1rv\xedzt\xfbr\xf5t\xfck\xf6rf\xfar\xf3g\xe9p'
ui_websocket.actionEciesEncrypt(0, utf8_text)
encrypted = ui_websocket.ws.result
ui_websocket.actionEciesDecrypt(0, encrypted)
assert ui_websocket.ws.result == utf8_text
def testEciesAes(self, ui_websocket):
ui_websocket.actionEciesEncrypt(0, "hello", return_aes_key=True)
ecies_encrypted, aes_key = ui_websocket.ws.result
# Decrypt using Ecies
ui_websocket.actionEciesDecrypt(0, ecies_encrypted)
assert ui_websocket.ws.result == "hello"
# Decrypt using AES
aes_iv, aes_encrypted = CryptMessage.split(ecies_encrypted.decode("base64"))
ui_websocket.actionAesDecrypt(0, aes_iv.encode("base64"), aes_encrypted.encode("base64"), aes_key)
assert ui_websocket.ws.result == "hello"
def testAes(self, ui_websocket):
ui_websocket.actionAesEncrypt(0, "hello")
key, iv, encrypted = ui_websocket.ws.result
assert len(key) == 44
assert len(iv) == 24
assert len(encrypted) == 24
# Single decrypt
ui_websocket.actionAesDecrypt(0, iv, encrypted, key)
assert ui_websocket.ws.result == "hello"
# Batch decrypt
ui_websocket.actionAesEncrypt(0, "hello")
key2, iv2, encrypted2 = ui_websocket.ws.result
assert [key, iv, encrypted] != [key2, iv2, encrypted2]
# 2 correct key
ui_websocket.actionAesDecrypt(0, [[iv, encrypted], [iv, encrypted], [iv, "baad"], [iv2, encrypted2]], [key])
assert ui_websocket.ws.result == ["hello", "hello", None, None]
# 3 key
ui_websocket.actionAesDecrypt(0, [[iv, encrypted], [iv, encrypted], [iv, "baad"], [iv2, encrypted2]], [key, key2])
assert ui_websocket.ws.result == ["hello", "hello", None, "hello"]
def testAesUtf8(self, ui_websocket):
utf8_text = u'\xc1rv\xedzt\xfbr\xf5t\xfck\xf6rf\xfar\xf3g\xe9'
ui_websocket.actionAesEncrypt(0, utf8_text)
key, iv, encrypted = ui_websocket.ws.result
ui_websocket.actionAesDecrypt(0, iv, encrypted, key)
assert ui_websocket.ws.result == utf8_text

View file

@ -1 +0,0 @@
from src.Test.conftest import *

View file

@ -1,5 +0,0 @@
[pytest]
python_files = Test*.py
addopts = -rsxX -v --durations=6
markers =
webtest: mark a test as a webtest.

View file

@ -1 +0,0 @@
import CryptMessagePlugin

View file

@ -1,89 +0,0 @@
import os
import re
from Plugin import PluginManager
from Config import config
from util import helper
# Keep archive open for faster reponse times for large sites
archive_cache = {}
def closeArchive(archive_path):
if archive_path in archive_cache:
del archive_cache[archive_path]
def openArchive(archive_path, path_within):
if archive_path not in archive_cache:
if archive_path.endswith("tar.gz"):
import tarfile
archive_cache[archive_path] = tarfile.open(archive_path, "r:gz")
elif archive_path.endswith("tar.bz2"):
import tarfile
archive_cache[archive_path] = tarfile.open(archive_path, "r:bz2")
else:
import zipfile
archive_cache[archive_path] = zipfile.ZipFile(archive_path)
helper.timer(5, lambda: closeArchive(archive_path)) # Close after 5 sec
archive = archive_cache[archive_path]
if archive_path.endswith(".zip"):
return archive.open(path_within)
else:
return archive.extractfile(path_within.encode("utf8"))
@PluginManager.registerTo("UiRequest")
class UiRequestPlugin(object):
def actionSiteMedia(self, path, **kwargs):
if ".zip/" in path or ".tar.gz/" in path:
path_parts = self.parsePath(path)
file_path = u"%s/%s/%s" % (config.data_dir, path_parts["address"], path_parts["inner_path"].decode("utf8"))
match = re.match("^(.*\.(?:tar.gz|tar.bz2|zip))/(.*)", file_path)
archive_path, path_within = match.groups()
if not os.path.isfile(archive_path):
site = self.server.site_manager.get(path_parts["address"])
if not site:
return self.actionSiteAddPrompt(path)
# Wait until file downloads
result = site.needFile(site.storage.getInnerPath(archive_path), priority=10)
# Send virutal file path download finished event to remove loading screen
site.updateWebsocket(file_done=site.storage.getInnerPath(file_path))
if not result:
return self.error404(path)
try:
file = openArchive(archive_path, path_within)
content_type = self.getContentType(file_path)
self.sendHeader(200, content_type=content_type, noscript=kwargs.get("header_noscript", False))
return self.streamFile(file)
except Exception as err:
self.log.debug("Error opening archive file: %s" % err)
return self.error404(path)
return super(UiRequestPlugin, self).actionSiteMedia(path, **kwargs)
def streamFile(self, file):
for i in range(100): # Read max 6MB
try:
block = file.read(60 * 1024)
if block:
yield block
else:
raise StopIteration
except StopIteration:
file.close()
break
@PluginManager.registerTo("SiteStorage")
class SiteStoragePlugin(object):
def isFile(self, inner_path):
if ".zip/" in inner_path or ".tar.gz/" in inner_path:
match = re.match("^(.*\.(?:tar.gz|tar.bz2|zip))/(.*)", inner_path)
inner_archive_path, path_within = match.groups()
return super(SiteStoragePlugin, self).isFile(inner_archive_path)
else:
return super(SiteStoragePlugin, self).isFile(inner_path)

View file

@ -1 +0,0 @@
import FilePackPlugin

View file

@ -1,350 +0,0 @@
import re
import time
import copy
from Plugin import PluginManager
from Translate import Translate
from util import RateLimit
from util import helper
from Debug import Debug
try:
import OptionalManager.UiWebsocketPlugin # To make optioanlFileInfo merger sites compatible
except Exception:
pass
if "merger_db" not in locals().keys(): # To keep merger_sites between module reloads
merger_db = {} # Sites that allowed to list other sites {address: [type1, type2...]}
merged_db = {} # Sites that allowed to be merged to other sites {address: type, ...}
merged_to_merger = {} # {address: [site1, site2, ...]} cache
site_manager = None # Site manager for merger sites
if "_" not in locals():
_ = Translate("plugins/MergerSite/languages/")
# Check if the site has permission to this merger site
def checkMergerPath(address, inner_path):
merged_match = re.match("^merged-(.*?)/([A-Za-z0-9]{26,35})/", inner_path)
if merged_match:
merger_type = merged_match.group(1)
# Check if merged site is allowed to include other sites
if merger_type in merger_db.get(address, []):
# Check if included site allows to include
merged_address = merged_match.group(2)
if merged_db.get(merged_address) == merger_type:
inner_path = re.sub("^merged-(.*?)/([A-Za-z0-9]{26,35})/", "", inner_path)
return merged_address, inner_path
else:
raise Exception(
"Merger site (%s) does not have permission for merged site: %s (%s)" %
(merger_type, merged_address, merged_db.get(merged_address))
)
else:
raise Exception("No merger (%s) permission to load: <br>%s (%s not in %s)" % (
address, inner_path, merger_type, merger_db.get(address, []))
)
else:
raise Exception("Invalid merger path: %s" % inner_path)
@PluginManager.registerTo("UiWebsocket")
class UiWebsocketPlugin(object):
# Download new site
def actionMergerSiteAdd(self, to, addresses):
if type(addresses) != list:
# Single site add
addresses = [addresses]
# Check if the site has merger permission
merger_types = merger_db.get(self.site.address)
if not merger_types:
return self.response(to, {"error": "Not a merger site"})
if RateLimit.isAllowed(self.site.address + "-MergerSiteAdd", 10) and len(addresses) == 1:
# Without confirmation if only one site address and not called in last 10 sec
self.cbMergerSiteAdd(to, addresses)
else:
self.cmd(
"confirm",
[_["Add <b>%s</b> new site?"] % len(addresses), "Add"],
lambda (res): self.cbMergerSiteAdd(to, addresses)
)
self.response(to, "ok")
# Callback of adding new site confirmation
def cbMergerSiteAdd(self, to, addresses):
added = 0
for address in addresses:
added += 1
site_manager.need(address)
if added:
self.cmd("notification", ["done", _["Added <b>%s</b> new site"] % added, 5000])
RateLimit.called(self.site.address + "-MergerSiteAdd")
site_manager.updateMergerSites()
# Delete a merged site
def actionMergerSiteDelete(self, to, address):
site = self.server.sites.get(address)
if not site:
return self.response(to, {"error": "No site found: %s" % address})
merger_types = merger_db.get(self.site.address)
if not merger_types:
return self.response(to, {"error": "Not a merger site"})
if merged_db.get(address) not in merger_types:
return self.response(to, {"error": "Merged type (%s) not in %s" % (merged_db.get(address), merger_types)})
self.cmd("notification", ["done", _["Site deleted: <b>%s</b>"] % address, 5000])
self.response(to, "ok")
# Lists merged sites
def actionMergerSiteList(self, to, query_site_info=False):
merger_types = merger_db.get(self.site.address)
ret = {}
if not merger_types:
return self.response(to, {"error": "Not a merger site"})
for address, merged_type in merged_db.iteritems():
if merged_type not in merger_types:
continue # Site not for us
if query_site_info:
site = self.server.sites.get(address)
ret[address] = self.formatSiteInfo(site, create_user=False)
else:
ret[address] = merged_type
self.response(to, ret)
def hasSitePermission(self, address):
if super(UiWebsocketPlugin, self).hasSitePermission(address):
return True
else:
if self.site.address in [merger_site.address for merger_site in merged_to_merger.get(address, [])]:
return True
else:
return False
# Add support merger sites for file commands
def mergerFuncWrapper(self, func_name, to, inner_path, *args, **kwargs):
if inner_path.startswith("merged-"):
merged_address, merged_inner_path = checkMergerPath(self.site.address, inner_path)
# Set the same cert for merged site
merger_cert = self.user.getSiteData(self.site.address).get("cert")
if merger_cert and self.user.getSiteData(merged_address).get("cert") != merger_cert:
self.user.setCert(merged_address, merger_cert)
req_self = copy.copy(self)
req_self.site = self.server.sites.get(merged_address) # Change the site to the merged one
func = getattr(super(UiWebsocketPlugin, req_self), func_name)
back = func(to, merged_inner_path, *args, **kwargs)
return back
else:
func = getattr(super(UiWebsocketPlugin, self), func_name)
return func(to, inner_path, *args, **kwargs)
def actionFileList(self, to, inner_path, *args, **kwargs):
return self.mergerFuncWrapper("actionFileList", to, inner_path, *args, **kwargs)
def actionDirList(self, to, inner_path, *args, **kwargs):
return self.mergerFuncWrapper("actionDirList", to, inner_path, *args, **kwargs)
def actionFileGet(self, to, inner_path, *args, **kwargs):
return self.mergerFuncWrapper("actionFileGet", to, inner_path, *args, **kwargs)
def actionFileWrite(self, to, inner_path, *args, **kwargs):
return self.mergerFuncWrapper("actionFileWrite", to, inner_path, *args, **kwargs)
def actionFileDelete(self, to, inner_path, *args, **kwargs):
return self.mergerFuncWrapper("actionFileDelete", to, inner_path, *args, **kwargs)
def actionFileRules(self, to, inner_path, *args, **kwargs):
return self.mergerFuncWrapper("actionFileRules", to, inner_path, *args, **kwargs)
def actionOptionalFileInfo(self, to, inner_path, *args, **kwargs):
return self.mergerFuncWrapper("actionOptionalFileInfo", to, inner_path, *args, **kwargs)
def actionOptionalFileDelete(self, to, inner_path, *args, **kwargs):
return self.mergerFuncWrapper("actionOptionalFileDelete", to, inner_path, *args, **kwargs)
# Add support merger sites for file commands with privatekey parameter
def mergerFuncWrapperWithPrivatekey(self, func_name, to, privatekey, inner_path, *args, **kwargs):
func = getattr(super(UiWebsocketPlugin, self), func_name)
if inner_path.startswith("merged-"):
merged_address, merged_inner_path = checkMergerPath(self.site.address, inner_path)
merged_site = self.server.sites.get(merged_address)
# Set the same cert for merged site
merger_cert = self.user.getSiteData(self.site.address).get("cert")
if merger_cert:
self.user.setCert(merged_address, merger_cert)
site_before = self.site # Save to be able to change it back after we ran the command
self.site = merged_site # Change the site to the merged one
try:
back = func(to, privatekey, merged_inner_path, *args, **kwargs)
finally:
self.site = site_before # Change back to original site
return back
else:
return func(to, privatekey, inner_path, *args, **kwargs)
def actionSiteSign(self, to, privatekey=None, inner_path="content.json", *args, **kwargs):
return self.mergerFuncWrapperWithPrivatekey("actionSiteSign", to, privatekey, inner_path, *args, **kwargs)
def actionSitePublish(self, to, privatekey=None, inner_path="content.json", *args, **kwargs):
return self.mergerFuncWrapperWithPrivatekey("actionSitePublish", to, privatekey, inner_path, *args, **kwargs)
def actionPermissionAdd(self, to, permission):
super(UiWebsocketPlugin, self).actionPermissionAdd(to, permission)
if permission.startswith("Merger"):
self.site.storage.rebuildDb()
@PluginManager.registerTo("UiRequest")
class UiRequestPlugin(object):
# Allow to load merged site files using /merged-ZeroMe/address/file.jpg
def parsePath(self, path):
path_parts = super(UiRequestPlugin, self).parsePath(path)
if "merged-" not in path: # Optimization
return path_parts
path_parts["address"], path_parts["inner_path"] = checkMergerPath(path_parts["address"], path_parts["inner_path"])
return path_parts
@PluginManager.registerTo("SiteStorage")
class SiteStoragePlugin(object):
# Also rebuild from merged sites
def getDbFiles(self):
merger_types = merger_db.get(self.site.address)
# First return the site's own db files
for item in super(SiteStoragePlugin, self).getDbFiles():
yield item
# Not a merger site, that's all
if not merger_types:
raise StopIteration
merged_sites = [
site_manager.sites[address]
for address, merged_type in merged_db.iteritems()
if merged_type in merger_types
]
for merged_site in merged_sites:
self.log.debug("Loading merged site: %s" % merged_site)
merged_type = merged_db[merged_site.address]
for content_inner_path, content in merged_site.content_manager.contents.iteritems():
# content.json file itself
if merged_site.storage.isFile(content_inner_path): # Missing content.json file
merged_inner_path = "merged-%s/%s/%s" % (merged_type, merged_site.address, content_inner_path)
yield merged_inner_path, merged_site.storage.getPath(content_inner_path)
else:
merged_site.log.error("[MISSING] %s" % content_inner_path)
# Data files in content.json
content_inner_path_dir = helper.getDirname(content_inner_path) # Content.json dir relative to site
for file_relative_path in content.get("files", {}).keys() + content.get("files_optional", {}).keys():
if not file_relative_path.endswith(".json"):
continue # We only interesed in json files
file_inner_path = content_inner_path_dir + file_relative_path # File Relative to site dir
file_inner_path = file_inner_path.strip("/") # Strip leading /
if merged_site.storage.isFile(file_inner_path):
merged_inner_path = "merged-%s/%s/%s" % (merged_type, merged_site.address, file_inner_path)
yield merged_inner_path, merged_site.storage.getPath(file_inner_path)
else:
merged_site.log.error("[MISSING] %s" % file_inner_path)
# Also notice merger sites on a merged site file change
def onUpdated(self, inner_path, file=None):
super(SiteStoragePlugin, self).onUpdated(inner_path, file)
merged_type = merged_db.get(self.site.address)
for merger_site in merged_to_merger.get(self.site.address, []):
if merger_site.address == self.site.address: # Avoid infinite loop
continue
virtual_path = "merged-%s/%s/%s" % (merged_type, self.site.address, inner_path)
if inner_path.endswith(".json"):
if file is not None:
merger_site.storage.onUpdated(virtual_path, file=file)
else:
merger_site.storage.onUpdated(virtual_path, file=self.open(inner_path))
else:
merger_site.storage.onUpdated(virtual_path)
@PluginManager.registerTo("Site")
class SitePlugin(object):
def fileDone(self, inner_path):
super(SitePlugin, self).fileDone(inner_path)
for merger_site in merged_to_merger.get(self.address, []):
if merger_site.address == self.address:
continue
for ws in merger_site.websockets:
ws.event("siteChanged", self, {"event": ["file_done", inner_path]})
def fileFailed(self, inner_path):
super(SitePlugin, self).fileFailed(inner_path)
for merger_site in merged_to_merger.get(self.address, []):
if merger_site.address == self.address:
continue
for ws in merger_site.websockets:
ws.event("siteChanged", self, {"event": ["file_failed", inner_path]})
@PluginManager.registerTo("SiteManager")
class SiteManagerPlugin(object):
# Update merger site for site types
def updateMergerSites(self):
global merger_db, merged_db, merged_to_merger, site_manager
s = time.time()
merger_db = {}
merged_db = {}
merged_to_merger = {}
site_manager = self
if not self.sites:
return
for site in self.sites.itervalues():
# Update merged sites
try:
merged_type = site.content_manager.contents.get("content.json", {}).get("merged_type")
except Exception, err:
self.log.error("Error loading site %s: %s" % (site.address, Debug.formatException(err)))
continue
if merged_type:
merged_db[site.address] = merged_type
# Update merger sites
for permission in site.settings["permissions"]:
if not permission.startswith("Merger:"):
continue
if merged_type:
self.log.error(
"Removing permission %s from %s: Merger and merged at the same time." %
(permission, site.address)
)
site.settings["permissions"].remove(permission)
continue
merger_type = permission.replace("Merger:", "")
if site.address not in merger_db:
merger_db[site.address] = []
merger_db[site.address].append(merger_type)
site_manager.sites[site.address] = site
# Update merged to merger
if merged_type:
for merger_site in self.sites.itervalues():
if "Merger:" + merged_type in merger_site.settings["permissions"]:
if site.address not in merged_to_merger:
merged_to_merger[site.address] = []
merged_to_merger[site.address].append(merger_site)
self.log.debug("Updated merger sites in %.3fs" % (time.time() - s))
def load(self, *args, **kwags):
super(SiteManagerPlugin, self).load(*args, **kwags)
self.updateMergerSites()
def save(self, *args, **kwags):
super(SiteManagerPlugin, self).save(*args, **kwags)
self.updateMergerSites()

View file

@ -1 +0,0 @@
import MergerSitePlugin

View file

@ -1,5 +0,0 @@
{
"Add <b>%s</b> new site?": "¿Agregar <b>%s</b> nuevo sitio?",
"Added <b>%s</b> new site": "Sitio <b>%s</b> agregado",
"Site deleted: <b>%s</b>": "Sitio removido: <b>%s</b>"
}

View file

@ -1,5 +0,0 @@
{
"Add <b>%s</b> new site?": "Ajouter le site <b>%s</b> ?",
"Added <b>%s</b> new site": "Site <b>%s</b> ajouté",
"Site deleted: <b>%s</b>": "Site <b>%s</b> supprimé"
}

View file

@ -1,5 +0,0 @@
{
"Add <b>%s</b> new site?": "Új oldal hozzáadása: <b>%s</b>?",
"Added <b>%s</b> new site": "Új oldal hozzáadva: <b>%s</b>",
"Site deleted: <b>%s</b>": "Oldal törölve: <b>%s</b>"
}

View file

@ -1,5 +0,0 @@
{
"Add <b>%s</b> new site?": "Aggiungere <b>%s</b> nuovo sito ?",
"Added <b>%s</b> new site": "Sito <b>%s</b> aggiunto",
"Site deleted: <b>%s</b>": "Sito <b>%s</b> eliminato"
}

View file

@ -1,5 +0,0 @@
{
"Add <b>%s</b> new site?": "Adicionar <b>%s</b> novo site?",
"Added <b>%s</b> new site": "Site <b>%s</b> adicionado",
"Site deleted: <b>%s</b>": "Site removido: <b>%s</b>"
}

View file

@ -1,5 +0,0 @@
{
"Add <b>%s</b> new site?": "<b>%s</b> sitesi eklensin mi?",
"Added <b>%s</b> new site": "<b>%s</b> sitesi eklendi",
"Site deleted: <b>%s</b>": "<b>%s</b> sitesi silindi"
}

View file

@ -1,5 +0,0 @@
{
"Add <b>%s</b> new site?": "添加新網站: <b>%s</b>",
"Added <b>%s</b> new site": "已添加到新網站:<b>%s</b>",
"Site deleted: <b>%s</b>": "網站已刪除:<b>%s</b>"
}

View file

@ -1,5 +0,0 @@
{
"Add <b>%s</b> new site?": "添加新站点: <b>%s</b>",
"Added <b>%s</b> new site": "已添加到新站点:<b>%s</b>",
"Site deleted: <b>%s</b>": "站点已删除:<b>%s</b>"
}

View file

@ -1,160 +0,0 @@
import time
import json
import os
import re
from Plugin import PluginManager
from Translate import Translate
from Config import config
from util import helper
if os.path.isfile("%s/mutes.json" % config.data_dir):
try:
data = json.load(open("%s/mutes.json" % config.data_dir))
mutes = data.get("mutes", {})
site_blacklist = data.get("site_blacklist", {})
except Exception as err:
mutes = {}
site_blacklist = {}
else:
open("%s/mutes.json" % config.data_dir, "w").write('{"mutes": {}, "site_blacklist": {}}')
mutes = {}
site_blacklist = {}
if "_" not in locals():
_ = Translate("plugins/Mute/languages/")
@PluginManager.registerTo("UiWebsocket")
class UiWebsocketPlugin(object):
# Search and remove or readd files of an user
def changeDb(self, auth_address, action):
self.log.debug("Mute action %s on user %s" % (action, auth_address))
res = self.site.content_manager.contents.db.execute(
"SELECT * FROM content LEFT JOIN site USING (site_id) WHERE inner_path LIKE :inner_path",
{"inner_path": "%%/%s/%%" % auth_address}
)
for row in res:
site = self.server.sites.get(row["address"])
if not site:
continue
dir_inner_path = helper.getDirname(row["inner_path"])
for file_name in site.storage.walk(dir_inner_path):
if action == "remove":
site.storage.onUpdated(dir_inner_path + file_name, False)
else:
site.storage.onUpdated(dir_inner_path + file_name)
site.onFileDone(dir_inner_path + file_name)
def cbMuteAdd(self, to, auth_address, cert_user_id, reason):
mutes[auth_address] = {"cert_user_id": cert_user_id, "reason": reason, "source": self.site.address, "date_added": time.time()}
self.saveMutes()
self.changeDb(auth_address, "remove")
self.response(to, "ok")
def actionMuteAdd(self, to, auth_address, cert_user_id, reason):
if "ADMIN" in self.getPermissions(to):
self.cbMuteAdd(to, auth_address, cert_user_id, reason)
else:
self.cmd(
"confirm",
[_["Hide all content from <b>%s</b>?"] % cert_user_id, _["Mute"]],
lambda (res): self.cbMuteAdd(to, auth_address, cert_user_id, reason)
)
def cbMuteRemove(self, to, auth_address):
del mutes[auth_address]
self.saveMutes()
self.changeDb(auth_address, "load")
self.response(to, "ok")
def actionMuteRemove(self, to, auth_address):
if "ADMIN" in self.getPermissions(to):
self.cbMuteRemove(to, auth_address)
else:
self.cmd(
"confirm",
[_["Unmute <b>%s</b>?"] % mutes[auth_address]["cert_user_id"], _["Unmute"]],
lambda (res): self.cbMuteRemove(to, auth_address)
)
def actionMuteList(self, to):
if "ADMIN" in self.getPermissions(to):
self.response(to, mutes)
else:
return self.response(to, {"error": "Only ADMIN sites can list mutes"})
# Blacklist
def actionBlacklistAdd(self, to, site_address, reason=None):
if "ADMIN" not in self.getPermissions(to):
return self.response(to, {"error": "Forbidden, only admin sites can add to blacklist"})
site_blacklist[site_address] = {"date_added": time.time(), "reason": reason}
self.saveMutes()
self.response(to, "ok")
def actionBlacklistRemove(self, to, site_address):
if "ADMIN" not in self.getPermissions(to):
return self.response(to, {"error": "Forbidden, only admin sites can remove from blacklist"})
del site_blacklist[site_address]
self.saveMutes()
self.response(to, "ok")
def actionBlacklistList(self, to):
if "ADMIN" in self.getPermissions(to):
self.response(to, site_blacklist)
else:
return self.response(to, {"error": "Only ADMIN sites can list blacklists"})
# Write mutes and blacklist to json file
def saveMutes(self):
helper.atomicWrite("%s/mutes.json" % config.data_dir, json.dumps({"mutes": mutes, "site_blacklist": site_blacklist}, indent=2, sort_keys=True))
@PluginManager.registerTo("SiteStorage")
class SiteStoragePlugin(object):
def updateDbFile(self, inner_path, file=None, cur=None):
if file is not False: # File deletion always allowed
# Find for bitcoin addresses in file path
matches = re.findall("/(1[A-Za-z0-9]{26,35})/", inner_path)
# Check if any of the adresses are in the mute list
for auth_address in matches:
if auth_address in mutes:
self.log.debug("Mute match: %s, ignoring %s" % (auth_address, inner_path))
return False
return super(SiteStoragePlugin, self).updateDbFile(inner_path, file=file, cur=cur)
@PluginManager.registerTo("UiRequest")
class UiRequestPlugin(object):
def actionWrapper(self, path, extra_headers=None):
match = re.match("/(?P<address>[A-Za-z0-9\._-]+)(?P<inner_path>/.*|$)", path)
if not match:
return False
address = match.group("address")
if self.server.site_manager.get(address): # Site already exists
return super(UiRequestPlugin, self).actionWrapper(path, extra_headers)
if self.server.site_manager.isDomain(address):
address = self.server.site_manager.resolveDomain(address)
if address in site_blacklist:
site = self.server.site_manager.get(config.homepage)
if not extra_headers:
extra_headers = []
self.sendHeader(extra_headers=extra_headers[:])
return iter([super(UiRequestPlugin, self).renderWrapper(
site, path, "uimedia/plugins/mute/blacklisted.html?address=" + address,
"Blacklisted site", extra_headers, show_loadingscreen=False
)])
else:
return super(UiRequestPlugin, self).actionWrapper(path, extra_headers)
def actionUiMedia(self, path, *args, **kwargs):
if path.startswith("/uimedia/plugins/mute/"):
file_path = path.replace("/uimedia/plugins/mute/", "plugins/Mute/media/")
return self.actionFile(file_path)
else:
return super(UiRequestPlugin, self).actionUiMedia(path)

View file

@ -1 +0,0 @@
import MutePlugin

View file

@ -1,6 +0,0 @@
{
"Hide all content from <b>%s</b>?": "Esconder todo el contenido de <b>%s</b>?",
"Mute": "Silenciar",
"Unmute <b>%s</b>?": "Mostrar todo el contenido de <b>%s</b>?",
"Unmute": "Reactivar"
}

View file

@ -1,6 +0,0 @@
{
"Hide all content from <b>%s</b>?": "<b>%s</b> tartalmaniak elrejtése?",
"Mute": "Elnémítás",
"Unmute <b>%s</b>?": "<b>%s</b> tartalmaniak megjelenítése?",
"Unmute": "Némítás visszavonása"
}

View file

@ -1,6 +0,0 @@
{
"Hide all content from <b>%s</b>?": "<b>%s</b> Vuoi nascondere i contenuti di questo utente ?",
"Mute": "Attiva Silenzia",
"Unmute <b>%s</b>?": "<b>%s</b> Vuoi mostrare i contenuti di questo utente ?",
"Unmute": "Disattiva Silenzia"
}

View file

@ -1,6 +0,0 @@
{
"Hide all content from <b>%s</b>?": "Esconder todo conteúdo de <b>%s</b>?",
"Mute": "Ativar mudo",
"Unmute <b>%s</b>?": "Mostrar o contéudo de <b>%s</b>?",
"Unmute": "Desativar mudo"
}

View file

@ -1,6 +0,0 @@
{
"Hide all content from <b>%s</b>?": "屏蔽 <b>%s</b> 的所有內容?",
"Mute": "屏蔽",
"Unmute <b>%s</b>?": "對 <b>%s</b> 解除屏蔽?",
"Unmute": "解除屏蔽"
}

View file

@ -1,6 +0,0 @@
{
"Hide all content from <b>%s</b>?": "屏蔽 <b>%s</b> 的所有内容?",
"Mute": "屏蔽",
"Unmute <b>%s</b>?": "对 <b>%s</b> 解除屏蔽?",
"Unmute": "解除屏蔽"
}

View file

@ -1,64 +0,0 @@
<html>
<body>
<style>
.content { line-height: 24px; font-family: monospace; font-size: 14px; color: #636363; text-transform: uppercase; top: 38%; position: relative; text-align: center; perspective: 1000px }
.content h1, .content h2 { font-weight: normal; letter-spacing: 1px; }
.content h2 { font-size: 15px; }
.content #details {
text-align: left; display: inline-block; width: 350px; background-color: white; padding: 17px 27px; border-radius: 0px;
box-shadow: 0px 2px 7px -1px #d8d8d8; text-transform: none; margin: 15px; transform: scale(0) rotateX(90deg); transition: all 0.6s cubic-bezier(0.785, 0.135, 0.15, 0.86);
}
.content #details #added { font-size: 12px; text-align: right; color: #a9a9a9; }
#button { transition: all 1s cubic-bezier(0.075, 0.82, 0.165, 1); opacity: 0; transform: translateY(50px); transition-delay: 0.5s }
.button {
padding: 8px 20px; background-color: #FFF85F; border-bottom: 2px solid #CDBD1E; border-radius: 2px;
text-decoration: none; transition: all 0.5s; background-position: left center; display: inline-block; margin-top: 10px; color: black;
}
.button:hover { background-color: #FFF400; border-bottom: 2px solid #4D4D4C; transition: none; }
.button:active { position: relative; top: 1px; }
.button:focus { outline: none; }
</style>
<div class="content">
<h1>Site blocked</h1>
<h2>This site is on your blacklist:</h2>
<div id="details">
<div id="reason">Too much image</div>
<div id="added">on 2015-01-25 12:32:11</div>
</div>
<div><a href="#Visit+Site" class="button button-submit" id="button">Remove from blacklist</a></div>
</div>
<script type="text/javascript" src="js/ZeroFrame.js"></script>
<script>
class Page extends ZeroFrame {
onOpenWebsocket () {
this.cmd("wrapperSetTitle", "Blacklisted site - ZeroNet")
this.cmd("siteInfo", {}, (site_info) => {
this.site_info = site_info
})
this.cmd("blacklistList", {}, (blacklists) => {
this.blacklists = blacklists
var address = document.location.search.match(/address=(.*?)[&\?]/)[1]
var reason = blacklists[address]["reason"]
if (!reason) reason = "Unknown reason"
var date = new Date(blacklists[address]["date_added"] * 1000)
document.getElementById("reason").innerText = reason
document.getElementById("added").innerText = "at " + date.toLocaleDateString() + " " + date.toLocaleTimeString()
document.getElementById("details").style.transform = "scale(1) rotateX(0deg)"
document.getElementById("button").style.transform = "translateY(0)"
document.getElementById("button").style.opacity = "1"
document.getElementById("button").onclick = () => {
this.cmd("blacklistRemove", address, () => { this.cmd("wrapperReload") })
}
});
}
}
page = new Page()
</script>
</body>
</html>

View file

@ -1,93 +0,0 @@
const CMD_INNER_READY = 'innerReady'
const CMD_RESPONSE = 'response'
const CMD_WRAPPER_READY = 'wrapperReady'
const CMD_PING = 'ping'
const CMD_PONG = 'pong'
const CMD_WRAPPER_OPENED_WEBSOCKET = 'wrapperOpenedWebsocket'
const CMD_WRAPPER_CLOSE_WEBSOCKET = 'wrapperClosedWebsocket'
class ZeroFrame {
constructor(url) {
this.url = url
this.waiting_cb = {}
this.wrapper_nonce = document.location.href.replace(/.*wrapper_nonce=([A-Za-z0-9]+).*/, "$1")
this.connect()
this.next_message_id = 1
this.init()
}
init() {
return this
}
connect() {
this.target = window.parent
window.addEventListener('message', e => this.onMessage(e), false)
this.cmd(CMD_INNER_READY)
}
onMessage(e) {
let message = e.data
let cmd = message.cmd
if (cmd === CMD_RESPONSE) {
if (this.waiting_cb[message.to] !== undefined) {
this.waiting_cb[message.to](message.result)
}
else {
this.log("Websocket callback not found:", message)
}
} else if (cmd === CMD_WRAPPER_READY) {
this.cmd(CMD_INNER_READY)
} else if (cmd === CMD_PING) {
this.response(message.id, CMD_PONG)
} else if (cmd === CMD_WRAPPER_OPENED_WEBSOCKET) {
this.onOpenWebsocket()
} else if (cmd === CMD_WRAPPER_CLOSE_WEBSOCKET) {
this.onCloseWebsocket()
} else {
this.onRequest(cmd, message)
}
}
onRequest(cmd, message) {
this.log("Unknown request", message)
}
response(to, result) {
this.send({
cmd: CMD_RESPONSE,
to: to,
result: result
})
}
cmd(cmd, params={}, cb=null) {
this.send({
cmd: cmd,
params: params
}, cb)
}
send(message, cb=null) {
message.wrapper_nonce = this.wrapper_nonce
message.id = this.next_message_id
this.next_message_id++
this.target.postMessage(message, '*')
if (cb) {
this.waiting_cb[message.id] = cb
}
}
log(...args) {
console.log.apply(console, ['[ZeroFrame]'].concat(args))
}
onOpenWebsocket() {
this.log('Websocket open')
}
onCloseWebsocket() {
this.log('Websocket close')
}
}

View file

@ -1,134 +0,0 @@
import time
import re
from Plugin import PluginManager
from Db import DbQuery
@PluginManager.registerTo("UiWebsocket")
class UiWebsocketPlugin(object):
def formatSiteInfo(self, site, create_user=True):
site_info = super(UiWebsocketPlugin, self).formatSiteInfo(site, create_user=True)
feed_following = self.user.sites[site.address].get("follow", None)
if feed_following == None:
site_info["feed_follow_num"] = None
else:
site_info["feed_follow_num"] = len(feed_following)
return site_info
def actionFeedFollow(self, to, feeds):
self.user.setFeedFollow(self.site.address, feeds)
self.user.save()
self.response(to, "ok")
def actionFeedListFollow(self, to):
feeds = self.user.sites[self.site.address].get("follow", {})
self.response(to, feeds)
def actionFeedQuery(self, to, limit=10, day_limit=3):
if "ADMIN" not in self.site.settings["permissions"]:
return self.response(to, "FeedQuery not allowed")
from Site import SiteManager
rows = []
for address, site_data in self.user.sites.iteritems():
feeds = site_data.get("follow")
if not feeds:
continue
if type(feeds) is not dict:
self.log.debug("Invalid feed for site %s" % address)
continue
for name, query_set in feeds.iteritems():
site = SiteManager.site_manager.get(address)
try:
query, params = query_set
query_parts = query.split("UNION")
for i, query_part in enumerate(query_parts):
db_query = DbQuery(query_part)
if day_limit:
where = " WHERE %s > strftime('%%s', 'now', '-%s day')" % (db_query.fields.get("date_added", "date_added"), day_limit)
if "WHERE" in query_part:
query_part = re.sub("WHERE (.*?)(?=$| GROUP BY)", where+" AND (\\1)", query_part)
else:
query_part += where
query_parts[i] = query_part
query = " UNION ".join(query_parts)
if ":params" in query:
query = query.replace(":params", ",".join(["?"] * len(params)))
res = site.storage.query(query + " ORDER BY date_added DESC LIMIT %s" % limit, params)
else:
res = site.storage.query(query + " ORDER BY date_added DESC LIMIT %s" % limit)
except Exception as err: # Log error
self.log.error("%s feed query %s error: %s" % (address, name, err))
continue
for row in res:
row = dict(row)
if row["date_added"] > 1000000000000: # Formatted as millseconds
row["date_added"] = row["date_added"] / 1000
if "date_added" not in row or row["date_added"] > time.time() + 120:
self.log.debug("Newsfeed from the future from from site %s" % address)
continue # Feed item is in the future, skip it
row["site"] = address
row["feed_name"] = name
rows.append(row)
time.sleep(0.0001)
return self.response(to, rows)
def actionFeedSearch(self, to, search):
if "ADMIN" not in self.site.settings["permissions"]:
return self.response(to, "FeedSearch not allowed")
from Site import SiteManager
rows = []
num_sites = 0
s = time.time()
for address, site in SiteManager.site_manager.list().iteritems():
if not site.storage.has_db:
continue
if site.storage.db: # Database loaded
feeds = site.storage.db.schema.get("feeds")
else:
try:
feeds = site.storage.loadJson("dbschema.json").get("feeds")
except:
continue
if not feeds:
continue
num_sites += 1
for name, query in feeds.iteritems():
try:
db_query = DbQuery(query)
db_query.wheres.append("%s LIKE ? OR %s LIKE ?" % (db_query.fields["body"], db_query.fields["title"]))
db_query.parts["ORDER BY"] = "date_added DESC"
db_query.parts["LIMIT"] = "30"
search_like = "%" + search.replace(" ", "%") + "%"
res = site.storage.query(str(db_query), [search_like, search_like])
except Exception, err:
self.log.error("%s feed query %s error: %s" % (address, name, err))
continue
for row in res:
row = dict(row)
if row["date_added"] > time.time() + 120:
continue # Feed item is in the future, skip it
row["site"] = address
row["feed_name"] = name
rows.append(row)
return self.response(to, {"rows": rows, "num": len(rows), "sites": num_sites, "taken": time.time() - s})
@PluginManager.registerTo("User")
class UserPlugin(object):
# Set queries that user follows
def setFeedFollow(self, address, feeds):
site_data = self.getSiteData(address)
site_data["follow"] = feeds
self.save()
return site_data

View file

@ -1 +0,0 @@
import NewsfeedPlugin

View file

@ -1,402 +0,0 @@
import time
import collections
import itertools
import re
import gevent
from util import helper
from Plugin import PluginManager
from Config import config
from Debug import Debug
if "content_db" not in locals().keys(): # To keep between module reloads
content_db = None
@PluginManager.registerTo("ContentDb")
class ContentDbPlugin(object):
def __init__(self, *args, **kwargs):
global content_db
content_db = self
self.filled = {} # Site addresses that already filled from content.json
self.need_filling = False # file_optional table just created, fill data from content.json files
self.time_peer_numbers_updated = 0
self.my_optional_files = {} # Last 50 site_address/inner_path called by fileWrite (auto-pinning these files)
self.optional_files = collections.defaultdict(dict)
self.optional_files_loading = False
helper.timer(60 * 5, self.checkOptionalLimit)
super(ContentDbPlugin, self).__init__(*args, **kwargs)
def getSchema(self):
schema = super(ContentDbPlugin, self).getSchema()
# Need file_optional table
schema["tables"]["file_optional"] = {
"cols": [
["file_id", "INTEGER PRIMARY KEY UNIQUE NOT NULL"],
["site_id", "INTEGER REFERENCES site (site_id) ON DELETE CASCADE"],
["inner_path", "TEXT"],
["hash_id", "INTEGER"],
["size", "INTEGER"],
["peer", "INTEGER DEFAULT 0"],
["uploaded", "INTEGER DEFAULT 0"],
["is_downloaded", "INTEGER DEFAULT 0"],
["is_pinned", "INTEGER DEFAULT 0"],
["time_added", "INTEGER DEFAULT 0"],
["time_downloaded", "INTEGER DEFAULT 0"],
["time_accessed", "INTEGER DEFAULT 0"]
],
"indexes": [
"CREATE UNIQUE INDEX file_optional_key ON file_optional (site_id, inner_path)",
"CREATE INDEX is_downloaded ON file_optional (is_downloaded)"
],
"schema_changed": 11
}
return schema
def initSite(self, site):
super(ContentDbPlugin, self).initSite(site)
if self.need_filling:
self.fillTableFileOptional(site)
if not self.optional_files_loading:
gevent.spawn_later(1, self.loadFilesOptional)
self.optional_files_loading = True
def checkTables(self):
changed_tables = super(ContentDbPlugin, self).checkTables()
if "file_optional" in changed_tables:
self.need_filling = True
return changed_tables
# Load optional files ending
def loadFilesOptional(self):
s = time.time()
num = 0
total = 0
total_downloaded = 0
res = content_db.execute("SELECT site_id, inner_path, size, is_downloaded FROM file_optional")
site_sizes = collections.defaultdict(lambda: collections.defaultdict(int))
for row in res:
self.optional_files[row["site_id"]][row["inner_path"][-8:]] = 1
num += 1
# Update site size stats
site_sizes[row["site_id"]]["size_optional"] += row["size"]
if row["is_downloaded"]:
site_sizes[row["site_id"]]["optional_downloaded"] += row["size"]
# Site site size stats to sites.json settings
site_ids_reverse = {val: key for key, val in self.site_ids.iteritems()}
for site_id, stats in site_sizes.iteritems():
site_address = site_ids_reverse.get(site_id)
if not site_address:
self.log.error("Not found site_id: %s" % site_id)
continue
site = self.sites[site_address]
site.settings["size_optional"] = stats["size_optional"]
site.settings["optional_downloaded"] = stats["optional_downloaded"]
total += stats["size_optional"]
total_downloaded += stats["optional_downloaded"]
self.log.debug(
"Loaded %s optional files: %.2fMB, downloaded: %.2fMB in %.3fs" %
(num, float(total) / 1024 / 1024, float(total_downloaded) / 1024 / 1024, time.time() - s)
)
if self.need_filling and self.getOptionalLimitBytes() >= 0 and self.getOptionalLimitBytes() < total_downloaded:
limit_bytes = self.getOptionalLimitBytes()
limit_new = round((float(total_downloaded) / 1024 / 1024 / 1024) * 1.1, 2) # Current limit + 10%
self.log.debug(
"First startup after update and limit is smaller than downloaded files size (%.2fGB), increasing it from %.2fGB to %.2fGB" %
(float(total_downloaded) / 1024 / 1024 / 1024, float(limit_bytes) / 1024 / 1024 / 1024, limit_new)
)
config.saveValue("optional_limit", limit_new)
config.optional_limit = str(limit_new)
# Predicts if the file is optional
def isOptionalFile(self, site_id, inner_path):
return self.optional_files[site_id].get(inner_path[-8:])
# Fill file_optional table with optional files found in sites
def fillTableFileOptional(self, site):
s = time.time()
site_id = self.site_ids.get(site.address)
if not site_id:
return False
cur = self.getCursor()
cur.execute("BEGIN")
res = cur.execute("SELECT * FROM content WHERE size_files_optional > 0 AND site_id = %s" % site_id)
num = 0
for row in res.fetchall():
content = site.content_manager.contents[row["inner_path"]]
try:
num += self.setContentFilesOptional(site, row["inner_path"], content, cur=cur)
except Exception as err:
self.log.error("Error loading %s into file_optional: %s" % (row["inner_path"], err))
cur.execute("COMMIT")
cur.close()
# Set my files to pinned
from User import UserManager
user = UserManager.user_manager.get()
if not user:
user = UserManager.user_manager.create()
auth_address = user.getAuthAddress(site.address)
self.execute(
"UPDATE file_optional SET is_pinned = 1 WHERE site_id = :site_id AND inner_path LIKE :inner_path",
{"site_id": site_id, "inner_path": "%%/%s/%%" % auth_address}
)
self.log.debug(
"Filled file_optional table for %s in %.3fs (loaded: %s, is_pinned: %s)" %
(site.address, time.time() - s, num, self.cur.cursor.rowcount)
)
self.filled[site.address] = True
def setContentFilesOptional(self, site, content_inner_path, content, cur=None):
if not cur:
cur = self
try:
cur.execute("BEGIN")
except Exception as err:
self.log.warning("Transaction begin error %s %s: %s" % (site, content_inner_path, Debug.formatException(err)))
num = 0
site_id = self.site_ids[site.address]
content_inner_dir = helper.getDirname(content_inner_path)
for relative_inner_path, file in content.get("files_optional", {}).iteritems():
file_inner_path = content_inner_dir + relative_inner_path
hash_id = int(file["sha512"][0:4], 16)
if hash_id in site.content_manager.hashfield:
is_downloaded = 1
else:
is_downloaded = 0
if site.address + "/" + content_inner_dir in self.my_optional_files:
is_pinned = 1
else:
is_pinned = 0
cur.insertOrUpdate("file_optional", {
"hash_id": hash_id,
"size": int(file["size"])
}, {
"site_id": site_id,
"inner_path": file_inner_path
}, oninsert={
"time_added": int(time.time()),
"time_downloaded": int(time.time()) if is_downloaded else 0,
"is_downloaded": is_downloaded,
"peer": is_downloaded,
"is_pinned": is_pinned
})
self.optional_files[site_id][file_inner_path[-8:]] = 1
num += 1
if cur == self:
try:
cur.execute("END")
except Exception as err:
self.log.warning("Transaction end error %s %s: %s" % (site, content_inner_path, Debug.formatException(err)))
return num
def setContent(self, site, inner_path, content, size=0):
super(ContentDbPlugin, self).setContent(site, inner_path, content, size=size)
old_content = site.content_manager.contents.get(inner_path, {})
if (not self.need_filling or self.filled.get(site.address)) and "files_optional" in content or "files_optional" in old_content:
self.setContentFilesOptional(site, inner_path, content)
# Check deleted files
if old_content:
old_files = old_content.get("files_optional", {}).keys()
new_files = content.get("files_optional", {}).keys()
content_inner_dir = helper.getDirname(inner_path)
deleted = [content_inner_dir + key for key in old_files if key not in new_files]
if deleted:
site_id = self.site_ids[site.address]
self.execute("DELETE FROM file_optional WHERE ?", {"site_id": site_id, "inner_path": deleted})
def deleteContent(self, site, inner_path):
content = site.content_manager.contents.get(inner_path)
if content and "files_optional" in content:
site_id = self.site_ids[site.address]
content_inner_dir = helper.getDirname(inner_path)
optional_inner_paths = [
content_inner_dir + relative_inner_path
for relative_inner_path in content.get("files_optional", {}).keys()
]
self.execute("DELETE FROM file_optional WHERE ?", {"site_id": site_id, "inner_path": optional_inner_paths})
super(ContentDbPlugin, self).deleteContent(site, inner_path)
def updatePeerNumbers(self):
s = time.time()
num_file = 0
num_updated = 0
num_site = 0
for site in self.sites.values():
if not site.content_manager.has_optional_files:
continue
has_updated_hashfield = next((
peer
for peer in site.peers.itervalues()
if peer.has_hashfield and peer.hashfield.time_changed > self.time_peer_numbers_updated
), None)
if not has_updated_hashfield and site.content_manager.hashfield.time_changed < self.time_peer_numbers_updated:
continue
hashfield_peers = itertools.chain.from_iterable(
peer.hashfield.storage
for peer in site.peers.itervalues()
if peer.has_hashfield
)
peer_nums = collections.Counter(
itertools.chain(
hashfield_peers,
site.content_manager.hashfield
)
)
site_id = self.site_ids[site.address]
if not site_id:
continue
res = self.execute("SELECT file_id, hash_id, peer FROM file_optional WHERE ?", {"site_id": site_id})
updates = {}
for row in res:
peer_num = peer_nums.get(row["hash_id"], 0)
if peer_num != row["peer"]:
updates[row["file_id"]] = peer_num
self.execute("BEGIN")
for file_id, peer_num in updates.iteritems():
self.execute("UPDATE file_optional SET peer = ? WHERE file_id = ?", (peer_num, file_id))
self.execute("END")
num_updated += len(updates)
num_file += len(peer_nums)
num_site += 1
self.time_peer_numbers_updated = time.time()
self.log.debug("%s/%s peer number for %s site updated in %.3fs" % (num_updated, num_file, num_site, time.time() - s))
def queryDeletableFiles(self):
# First return the files with atleast 10 seeder and not accessed in last weed
query = """
SELECT * FROM file_optional
WHERE peer > 10 AND is_downloaded = 1 AND is_pinned = 0
ORDER BY time_accessed < %s DESC, uploaded / size
""" % int(time.time() - 60 * 60 * 7)
limit_start = 0
while 1:
num = 0
res = self.execute("%s LIMIT %s, 50" % (query, limit_start))
for row in res:
yield row
num += 1
if num < 50:
break
limit_start += 50
self.log.debug("queryDeletableFiles returning less-seeded files")
# Then return files less seeder but still not accessed in last week
query = """
SELECT * FROM file_optional
WHERE is_downloaded = 1 AND peer <= 10 AND is_pinned = 0
ORDER BY peer DESC, time_accessed < %s DESC, uploaded / size
""" % int(time.time() - 60 * 60 * 7)
limit_start = 0
while 1:
num = 0
res = self.execute("%s LIMIT %s, 50" % (query, limit_start))
for row in res:
yield row
num += 1
if num < 50:
break
limit_start += 50
self.log.debug("queryDeletableFiles returning everyting")
# At the end return all files
query = """
SELECT * FROM file_optional
WHERE is_downloaded = 1 AND peer <= 10 AND is_pinned = 0
ORDER BY peer DESC, time_accessed, uploaded / size
"""
limit_start = 0
while 1:
num = 0
res = self.execute("%s LIMIT %s, 50" % (query, limit_start))
for row in res:
yield row
num += 1
if num < 50:
break
limit_start += 50
def getOptionalLimitBytes(self):
if config.optional_limit.endswith("%"):
limit_percent = float(re.sub("[^0-9.]", "", config.optional_limit))
limit_bytes = helper.getFreeSpace() * (limit_percent / 100)
else:
limit_bytes = float(re.sub("[^0-9.]", "", config.optional_limit)) * 1024 * 1024 * 1024
return limit_bytes
def getOptionalNeedDelete(self, size):
if config.optional_limit.endswith("%"):
limit_percent = float(re.sub("[^0-9.]", "", config.optional_limit))
need_delete = size - ((helper.getFreeSpace() + size) * (limit_percent / 100))
else:
need_delete = size - self.getOptionalLimitBytes()
return need_delete
def checkOptionalLimit(self, limit=None):
if not limit:
limit = self.getOptionalLimitBytes()
if limit < 0:
self.log.debug("Invalid limit for optional files: %s" % limit)
return False
size = self.execute("SELECT SUM(size) FROM file_optional WHERE is_downloaded = 1 AND is_pinned = 0").fetchone()[0]
if not size:
size = 0
need_delete = self.getOptionalNeedDelete(size)
self.log.debug(
"Optional size: %.1fMB/%.1fMB, Need delete: %.1fMB" %
(float(size) / 1024 / 1024, float(limit) / 1024 / 1024, float(need_delete) / 1024 / 1024)
)
if need_delete <= 0:
return False
self.updatePeerNumbers()
site_ids_reverse = {val: key for key, val in self.site_ids.iteritems()}
deleted_file_ids = []
for row in self.queryDeletableFiles():
site_address = site_ids_reverse.get(row["site_id"])
site = self.sites.get(site_address)
if not site:
self.log.error("No site found for id: %s" % row["site_id"])
continue
site.log.debug("Deleting %s %.3f MB left" % (row["inner_path"], float(need_delete) / 1024 / 1024))
deleted_file_ids.append(row["file_id"])
try:
site.content_manager.optionalRemove(row["inner_path"], row["hash_id"], row["size"])
site.storage.delete(row["inner_path"])
need_delete -= row["size"]
except Exception as err:
site.log.error("Error deleting %s: %s" % (row["inner_path"], err))
if need_delete <= 0:
break
cur = self.getCursor()
cur.execute("BEGIN")
for file_id in deleted_file_ids:
cur.execute("UPDATE file_optional SET is_downloaded = 0, is_pinned = 0, peer = peer - 1 WHERE ?", {"file_id": file_id})
cur.execute("COMMIT")
cur.close()

View file

@ -1,136 +0,0 @@
import time
import collections
from util import helper
from Plugin import PluginManager
import ContentDbPlugin
# We can only import plugin host clases after the plugins are loaded
@PluginManager.afterLoad
def importPluginnedClasses():
global config
from Config import config
def processAccessLog():
if access_log:
content_db = ContentDbPlugin.content_db
now = int(time.time())
num = 0
for site_id in access_log:
content_db.execute(
"UPDATE file_optional SET time_accessed = %s WHERE ?" % now,
{"site_id": site_id, "inner_path": access_log[site_id].keys()}
)
num += len(access_log[site_id])
access_log.clear()
def processRequestLog():
if request_log:
content_db = ContentDbPlugin.content_db
cur = content_db.getCursor()
num = 0
cur.execute("BEGIN")
for site_id in request_log:
for inner_path, uploaded in request_log[site_id].iteritems():
content_db.execute(
"UPDATE file_optional SET uploaded = uploaded + %s WHERE ?" % uploaded,
{"site_id": site_id, "inner_path": inner_path}
)
num += 1
cur.execute("END")
request_log.clear()
if "access_log" not in locals().keys(): # To keep between module reloads
access_log = collections.defaultdict(dict) # {site_id: {inner_path1: 1, inner_path2: 1...}}
request_log = collections.defaultdict(lambda: collections.defaultdict(int)) # {site_id: {inner_path1: 1, inner_path2: 1...}}
helper.timer(61, processAccessLog)
helper.timer(60, processRequestLog)
@PluginManager.registerTo("WorkerManager")
class WorkerManagerPlugin(object):
def doneTask(self, task):
content_db = self.site.content_manager.contents.db
if task["optional_hash_id"] and task["optional_hash_id"] not in self.site.content_manager.hashfield:
inner_path = task["inner_path"]
is_pinned = 0
if "|" in inner_path: # Big file piece
inner_path, file_range = inner_path.split("|")
file_info = self.site.content_manager.getFileInfo(inner_path)
# Auto-pin bigfiles
if config.pin_bigfile and file_info["size"] > 1024 * 1024 * config.pin_bigfile:
is_pinned = 1
content_db.executeDelayed(
"UPDATE file_optional SET time_downloaded = :now, is_downloaded = 1, peer = peer + 1, is_pinned = :is_pinned WHERE site_id = :site_id AND inner_path = :inner_path",
{"now": int(time.time()), "site_id": content_db.site_ids[self.site.address], "inner_path": inner_path, "is_pinned": is_pinned}
)
super(WorkerManagerPlugin, self).doneTask(task)
if task["optional_hash_id"] and not self.tasks:
content_db.processDelayed()
@PluginManager.registerTo("UiRequest")
class UiRequestPlugin(object):
def parsePath(self, path):
global access_log
path_parts = super(UiRequestPlugin, self).parsePath(path)
if path_parts:
site_id = ContentDbPlugin.content_db.site_ids.get(path_parts["request_address"])
if site_id:
if ContentDbPlugin.content_db.isOptionalFile(site_id, path_parts["inner_path"]):
access_log[site_id][path_parts["inner_path"]] = 1
return path_parts
@PluginManager.registerTo("FileRequest")
class FileRequestPlugin(object):
def actionGetFile(self, params):
stats = super(FileRequestPlugin, self).actionGetFile(params)
self.recordFileRequest(params["site"], params["inner_path"], stats)
return stats
def actionStreamFile(self, params):
stats = super(FileRequestPlugin, self).actionStreamFile(params)
self.recordFileRequest(params["site"], params["inner_path"], stats)
return stats
def recordFileRequest(self, site_address, inner_path, stats):
if not stats:
# Only track the last request of files
return False
site_id = ContentDbPlugin.content_db.site_ids[site_address]
if site_id and ContentDbPlugin.content_db.isOptionalFile(site_id, inner_path):
request_log[site_id][inner_path] += stats["bytes_sent"]
@PluginManager.registerTo("Site")
class SitePlugin(object):
def isDownloadable(self, inner_path):
is_downloadable = super(SitePlugin, self).isDownloadable(inner_path)
if is_downloadable:
return is_downloadable
for path in self.settings.get("optional_help", {}).iterkeys():
if inner_path.startswith(path):
return True
return False
@PluginManager.registerTo("ConfigPlugin")
class ConfigPlugin(object):
def createArguments(self):
group = self.parser.add_argument_group("OptionalManager plugin")
group.add_argument('--optional_limit', help='Limit total size of optional files', default="10%", metavar="GB or free space %")
group.add_argument('--pin_bigfile', help='Automatically pin files larger than this limit', default=20, metavar="MB", type=int)
return super(ConfigPlugin, self).createArguments()

View file

@ -1,42 +0,0 @@
import hashlib
import os
import copy
import pytest
from OptionalManager import OptionalManagerPlugin
from util import helper
@pytest.mark.usefixtures("resetSettings")
class TestOptionalManager:
def testDbFill(self, site):
contents = site.content_manager.contents
assert len(site.content_manager.hashfield) > 0
assert contents.db.execute("SELECT COUNT(*) FROM file_optional WHERE is_downloaded = 1").fetchone()[0] == len(site.content_manager.hashfield)
def testSetContent(self, site):
contents = site.content_manager.contents
# Add new file
new_content = copy.deepcopy(contents["content.json"])
new_content["files_optional"]["testfile"] = {
"size": 1234,
"sha512": "aaaabbbbcccc"
}
num_optional_files_before = contents.db.execute("SELECT COUNT(*) FROM file_optional").fetchone()[0]
contents["content.json"] = new_content
assert contents.db.execute("SELECT COUNT(*) FROM file_optional").fetchone()[0] > num_optional_files_before
# Remove file
new_content = copy.deepcopy(contents["content.json"])
del new_content["files_optional"]["testfile"]
num_optional_files_before = contents.db.execute("SELECT COUNT(*) FROM file_optional").fetchone()[0]
contents["content.json"] = new_content
assert contents.db.execute("SELECT COUNT(*) FROM file_optional").fetchone()[0] < num_optional_files_before
def testDeleteContent(self, site):
contents = site.content_manager.contents
num_optional_files_before = contents.db.execute("SELECT COUNT(*) FROM file_optional").fetchone()[0]
del contents["content.json"]
assert contents.db.execute("SELECT COUNT(*) FROM file_optional").fetchone()[0] < num_optional_files_before

View file

@ -1 +0,0 @@
from src.Test.conftest import *

View file

@ -1,5 +0,0 @@
[pytest]
python_files = Test*.py
addopts = -rsxX -v --durations=6
markers =
webtest: mark a test as a webtest.

View file

@ -1,345 +0,0 @@
import re
import time
import cgi
import gevent
from Plugin import PluginManager
from Config import config
from util import helper
from Translate import Translate
if "_" not in locals():
_ = Translate("plugins/OptionalManager/languages/")
@PluginManager.registerTo("UiWebsocket")
class UiWebsocketPlugin(object):
def __init__(self, *args, **kwargs):
self.time_peer_numbers_updated = 0
super(UiWebsocketPlugin, self).__init__(*args, **kwargs)
def actionSiteSign(self, to, privatekey=None, inner_path="content.json", *args, **kwargs):
# Add file to content.db and set it as pinned
content_db = self.site.content_manager.contents.db
content_inner_dir = helper.getDirname(inner_path)
content_db.my_optional_files[self.site.address + "/" + content_inner_dir] = time.time()
if len(content_db.my_optional_files) > 50: # Keep only last 50
oldest_key = min(
content_db.my_optional_files.iterkeys(),
key=(lambda key: content_db.my_optional_files[key])
)
del content_db.my_optional_files[oldest_key]
return super(UiWebsocketPlugin, self).actionSiteSign(to, privatekey, inner_path, *args, **kwargs)
def updatePeerNumbers(self):
content_db = self.site.content_manager.contents.db
content_db.updatePeerNumbers()
self.site.updateWebsocket(peernumber_updated=True)
def addBigfileInfo(self, row):
content_db = self.site.content_manager.contents.db
site = content_db.sites[row["address"]]
if not site.settings.get("has_bigfile"):
return False
file_info = site.content_manager.getFileInfo(row["inner_path"])
if not file_info.get("piece_size"):
return False
sha512 = file_info["sha512"]
if sha512 in site.storage.piecefields:
piecefield = site.storage.piecefields[sha512].tostring()
else:
piecefield = None
if piecefield:
row["pieces"] = len(piecefield)
row["pieces_downloaded"] = piecefield.count("1")
row["downloaded_percent"] = 100 * row["pieces_downloaded"] / row["pieces"]
row["bytes_downloaded"] = row["pieces_downloaded"] * file_info["piece_size"]
row["is_downloading"] = bool(next((task for task in site.worker_manager.tasks if task["inner_path"].startswith(row["inner_path"])), False))
# Add leech / seed stats
row["peer_seed"] = 0
row["peer_leech"] = 0
for peer in site.peers.itervalues():
if not peer.time_piecefields_updated or sha512 not in peer.piecefields:
continue
peer_piecefield = peer.piecefields[sha512].tostring()
if not peer_piecefield:
continue
if peer_piecefield == "1" * len(peer_piecefield):
row["peer_seed"] += 1
else:
row["peer_leech"] += 1
# Add myself
if piecefield:
if row["pieces_downloaded"] == row["pieces"]:
row["peer_seed"] += 1
else:
row["peer_leech"] += 1
return True
# Optional file functions
def actionOptionalFileList(self, to, address=None, orderby="time_downloaded DESC", limit=10, filter="downloaded"):
if not address:
address = self.site.address
# Update peer numbers if necessary
content_db = self.site.content_manager.contents.db
if time.time() - content_db.time_peer_numbers_updated > 60 * 1 and time.time() - self.time_peer_numbers_updated > 60 * 5:
# Start in new thread to avoid blocking
self.time_peer_numbers_updated = time.time()
gevent.spawn(self.updatePeerNumbers)
if address == "all" and "ADMIN" not in self.permissions:
return self.response(to, {"error": "Forbidden"})
if not self.hasSitePermission(address):
return self.response(to, {"error": "Forbidden"})
if not all([re.match("^[a-z_*/+-]+( DESC| ASC|)$", part.strip()) for part in orderby.split(",")]):
return self.response(to, "Invalid order_by")
if type(limit) != int:
return self.response(to, "Invalid limit")
back = []
content_db = self.site.content_manager.contents.db
wheres = {}
if "bigfile" in filter:
wheres["size >"] = 1024 * 1024 * 10
if "downloaded" in filter:
wheres["is_downloaded"] = 1
if address == "all":
join = "LEFT JOIN site USING (site_id)"
else:
wheres["site_id"] = content_db.site_ids[address]
join = ""
query = "SELECT * FROM file_optional %s WHERE ? ORDER BY %s LIMIT %s" % (join, orderby, limit)
for row in content_db.execute(query, wheres):
row = dict(row)
if address != "all":
row["address"] = address
if row["size"] > 1024 * 1024:
has_info = self.addBigfileInfo(row)
else:
has_info = False
if not has_info:
if row["is_downloaded"]:
row["bytes_downloaded"] = row["size"]
row["downloaded_percent"] = 100
else:
row["bytes_downloaded"] = 0
row["downloaded_percent"] = 0
back.append(row)
self.response(to, back)
def actionOptionalFileInfo(self, to, inner_path):
content_db = self.site.content_manager.contents.db
site_id = content_db.site_ids[self.site.address]
# Update peer numbers if necessary
if time.time() - content_db.time_peer_numbers_updated > 60 * 1 and time.time() - self.time_peer_numbers_updated > 60 * 5:
# Start in new thread to avoid blocking
self.time_peer_numbers_updated = time.time()
gevent.spawn(self.updatePeerNumbers)
query = "SELECT * FROM file_optional WHERE site_id = :site_id AND inner_path = :inner_path LIMIT 1"
res = content_db.execute(query, {"site_id": site_id, "inner_path": inner_path})
row = next(res, None)
if row:
row = dict(row)
if row["size"] > 1024 * 1024:
row["address"] = self.site.address
self.addBigfileInfo(row)
self.response(to, row)
else:
self.response(to, None)
def setPin(self, inner_path, is_pinned, address=None):
if not address:
address = self.site.address
if not self.hasSitePermission(address):
return {"error": "Forbidden"}
site = self.server.sites[address]
content_db = site.content_manager.contents.db
site_id = content_db.site_ids[site.address]
content_db.execute("UPDATE file_optional SET is_pinned = %s WHERE ?" % is_pinned, {"site_id": site_id, "inner_path": inner_path})
return "ok"
def actionOptionalFilePin(self, to, inner_path, address=None):
back = self.setPin(inner_path, 1, address)
if back == "ok":
self.cmd("notification", ["done", _["Pinned %s files"] % len(inner_path) if type(inner_path) is list else 1, 5000])
self.response(to, back)
def actionOptionalFileUnpin(self, to, inner_path, address=None):
back = self.setPin(inner_path, 0, address)
if back == "ok":
self.cmd("notification", ["done", _["Removed pin from %s files"] % len(inner_path) if type(inner_path) is list else 1, 5000])
self.response(to, back)
def actionOptionalFileDelete(self, to, inner_path, address=None):
if not address:
address = self.site.address
if not self.hasSitePermission(address):
return self.response(to, {"error": "Forbidden"})
site = self.server.sites[address]
content_db = site.content_manager.contents.db
site_id = content_db.site_ids[site.address]
res = content_db.execute("SELECT * FROM file_optional WHERE ? LIMIT 1", {"site_id": site_id, "inner_path": inner_path, "is_downloaded": 1})
row = next(res, None)
if not row:
return self.response(to, {"error": "Not found in content.db"})
removed = site.content_manager.optionalRemove(inner_path, row["hash_id"], row["size"])
# if not removed:
# return self.response(to, {"error": "Not found in hash_id: %s" % row["hash_id"]})
content_db.execute("UPDATE file_optional SET is_downloaded = 0, is_pinned = 0, peer = peer - 1 WHERE ?", {"site_id": site_id, "inner_path": inner_path})
try:
site.storage.delete(inner_path)
except Exception as err:
return self.response(to, {"error": "File delete error: %s" % err})
site.updateWebsocket(file_delete=inner_path)
self.response(to, "ok")
# Limit functions
def actionOptionalLimitStats(self, to):
if "ADMIN" not in self.site.settings["permissions"]:
return self.response(to, "Forbidden")
back = {}
back["limit"] = config.optional_limit
back["used"] = self.site.content_manager.contents.db.execute(
"SELECT SUM(size) FROM file_optional WHERE is_downloaded = 1 AND is_pinned = 0"
).fetchone()[0]
back["free"] = helper.getFreeSpace()
self.response(to, back)
def actionOptionalLimitSet(self, to, limit):
if "ADMIN" not in self.site.settings["permissions"]:
return self.response(to, {"error": "Forbidden"})
config.optional_limit = re.sub("\.0+$", "", limit) # Remove unnecessary digits from end
config.saveValue("optional_limit", limit)
self.response(to, "ok")
# Distribute help functions
def actionOptionalHelpList(self, to, address=None):
if not address:
address = self.site.address
if not self.hasSitePermission(address):
return self.response(to, {"error": "Forbidden"})
site = self.server.sites[address]
self.response(to, site.settings.get("optional_help", {}))
def actionOptionalHelp(self, to, directory, title, address=None):
if not address:
address = self.site.address
if not self.hasSitePermission(address):
return self.response(to, {"error": "Forbidden"})
site = self.server.sites[address]
content_db = site.content_manager.contents.db
site_id = content_db.site_ids[address]
if "optional_help" not in site.settings:
site.settings["optional_help"] = {}
stats = content_db.execute(
"SELECT COUNT(*) AS num, SUM(size) AS size FROM file_optional WHERE site_id = :site_id AND inner_path LIKE :inner_path",
{"site_id": site_id, "inner_path": directory + "%"}
).fetchone()
stats = dict(stats)
if not stats["size"]:
stats["size"] = 0
if not stats["num"]:
stats["num"] = 0
self.cmd("notification", [
"done",
_["You started to help distribute <b>%s</b>.<br><small>Directory: %s</small>"] %
(cgi.escape(title), cgi.escape(directory)),
10000
])
site.settings["optional_help"][directory] = title
self.response(to, dict(stats))
def actionOptionalHelpRemove(self, to, directory, address=None):
if not address:
address = self.site.address
if not self.hasSitePermission(address):
return self.response(to, {"error": "Forbidden"})
site = self.server.sites[address]
try:
del site.settings["optional_help"][directory]
self.response(to, "ok")
except Exception:
self.response(to, {"error": "Not found"})
def cbOptionalHelpAll(self, to, site, value):
site.settings["autodownloadoptional"] = value
self.response(to, value)
def actionOptionalHelpAll(self, to, value, address=None):
if not address:
address = self.site.address
if not self.hasSitePermission(address):
return self.response(to, {"error": "Forbidden"})
site = self.server.sites[address]
if value:
if "ADMIN" in self.site.settings["permissions"]:
self.cbOptionalHelpAll(to, site, True)
else:
site_title = site.content_manager.contents["content.json"].get("title", address)
self.cmd(
"confirm",
[
_["Help distribute all new optional files on site <b>%s</b>"] % cgi.escape(site_title),
_["Yes, I want to help!"]
],
lambda (res): self.cbOptionalHelpAll(to, site, True)
)
else:
site.settings["autodownloadoptional"] = False
self.response(to, False)

View file

@ -1 +0,0 @@
import OptionalManagerPlugin

View file

@ -1,7 +0,0 @@
{
"Pinned %s files": "Archivos %s fijados",
"Removed pin from %s files": "Archivos %s que no estan fijados",
"You started to help distribute <b>%s</b>.<br><small>Directory: %s</small>": "Tu empezaste a ayudar a distribuir <b>%s</b>.<br><small>Directorio: %s</small>",
"Help distribute all new optional files on site <b>%s</b>": "Ayude a distribuir todos los archivos opcionales en el sitio <b>%s</b>",
"Yes, I want to help!": "¡Si, yo quiero ayudar!"
}

View file

@ -1,7 +0,0 @@
{
"Pinned %s files": "Fichiers %s épinglés",
"Removed pin from %s files": "Fichiers %s ne sont plus épinglés",
"You started to help distribute <b>%s</b>.<br><small>Directory: %s</small>": "Vous avez commencé à aider à distribuer <b>%s</b>.<br><small>Dossier : %s</small>",
"Help distribute all new optional files on site <b>%s</b>": "Aider à distribuer tous les fichiers optionnels du site <b>%s</b>",
"Yes, I want to help!": "Oui, je veux aider !"
}

View file

@ -1,7 +0,0 @@
{
"Pinned %s files": "%s fájl rögzítve",
"Removed pin from %s files": "%s fájl rögzítés eltávolítva",
"You started to help distribute <b>%s</b>.<br><small>Directory: %s</small>": "Új segítség a terjesztésben: <b>%s</b>.<br><small>Könyvtár: %s</small>",
"Help distribute all new optional files on site <b>%s</b>": "Segítség az összes új opcionális fájl terjesztésében az <b>%s</b> oldalon",
"Yes, I want to help!": "Igen, segíteni akarok!"
}

View file

@ -1,7 +0,0 @@
{
"Pinned %s files": "Arquivos %s fixados",
"Removed pin from %s files": "Arquivos %s não estão fixados",
"You started to help distribute <b>%s</b>.<br><small>Directory: %s</small>": "Você começou a ajudar a distribuir <b>%s</b>.<br><small>Pasta: %s</small>",
"Help distribute all new optional files on site <b>%s</b>": "Ajude a distribuir todos os novos arquivos opcionais no site <b>%s</b>",
"Yes, I want to help!": "Sim, eu quero ajudar!"
}

View file

@ -1,7 +0,0 @@
{
"Pinned %s files": "已固定 %s 個檔",
"Removed pin from %s files": "已解除固定 %s 個檔",
"You started to help distribute <b>%s</b>.<br><small>Directory: %s</small>": "你已經開始幫助分發 <b>%s</b> 。<br><small>目錄:%s</small>",
"Help distribute all new optional files on site <b>%s</b>": "你想要幫助分發 <b>%s</b> 網站的所有檔嗎?",
"Yes, I want to help!": "是,我想要幫助!"
}

View file

@ -1,7 +0,0 @@
{
"Pinned %s files": "已固定 %s 个文件",
"Removed pin from %s files": "已解除固定 %s 个文件",
"You started to help distribute <b>%s</b>.<br><small>Directory: %s</small>": "你已经开始帮助分发 <b>%s</b> 。<br><small>目录:%s</small>",
"Help distribute all new optional files on site <b>%s</b>": "你想要帮助分发 <b>%s</b> 站点的所有文件吗?",
"Yes, I want to help!": "是,我想要帮助!"
}

View file

@ -1,100 +0,0 @@
import time
import sqlite3
import random
import atexit
import gevent
from Plugin import PluginManager
@PluginManager.registerTo("ContentDb")
class ContentDbPlugin(object):
def __init__(self, *args, **kwargs):
atexit.register(self.saveAllPeers)
super(ContentDbPlugin, self).__init__(*args, **kwargs)
def getSchema(self):
schema = super(ContentDbPlugin, self).getSchema()
schema["tables"]["peer"] = {
"cols": [
["site_id", "INTEGER REFERENCES site (site_id) ON DELETE CASCADE"],
["address", "TEXT NOT NULL"],
["port", "INTEGER NOT NULL"],
["hashfield", "BLOB"],
["time_added", "INTEGER NOT NULL"]
],
"indexes": [
"CREATE UNIQUE INDEX peer_key ON peer (site_id, address, port)"
],
"schema_changed": 1
}
return schema
def loadPeers(self, site):
s = time.time()
site_id = self.site_ids.get(site.address)
res = self.execute("SELECT * FROM peer WHERE site_id = :site_id", {"site_id": site_id})
num = 0
num_hashfield = 0
for row in res:
peer = site.addPeer(row["address"], row["port"])
if not peer: # Already exist
continue
if row["hashfield"]:
peer.hashfield.replaceFromString(row["hashfield"])
num_hashfield += 1
peer.time_added = row["time_added"]
peer.reputation = int((time.time() - peer.time_added) / (60 * 60 * 24)) # Boost reputation for older peers
if row["address"].endswith(".onion"):
peer.reputation = peer.reputation / 2 # Onion peers less likely working
num += 1
if num_hashfield:
site.content_manager.has_optional_files = True
site.log.debug("%s peers (%s with hashfield) loaded in %.3fs" % (num, num_hashfield, time.time() - s))
def iteratePeers(self, site):
site_id = self.site_ids.get(site.address)
for key, peer in site.peers.iteritems():
address, port = key.split(":")
if peer.has_hashfield:
hashfield = sqlite3.Binary(peer.hashfield.tostring())
else:
hashfield = ""
yield (site_id, address, port, hashfield, int(peer.time_added))
def savePeers(self, site, spawn=False):
if spawn:
# Save peers every hour (+random some secs to not update very site at same time)
gevent.spawn_later(60 * 60 + random.randint(0, 60), self.savePeers, site, spawn=True)
if not site.peers:
site.log.debug("Peers not saved: No peers found")
return
s = time.time()
site_id = self.site_ids.get(site.address)
cur = self.getCursor()
cur.execute("BEGIN")
try:
self.execute("DELETE FROM peer WHERE site_id = :site_id", {"site_id": site_id})
self.cur.cursor.executemany(
"INSERT INTO peer (site_id, address, port, hashfield, time_added) VALUES (?, ?, ?, ?, ?)",
self.iteratePeers(site)
)
except Exception as err:
site.log.error("Save peer error: %s" % err)
finally:
cur.execute("END")
site.log.debug("Peers saved in %.3fs" % (time.time() - s))
def initSite(self, site):
super(ContentDbPlugin, self).initSite(site)
gevent.spawn_later(0.5, self.loadPeers, site)
gevent.spawn_later(60*60, self.savePeers, site, spawn=True)
def saveAllPeers(self):
for site in self.sites.values():
try:
self.savePeers(site)
except Exception, err:
site.log.error("Save peer error: %s" % err)

View file

@ -1,2 +0,0 @@
import PeerDbPlugin

View file

@ -1,616 +0,0 @@
import re
import os
import cgi
import sys
import math
import time
import json
try:
import cStringIO as StringIO
except:
import StringIO
import gevent
from Config import config
from Plugin import PluginManager
from Debug import Debug
from Translate import Translate
from util import helper
plugin_dir = "plugins/Sidebar"
media_dir = plugin_dir + "/media"
sys.path.append(plugin_dir) # To able to load geoip lib
loc_cache = {}
if "_" not in locals():
_ = Translate(plugin_dir + "/languages/")
@PluginManager.registerTo("UiRequest")
class UiRequestPlugin(object):
# Inject our resources to end of original file streams
def actionUiMedia(self, path):
if path == "/uimedia/all.js" or path == "/uimedia/all.css":
# First yield the original file and header
body_generator = super(UiRequestPlugin, self).actionUiMedia(path)
for part in body_generator:
yield part
# Append our media file to the end
ext = re.match(".*(js|css)$", path).group(1)
plugin_media_file = "%s/all.%s" % (media_dir, ext)
if config.debug:
# If debugging merge *.css to all.css and *.js to all.js
from Debug import DebugMedia
DebugMedia.merge(plugin_media_file)
if ext == "js":
yield _.translateData(open(plugin_media_file).read())
else:
for part in self.actionFile(plugin_media_file, send_header=False):
yield part
elif path.startswith("/uimedia/globe/"): # Serve WebGL globe files
file_name = re.match(".*/(.*)", path).group(1)
plugin_media_file = "%s-globe/%s" % (media_dir, file_name)
if config.debug and path.endswith("all.js"):
# If debugging merge *.css to all.css and *.js to all.js
from Debug import DebugMedia
DebugMedia.merge(plugin_media_file)
for part in self.actionFile(plugin_media_file):
yield part
else:
for part in super(UiRequestPlugin, self).actionUiMedia(path):
yield part
@PluginManager.registerTo("UiWebsocket")
class UiWebsocketPlugin(object):
def sidebarRenderPeerStats(self, body, site):
connected = len([peer for peer in site.peers.values() if peer.connection and peer.connection.connected])
connectable = len([peer_id for peer_id in site.peers.keys() if not peer_id.endswith(":0")])
onion = len([peer_id for peer_id in site.peers.keys() if ".onion" in peer_id])
peers_total = len(site.peers)
# Add myself
if site.settings["serving"]:
peers_total += 1
if site.connection_server.port_opened:
connectable += 1
if site.connection_server.tor_manager.start_onions:
onion += 1
if peers_total:
percent_connected = float(connected) / peers_total
percent_connectable = float(connectable) / peers_total
percent_onion = float(onion) / peers_total
else:
percent_connectable = percent_connected = percent_onion = 0
body.append(_(u"""
<li>
<label>{_[Peers]}</label>
<ul class='graph'>
<li style='width: 100%' class='total back-black' title="{_[Total peers]}"></li>
<li style='width: {percent_connectable:.0%}' class='connectable back-blue' title='{_[Connectable peers]}'></li>
<li style='width: {percent_onion:.0%}' class='connected back-purple' title='{_[Onion]}'></li>
<li style='width: {percent_connected:.0%}' class='connected back-green' title='{_[Connected peers]}'></li>
</ul>
<ul class='graph-legend'>
<li class='color-green'><span>{_[Connected]}:</span><b>{connected}</b></li>
<li class='color-blue'><span>{_[Connectable]}:</span><b>{connectable}</b></li>
<li class='color-purple'><span>{_[Onion]}:</span><b>{onion}</b></li>
<li class='color-black'><span>{_[Total]}:</span><b>{peers_total}</b></li>
</ul>
</li>
"""))
def sidebarRenderTransferStats(self, body, site):
recv = float(site.settings.get("bytes_recv", 0)) / 1024 / 1024
sent = float(site.settings.get("bytes_sent", 0)) / 1024 / 1024
transfer_total = recv + sent
if transfer_total:
percent_recv = recv / transfer_total
percent_sent = sent / transfer_total
else:
percent_recv = 0.5
percent_sent = 0.5
body.append(_(u"""
<li>
<label>{_[Data transfer]}</label>
<ul class='graph graph-stacked'>
<li style='width: {percent_recv:.0%}' class='received back-yellow' title="{_[Received bytes]}"></li>
<li style='width: {percent_sent:.0%}' class='sent back-green' title="{_[Sent bytes]}"></li>
</ul>
<ul class='graph-legend'>
<li class='color-yellow'><span>{_[Received]}:</span><b>{recv:.2f}MB</b></li>
<li class='color-green'<span>{_[Sent]}:</span><b>{sent:.2f}MB</b></li>
</ul>
</li>
"""))
def sidebarRenderFileStats(self, body, site):
body.append(_(u"<li><label>{_[Files]}</label><ul class='graph graph-stacked'>"))
extensions = (
("html", "yellow"),
("css", "orange"),
("js", "purple"),
("Image", "green"),
("json", "darkblue"),
("User data", "blue"),
("Other", "white"),
("Total", "black")
)
# Collect stats
size_filetypes = {}
size_total = 0
contents = site.content_manager.listContents() # Without user files
for inner_path in contents:
content = site.content_manager.contents[inner_path]
if "files" not in content:
continue
for file_name, file_details in content["files"].items():
size_total += file_details["size"]
ext = file_name.split(".")[-1]
size_filetypes[ext] = size_filetypes.get(ext, 0) + file_details["size"]
# Get user file sizes
size_user_content = site.content_manager.contents.execute(
"SELECT SUM(size) + SUM(size_files) AS size FROM content WHERE ?",
{"not__inner_path": contents}
).fetchone()["size"]
if not size_user_content:
size_user_content = 0
size_filetypes["User data"] = size_user_content
size_total += size_user_content
# The missing difference is content.json sizes
if "json" in size_filetypes:
size_filetypes["json"] += max(0, site.settings["size"] - size_total)
size_total = size_other = site.settings["size"]
# Bar
for extension, color in extensions:
if extension == "Total":
continue
if extension == "Other":
size = max(0, size_other)
elif extension == "Image":
size = size_filetypes.get("jpg", 0) + size_filetypes.get("png", 0) + size_filetypes.get("gif", 0)
size_other -= size
else:
size = size_filetypes.get(extension, 0)
size_other -= size
if size_total == 0:
percent = 0
else:
percent = 100 * (float(size) / size_total)
percent = math.floor(percent * 100) / 100 # Floor to 2 digits
body.append(
u"""<li style='width: %.2f%%' class='%s back-%s' title="%s"></li>""" %
(percent, _[extension], color, _[extension])
)
# Legend
body.append("</ul><ul class='graph-legend'>")
for extension, color in extensions:
if extension == "Other":
size = max(0, size_other)
elif extension == "Image":
size = size_filetypes.get("jpg", 0) + size_filetypes.get("png", 0) + size_filetypes.get("gif", 0)
elif extension == "Total":
size = size_total
else:
size = size_filetypes.get(extension, 0)
if extension == "js":
title = "javascript"
else:
title = extension
if size > 1024 * 1024 * 10: # Format as mB is more than 10mB
size_formatted = "%.0fMB" % (size / 1024 / 1024)
else:
size_formatted = "%.0fkB" % (size / 1024)
body.append(u"<li class='color-%s'><span>%s:</span><b>%s</b></li>" % (color, _[title], size_formatted))
body.append("</ul></li>")
def sidebarRenderSizeLimit(self, body, site):
free_space = helper.getFreeSpace() / 1024 / 1024
size = float(site.settings["size"]) / 1024 / 1024
size_limit = site.getSizeLimit()
percent_used = size / size_limit
body.append(_(u"""
<li>
<label>{_[Size limit]} <small>({_[limit used]}: {percent_used:.0%}, {_[free space]}: {free_space:,d}MB)</small></label>
<input type='text' class='text text-num' value="{size_limit}" id='input-sitelimit'/><span class='text-post'>MB</span>
<a href='#Set' class='button' id='button-sitelimit'>{_[Set]}</a>
</li>
"""))
def sidebarRenderOptionalFileStats(self, body, site):
size_total = float(site.settings["size_optional"])
size_downloaded = float(site.settings["optional_downloaded"])
if not size_total:
return False
percent_downloaded = size_downloaded / size_total
size_formatted_total = size_total / 1024 / 1024
size_formatted_downloaded = size_downloaded / 1024 / 1024
body.append(_(u"""
<li>
<label>{_[Optional files]}</label>
<ul class='graph'>
<li style='width: 100%' class='total back-black' title="{_[Total size]}"></li>
<li style='width: {percent_downloaded:.0%}' class='connected back-green' title='{_[Downloaded files]}'></li>
</ul>
<ul class='graph-legend'>
<li class='color-green'><span>{_[Downloaded]}:</span><b>{size_formatted_downloaded:.2f}MB</b></li>
<li class='color-black'><span>{_[Total]}:</span><b>{size_formatted_total:.2f}MB</b></li>
</ul>
</li>
"""))
return True
def sidebarRenderOptionalFileSettings(self, body, site):
if self.site.settings.get("autodownloadoptional"):
checked = "checked='checked'"
else:
checked = ""
body.append(_(u"""
<li>
<label>{_[Download and help distribute all files]}</label>
<input type="checkbox" class="checkbox" id="checkbox-autodownloadoptional" {checked}/><div class="checkbox-skin"></div>
</li>
"""))
def sidebarRenderBadFiles(self, body, site):
body.append(_(u"""
<li>
<label>{_[Missing files]}:</label>
<ul class='filelist'>
"""))
i = 0
for bad_file, tries in site.bad_files.iteritems():
i += 1
body.append(_(u"""<li class='color-red' title="{bad_file} ({tries})">{bad_file}</li>""", {
"bad_file": cgi.escape(bad_file, True), "tries": _.pluralize(tries, "{} try", "{} tries")
}))
if i > 30:
break
if len(site.bad_files) > 30:
num_bad_files = len(site.bad_files) - 30
body.append(_(u"""<li class='color-red'>{_[+ {num_bad_files} more]}</li>""", nested=True))
body.append("""
</ul>
</li>
""")
def sidebarRenderDbOptions(self, body, site):
if site.storage.db:
inner_path = site.storage.getInnerPath(site.storage.db.db_path)
size = float(site.storage.getSize(inner_path)) / 1024
feeds = len(site.storage.db.schema.get("feeds", {}))
else:
inner_path = _[u"No database found"]
size = 0.0
feeds = 0
body.append(_(u"""
<li>
<label>{_[Database]} <small>({size:.2f}kB, {_[search feeds]}: {_[{feeds} query]})</small></label>
<div class='flex'>
<input type='text' class='text disabled' value="{inner_path}" disabled='disabled'/>
<a href='#Reload' id="button-dbreload" class='button'>{_[Reload]}</a>
<a href='#Rebuild' id="button-dbrebuild" class='button'>{_[Rebuild]}</a>
</div>
</li>
""", nested=True))
def sidebarRenderIdentity(self, body, site):
auth_address = self.user.getAuthAddress(self.site.address)
rules = self.site.content_manager.getRules("data/users/%s/content.json" % auth_address)
if rules and rules.get("max_size"):
quota = rules["max_size"] / 1024
try:
content = site.content_manager.contents["data/users/%s/content.json" % auth_address]
used = len(json.dumps(content)) + sum([file["size"] for file in content["files"].values()])
except:
used = 0
used = used / 1024
else:
quota = used = 0
body.append(_(u"""
<li>
<label>{_[Identity address]} <small>({_[limit used]}: {used:.2f}kB / {quota:.2f}kB)</small></label>
<div class='flex'>
<span class='input text disabled'>{auth_address}</span>
<a href='#Change' class='button' id='button-identity'>{_[Change]}</a>
</div>
</li>
"""))
def sidebarRenderControls(self, body, site):
auth_address = self.user.getAuthAddress(self.site.address)
if self.site.settings["serving"]:
class_pause = ""
class_resume = "hidden"
else:
class_pause = "hidden"
class_resume = ""
body.append(_(u"""
<li>
<label>{_[Site control]}</label>
<a href='#Update' class='button noupdate' id='button-update'>{_[Update]}</a>
<a href='#Pause' class='button {class_pause}' id='button-pause'>{_[Pause]}</a>
<a href='#Resume' class='button {class_resume}' id='button-resume'>{_[Resume]}</a>
<a href='#Delete' class='button noupdate' id='button-delete'>{_[Delete]}</a>
</li>
"""))
site_address = self.site.address
body.append(_(u"""
<li>
<label>{_[Site address]}</label><br>
<div class='flex'>
<span class='input text disabled'>{site_address}</span>
<a href='bitcoin:{site_address}' class='button' id='button-donate'>{_[Donate]}</a>
</div>
</li>
"""))
def sidebarRenderOwnedCheckbox(self, body, site):
if self.site.settings["own"]:
checked = "checked='checked'"
else:
checked = ""
body.append(_(u"""
<h2 class='owned-title'>{_[This is my site]}</h2>
<input type="checkbox" class="checkbox" id="checkbox-owned" {checked}/><div class="checkbox-skin"></div>
"""))
def sidebarRenderOwnSettings(self, body, site):
title = cgi.escape(site.content_manager.contents.get("content.json", {}).get("title", ""), True)
description = cgi.escape(site.content_manager.contents.get("content.json", {}).get("description", ""), True)
privatekey = cgi.escape(self.user.getSiteData(site.address, create=False).get("privatekey", ""))
body.append(_(u"""
<li>
<label for='settings-title'>{_[Site title]}</label>
<input type='text' class='text' value="{title}" id='settings-title'/>
</li>
<li>
<label for='settings-description'>{_[Site description]}</label>
<input type='text' class='text' value="{description}" id='settings-description'/>
</li>
<li style='display: none'>
<label>{_[Private key]}</label>
<input type='text' class='text long' value="{privatekey}" placeholder='{_[Ask when signing]}'/>
</li>
<li>
<a href='#Save' class='button' id='button-settings'>{_[Save site settings]}</a>
</li>
"""))
def sidebarRenderContents(self, body, site):
body.append(_(u"""
<li>
<label>{_[Content publishing]}</label>
"""))
# Choose content you want to sign
contents = ["content.json"]
contents += site.content_manager.contents.get("content.json", {}).get("includes", {}).keys()
body.append(_(u"<div class='contents'>{_[Choose]}: "))
for content in contents:
content = cgi.escape(content, True)
body.append(_("<a href='#{content}' onclick='$(\"#input-contents\").val(\"{content}\"); return false'>{content}</a> "))
body.append("</div>")
body.append(_(u"""
<div class='flex'>
<input type='text' class='text' value="content.json" id='input-contents'/>
<a href='#Sign' class='button' id='button-sign'>{_[Sign]}</a>
<a href='#Publish' class='button' id='button-publish'>{_[Publish]}</a>
</div>
</li>
"""))
def actionSidebarGetHtmlTag(self, to):
site = self.site
body = []
body.append("<div>")
body.append("<a href='#Close' class='close'>&times;</a>")
body.append("<h1>%s</h1>" % cgi.escape(site.content_manager.contents.get("content.json", {}).get("title", ""), True))
body.append("<div class='globe loading'></div>")
body.append("<ul class='fields'>")
self.sidebarRenderPeerStats(body, site)
self.sidebarRenderTransferStats(body, site)
self.sidebarRenderFileStats(body, site)
self.sidebarRenderSizeLimit(body, site)
has_optional = self.sidebarRenderOptionalFileStats(body, site)
if has_optional:
self.sidebarRenderOptionalFileSettings(body, site)
self.sidebarRenderDbOptions(body, site)
self.sidebarRenderIdentity(body, site)
self.sidebarRenderControls(body, site)
if site.bad_files:
self.sidebarRenderBadFiles(body, site)
self.sidebarRenderOwnedCheckbox(body, site)
body.append("<div class='settings-owned'>")
self.sidebarRenderOwnSettings(body, site)
self.sidebarRenderContents(body, site)
body.append("</div>")
body.append("</ul>")
body.append("</div>")
self.response(to, "".join(body))
def downloadGeoLiteDb(self, db_path):
import urllib
import gzip
import shutil
from util import helper
self.log.info("Downloading GeoLite2 City database...")
self.cmd("notification", ["geolite-info", _["Downloading GeoLite2 City database (one time only, ~20MB)..."], 0])
db_urls = [
"https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz",
"https://raw.githubusercontent.com/texnikru/GeoLite2-Database/master/GeoLite2-City.mmdb.gz"
]
for db_url in db_urls:
try:
# Download
response = helper.httpRequest(db_url)
data = StringIO.StringIO()
while True:
buff = response.read(1024 * 512)
if not buff:
break
data.write(buff)
self.log.info("GeoLite2 City database downloaded (%s bytes), unpacking..." % data.tell())
data.seek(0)
# Unpack
with gzip.GzipFile(fileobj=data) as gzip_file:
shutil.copyfileobj(gzip_file, open(db_path, "wb"))
self.cmd("notification", ["geolite-done", _["GeoLite2 City database downloaded!"], 5000])
time.sleep(2) # Wait for notify animation
return True
except Exception as err:
self.log.error("Error downloading %s: %s" % (db_url, err))
pass
self.cmd("notification", [
"geolite-error",
_["GeoLite2 City database download error: {}!<br>Please download manually and unpack to data dir:<br>{}"].format(err, db_urls[0]),
0
])
def actionSidebarGetPeers(self, to):
permissions = self.getPermissions(to)
if "ADMIN" not in permissions:
return self.response(to, "You don't have permission to run this command")
try:
import maxminddb
db_path = config.data_dir + '/GeoLite2-City.mmdb'
if not os.path.isfile(db_path) or os.path.getsize(db_path) == 0:
if not self.downloadGeoLiteDb(db_path):
return False
geodb = maxminddb.open_database(db_path)
peers = self.site.peers.values()
# Find avg ping
ping_times = [
peer.connection.last_ping_delay
for peer in peers
if peer.connection and peer.connection.last_ping_delay and peer.connection.last_ping_delay
]
if ping_times:
ping_avg = sum(ping_times) / float(len(ping_times))
else:
ping_avg = 0
# Place bars
globe_data = []
placed = {} # Already placed bars here
for peer in peers:
# Height of bar
if peer.connection and peer.connection.last_ping_delay:
ping = min(0.20, math.log(1 + peer.connection.last_ping_delay / ping_avg, 300))
else:
ping = -0.03
# Query and cache location
if peer.ip in loc_cache:
loc = loc_cache[peer.ip]
else:
try:
loc = geodb.get(peer.ip)
except:
loc = None
loc_cache[peer.ip] = loc
if not loc or "location" not in loc:
continue
# Create position array
lat, lon = (loc["location"]["latitude"], loc["location"]["longitude"])
latlon = "%s,%s" % (lat, lon)
if latlon in placed: # Dont place more than 1 bar to same place, fake repos using ip address last two part
lat += float(128 - int(peer.ip.split(".")[-2])) / 50
lon += float(128 - int(peer.ip.split(".")[-1])) / 50
latlon = "%s,%s" % (lat, lon)
placed[latlon] = True
globe_data += (lat, lon, ping)
# Append myself
loc = geodb.get(config.ip_external)
if loc and loc.get("location"):
lat, lon = (loc["location"]["latitude"], loc["location"]["longitude"])
globe_data += (lat, lon, -0.135)
self.response(to, globe_data)
except Exception, err:
self.log.debug("sidebarGetPeers error: %s" % Debug.formatException(err))
self.response(to, {"error": err})
def actionSiteSetOwned(self, to, owned):
permissions = self.getPermissions(to)
if "ADMIN" not in permissions:
return self.response(to, "You don't have permission to run this command")
self.site.settings["own"] = bool(owned)
self.site.updateWebsocket(owned=owned)
def actionSiteSetAutodownloadoptional(self, to, owned):
permissions = self.getPermissions(to)
if "ADMIN" not in permissions:
return self.response(to, "You don't have permission to run this command")
self.site.settings["autodownloadoptional"] = bool(owned)
self.site.bad_files = {}
gevent.spawn(self.site.update, check_files=True)
self.site.worker_manager.removeGoodFileTasks()
def actionDbReload(self, to):
permissions = self.getPermissions(to)
if "ADMIN" not in permissions:
return self.response(to, "You don't have permission to run this command")
self.site.storage.closeDb()
self.site.storage.getDb()
return self.response(to, "ok")
def actionDbRebuild(self, to):
permissions = self.getPermissions(to)
if "ADMIN" not in permissions:
return self.response(to, "You don't have permission to run this command")
self.site.storage.rebuildDb()
return self.response(to, "ok")

View file

@ -1 +0,0 @@
import SidebarPlugin

View file

@ -1,81 +0,0 @@
{
"Peers": "Klienter",
"Connected": "Forbundet",
"Connectable": "Mulige",
"Connectable peers": "Mulige klienter",
"Data transfer": "Data overførsel",
"Received": "Modtaget",
"Received bytes": "Bytes modtaget",
"Sent": "Sendt",
"Sent bytes": "Bytes sendt",
"Files": "Filer",
"Total": "I alt",
"Image": "Image",
"Other": "Andet",
"User data": "Bruger data",
"Size limit": "Side max størrelse",
"limit used": "brugt",
"free space": "fri",
"Set": "Opdater",
"Optional files": "Valgfri filer",
"Downloaded": "Downloadet",
"Download and help distribute all files": "Download og hjælp med at dele filer",
"Total size": "Størrelse i alt",
"Downloaded files": "Filer downloadet",
"Database": "Database",
"search feeds": "søgninger",
"{feeds} query": "{feeds} søgninger",
"Reload": "Genindlæs",
"Rebuild": "Genopbyg",
"No database found": "Ingen database fundet",
"Identity address": "Autorisations ID",
"Change": "Skift",
"Update": "Opdater",
"Pause": "Pause",
"Resume": "Aktiv",
"Delete": "Slet",
"Are you sure?": "Er du sikker?",
"Site address": "Side addresse",
"Donate": "Doner penge",
"Missing files": "Manglende filer",
"{} try": "{} forsøg",
"{} tries": "{} forsøg",
"+ {num_bad_files} more": "+ {num_bad_files} mere",
"This is my site": "Dette er min side",
"Site title": "Side navn",
"Site description": "Side beskrivelse",
"Save site settings": "Gem side opsætning",
"Content publishing": "Indhold offentliggøres",
"Choose": "Vælg",
"Sign": "Signer",
"Publish": "Offentliggør",
"This function is disabled on this proxy": "Denne funktion er slået fra på denne ZeroNet proxyEz a funkció ki van kapcsolva ezen a proxy-n",
"GeoLite2 City database download error: {}!<br>Please download manually and unpack to data dir:<br>{}": "GeoLite2 City database kunne ikke downloades: {}!<br>Download venligst databasen manuelt og udpak i data folder:<br>{}",
"Downloading GeoLite2 City database (one time only, ~20MB)...": "GeoLite2 város adatbázis letöltése (csak egyszer kell, kb 20MB)...",
"GeoLite2 City database downloaded!": "GeoLite2 City database downloadet!",
"Are you sure?": "Er du sikker?",
"Site storage limit modified!": "Side max størrelse ændret!",
"Database schema reloaded!": "Database definition genindlæst!",
"Database rebuilding....": "Genopbygger database...",
"Database rebuilt!": "Database genopbygget!",
"Site updated!": "Side opdateret!",
"Delete this site": "Slet denne side",
"File write error: ": "Fejl ved skrivning af fil: ",
"Site settings saved!": "Side opsætning gemt!",
"Enter your private key:": "Indtast din private nøgle:",
" Signed!": " Signeret!",
"WebGL not supported": "WebGL er ikke supporteret"
}

View file

@ -1,81 +0,0 @@
{
"Peers": "Peers",
"Connected": "Verbunden",
"Connectable": "Verbindbar",
"Connectable peers": "Verbindbare Peers",
"Data transfer": "Datei Transfer",
"Received": "Empfangen",
"Received bytes": "Empfangene Bytes",
"Sent": "Gesendet",
"Sent bytes": "Gesendete Bytes",
"Files": "Dateien",
"Total": "Gesamt",
"Image": "Bilder",
"Other": "Sonstiges",
"User data": "Nutzer Daten",
"Size limit": "Speicher Limit",
"limit used": "Limit benutzt",
"free space": "freier Speicher",
"Set": "Setzten",
"Optional files": "Optionale Dateien",
"Downloaded": "Heruntergeladen",
"Download and help distribute all files": "Herunterladen und helfen alle Dateien zu verteilen",
"Total size": "Gesamte Größe",
"Downloaded files": "Heruntergeladene Dateien",
"Database": "Datenbank",
"search feeds": "Feeds durchsuchen",
"{feeds} query": "{feeds} Abfrage",
"Reload": "Neu laden",
"Rebuild": "Neu bauen",
"No database found": "Keine Datenbank gefunden",
"Identity address": "Identitäts Adresse",
"Change": "Ändern",
"Update": "Aktualisieren",
"Pause": "Pausieren",
"Resume": "Fortsetzen",
"Delete": "Löschen",
"Are you sure?": "Bist du sicher?",
"Site address": "Seiten Adresse",
"Donate": "Spenden",
"Missing files": "Fehlende Dateien",
"{} try": "{} versuch",
"{} tries": "{} versuche",
"+ {num_bad_files} more": "+ {num_bad_files} mehr",
"This is my site": "Das ist meine Seite",
"Site title": "Seiten Titel",
"Site description": "Seiten Beschreibung",
"Save site settings": "Einstellungen der Seite speichern",
"Content publishing": "Inhaltsveröffentlichung",
"Choose": "Wähle",
"Sign": "Signieren",
"Publish": "Veröffentlichen",
"This function is disabled on this proxy": "Diese Funktion ist auf dieser Proxy deaktiviert",
"GeoLite2 City database download error: {}!<br>Please download manually and unpack to data dir:<br>{}": "GeoLite2 City Datenbank Download Fehler: {}!<br>Bitte manuell herunterladen und die Datei in das Datei Verzeichnis extrahieren:<br>{}",
"Downloading GeoLite2 City database (one time only, ~20MB)...": "Herunterladen der GeoLite2 City Datenbank (einmalig, ~20MB)...",
"GeoLite2 City database downloaded!": "GeoLite2 City Datenbank heruntergeladen!",
"Are you sure?": "Bist du sicher?",
"Site storage limit modified!": "Speicher Limit der Seite modifiziert!",
"Database schema reloaded!": "Datebank Schema neu geladen!",
"Database rebuilding....": "Datenbank neu bauen...",
"Database rebuilt!": "Datenbank neu gebaut!",
"Site updated!": "Seite aktualisiert!",
"Delete this site": "Diese Seite löschen",
"File write error: ": "Datei schreib fehler:",
"Site settings saved!": "Seiten Einstellungen gespeichert!",
"Enter your private key:": "Gib deinen privaten Schlüssel ein:",
" Signed!": " Signiert!",
"WebGL not supported": "WebGL nicht unterstützt"
}

View file

@ -1,79 +0,0 @@
{
"Peers": "Pares",
"Connected": "Conectados",
"Connectable": "Conectables",
"Connectable peers": "Pares conectables",
"Data transfer": "Transferencia de datos",
"Received": "Recibidos",
"Received bytes": "Bytes recibidos",
"Sent": "Enviados",
"Sent bytes": "Bytes envidados",
"Files": "Ficheros",
"Total": "Total",
"Image": "Imagen",
"Other": "Otro",
"User data": "Datos del usuario",
"Size limit": "Límite de tamaño",
"limit used": "Límite utilizado",
"free space": "Espacio libre",
"Set": "Establecer",
"Optional files": "Ficheros opcionales",
"Downloaded": "Descargado",
"Download and help distribute all files": "Descargar y ayudar a distribuir todos los ficheros",
"Total size": "Tamaño total",
"Downloaded files": "Ficheros descargados",
"Database": "Base de datos",
"search feeds": "Fuentes de búsqueda",
"{feeds} query": "{feeds} consulta",
"Reload": "Recargar",
"Rebuild": "Reconstruir",
"No database found": "No se ha encontrado la base de datos",
"Identity address": "Dirección de la identidad",
"Change": "Cambiar",
"Update": "Actualizar",
"Pause": "Pausar",
"Resume": "Reanudar",
"Delete": "Borrar",
"Site address": "Dirección del sitio",
"Donate": "Donar",
"Missing files": "Ficheros perdidos",
"{} try": "{} intento",
"{} tries": "{} intentos",
"+ {num_bad_files} more": "+ {num_bad_files} más",
"This is my site": "Este es mi sitio",
"Site title": "Título del sitio",
"Site description": "Descripción del sitio",
"Save site settings": "Guardar la configuración del sitio",
"Content publishing": "Publicación del contenido",
"Choose": "Elegir",
"Sign": "Firmar",
"Publish": "Publicar",
"This function is disabled on this proxy": "Esta función está deshabilitada en este proxy",
"GeoLite2 City database download error: {}!<br>Please download manually and unpack to data dir:<br>{}": "¡Error de la base de datos GeoLite2 {}!<br>Por favor, descárgalo manualmente y descomprime al directorio de datos<br>{}",
"Downloading GeoLite2 City database (one time only, ~20MB)...": "Descargando la base de datos de GeoLite2 (una única vez, ~20MB...",
"GeoLite2 City database downloaded!": "¡Base de datos de GeoLite2 descargada!",
"Are you sure?": "¿Estás seguro?",
"Site storage limit modified!": "¡Límite de almacenamiento del sitio modificado!",
"Database schema reloaded!": "¡Esquema de la base de datos recargado!",
"Database rebuilding....": "Reconstruyendo la base de datos...",
"Database rebuilt!": "¡Base de datos reconstruida!",
"Site updated!": "¡Sitio actualizado!",
"Delete this site": "Borrar este sitio",
"File write error: ": "Error de escritura de fichero",
"Site settings saved!": "¡Configuración del sitio guardada!",
"Enter your private key:": "Introduce tu clave privada",
" Signed!": " ¡firmado!",
"WebGL not supported": "WebGL no está soportado"
}

View file

@ -1,82 +0,0 @@
{
"Peers": "Pairs",
"Connected": "Connectés",
"Connectable": "Accessibles",
"Connectable peers": "Pairs accessibles",
"Data transfer": "Données transférées",
"Received": "Reçues",
"Received bytes": "Bytes reçus",
"Sent": "Envoyées",
"Sent bytes": "Bytes envoyés",
"Files": "Fichiers",
"Total": "Total",
"Image": "Image",
"Other": "Autre",
"User data": "Utilisateurs",
"Size limit": "Taille maximale",
"limit used": "utlisé",
"free space": "libre",
"Set": "Modifier",
"Optional files": "Fichiers optionnels",
"Downloaded": "Téléchargé",
"Download and help distribute all files": "Télécharger et distribuer tous les fichiers",
"Total size": "Taille totale",
"Downloaded files": "Fichiers téléchargés",
"Database": "Base de données",
"search feeds": "recherche",
"{feeds} query": "{feeds} requête",
"Reload": "Recharger",
"Rebuild": "Reconstruire",
"No database found": "Aucune base de données trouvée",
"Identity address": "Adresse d'identité",
"Change": "Modifier",
"Site control": "Opérations",
"Update": "Mettre à jour",
"Pause": "Suspendre",
"Resume": "Reprendre",
"Delete": "Supprimer",
"Are you sure?": "Êtes-vous certain?",
"Site address": "Adresse du site",
"Donate": "Faire un don",
"Missing files": "Fichiers manquants",
"{} try": "{} essai",
"{} tries": "{} essais",
"+ {num_bad_files} more": "+ {num_bad_files} manquants",
"This is my site": "Ce site m'appartient",
"Site title": "Nom du site",
"Site description": "Description du site",
"Save site settings": "Enregistrer les paramètres",
"Content publishing": "Publication du contenu",
"Choose": "Sélectionner",
"Sign": "Signer",
"Publish": "Publier",
"This function is disabled on this proxy": "Cette fonction est désactivé sur ce proxy",
"GeoLite2 City database download error: {}!<br>Please download manually and unpack to data dir:<br>{}": "Erreur au téléchargement de la base de données GeoLite2: {}!<br>Téléchargez et décompressez dans le dossier data:<br>{}",
"Downloading GeoLite2 City database (one time only, ~20MB)...": "Téléchargement de la base de données GeoLite2 (une seule fois, ~20MB)...",
"GeoLite2 City database downloaded!": "Base de données GeoLite2 téléchargée!",
"Are you sure?": "Êtes-vous certain?",
"Site storage limit modified!": "Taille maximale modifiée!",
"Database schema reloaded!": "Base de données rechargée!",
"Database rebuilding....": "Reconstruction de la base de données...",
"Database rebuilt!": "Base de données reconstruite!",
"Site updated!": "Site mis à jour!",
"Delete this site": "Supprimer ce site",
"File write error: ": "Erreur à l'écriture du fichier: ",
"Site settings saved!": "Paramètres du site enregistrés!",
"Enter your private key:": "Entrez votre clé privée:",
" Signed!": " Signé!",
"WebGL not supported": "WebGL n'est pas supporté"
}

View file

@ -1,82 +0,0 @@
{
"Peers": "Csatlakozási pontok",
"Connected": "Csaltakozva",
"Connectable": "Csatlakozható",
"Connectable peers": "Csatlakozható peer-ek",
"Data transfer": "Adatátvitel",
"Received": "Fogadott",
"Received bytes": "Fogadott byte-ok",
"Sent": "Küldött",
"Sent bytes": "Küldött byte-ok",
"Files": "Fájlok",
"Total": "Összesen",
"Image": "Kép",
"Other": "Egyéb",
"User data": "Felh. adat",
"Size limit": "Méret korlát",
"limit used": "felhasznált",
"free space": "szabad hely",
"Set": "Beállít",
"Optional files": "Opcionális fájlok",
"Downloaded": "Letöltött",
"Download and help distribute all files": "Minden opcionális fájl letöltése",
"Total size": "Teljes méret",
"Downloaded files": "Letöltve",
"Database": "Adatbázis",
"search feeds": "Keresés források",
"{feeds} query": "{feeds} lekérdezés",
"Reload": "Újratöltés",
"Rebuild": "Újraépítés",
"No database found": "Adatbázis nem található",
"Identity address": "Azonosító cím",
"Change": "Módosít",
"Site control": "Oldal műveletek",
"Update": "Frissít",
"Pause": "Szünteltet",
"Resume": "Folytat",
"Delete": "Töröl",
"Are you sure?": "Biztos vagy benne?",
"Site address": "Oldal címe",
"Donate": "Támogatás",
"Missing files": "Hiányzó fájlok",
"{} try": "{} próbálkozás",
"{} tries": "{} próbálkozás",
"+ {num_bad_files} more": "+ még {num_bad_files} darab",
"This is my site": "Ez az én oldalam",
"Site title": "Oldal neve",
"Site description": "Oldal leírása",
"Save site settings": "Oldal beállítások mentése",
"Content publishing": "Tartalom publikálás",
"Choose": "Válassz",
"Sign": "Aláírás",
"Publish": "Publikálás",
"This function is disabled on this proxy": "Ez a funkció ki van kapcsolva ezen a proxy-n",
"GeoLite2 City database download error: {}!<br>Please download manually and unpack to data dir:<br>{}": "GeoLite2 város adatbázis letöltési hiba: {}!<br>A térképhez töltsd le és csomagold ki a data könyvtárba:<br>{}",
"Downloading GeoLite2 City database (one time only, ~20MB)...": "GeoLite2 város adatbázis letöltése (csak egyszer kell, kb 20MB)...",
"GeoLite2 City database downloaded!": "GeoLite2 város adatbázis letöltve!",
"Are you sure?": "Biztos vagy benne?",
"Site storage limit modified!": "Az oldalt méret korlát módosítva!",
"Database schema reloaded!": "Adatbázis séma újratöltve!",
"Database rebuilding....": "Adatbázis újraépítés...",
"Database rebuilt!": "Adatbázis újraépítve!",
"Site updated!": "Az oldal frissítve!",
"Delete this site": "Az oldal törlése",
"File write error: ": "Fájl írási hiba: ",
"Site settings saved!": "Az oldal beállításai elmentve!",
"Enter your private key:": "Add meg a prviát kulcsod:",
" Signed!": " Aláírva!",
"WebGL not supported": "WebGL nem támogatott"
}

View file

@ -1,81 +0,0 @@
{
"Peers": "Peer",
"Connected": "Connessi",
"Connectable": "Collegabili",
"Connectable peers": "Peer collegabili",
"Data transfer": "Trasferimento dati",
"Received": "Ricevuti",
"Received bytes": "Byte ricevuti",
"Sent": "Inviati",
"Sent bytes": "Byte inviati",
"Files": "File",
"Total": "Totale",
"Image": "Imagine",
"Other": "Altro",
"User data": "Dati utente",
"Size limit": "Limite dimensione",
"limit used": "limite usato",
"free space": "spazio libero",
"Set": "Imposta",
"Optional files": "File facoltativi",
"Downloaded": "Scaricati",
"Download and help distribute all files": "Scarica e aiuta a distribuire tutti i file",
"Total size": "Dimensione totale",
"Downloaded files": "File scaricati",
"Database": "Database",
"search feeds": "ricerca di feed",
"{feeds} query": "{feeds} interrogazione",
"Reload": "Ricaricare",
"Rebuild": "Ricostruire",
"No database found": "Nessun database trovato",
"Identity address": "Indirizzo di identità",
"Change": "Cambia",
"Update": "Aggiorna",
"Pause": "Sospendi",
"Resume": "Riprendi",
"Delete": "Cancella",
"Are you sure?": "Sei sicuro?",
"Site address": "Indirizzo sito",
"Donate": "Dona",
"Missing files": "File mancanti",
"{} try": "{} tenta",
"{} tries": "{} prova",
"+ {num_bad_files} more": "+ {num_bad_files} altri",
"This is my site": "Questo è il mio sito",
"Site title": "Titolo sito",
"Site description": "Descrizione sito",
"Save site settings": "Salva impostazioni sito",
"Content publishing": "Pubblicazione contenuto",
"Choose": "Scegli",
"Sign": "Firma",
"Publish": "Pubblica",
"This function is disabled on this proxy": "Questa funzione è disabilitata su questo proxy",
"GeoLite2 City database download error: {}!<br>Please download manually and unpack to data dir:<br>{}": "Errore scaricamento database GeoLite2 City: {}!<br>Si prega di scaricarlo manualmente e spacchetarlo nella cartella dir:<br>{}",
"Downloading GeoLite2 City database (one time only, ~20MB)...": "Scaricamento database GeoLite2 City (solo una volta, ~20MB)...",
"GeoLite2 City database downloaded!": "Database GeoLite2 City scaricato!",
"Are you sure?": "Sei sicuro?",
"Site storage limit modified!": "Limite di archiviazione del sito modificato!",
"Database schema reloaded!": "Schema database ricaricato!",
"Database rebuilding....": "Ricostruzione database...",
"Database rebuilt!": "Database ricostruito!",
"Site updated!": "Sito aggiornato!",
"Delete this site": "Cancella questo sito",
"File write error: ": "Errore scrittura file:",
"Site settings saved!": "Impostazioni sito salvate!",
"Enter your private key:": "Inserisci la tua chiave privata:",
" Signed!": " Firmato!",
"WebGL not supported": "WebGL non supportato"
}

View file

@ -1,82 +0,0 @@
{
"Peers": "Użytkownicy równorzędni",
"Connected": "Połączony",
"Connectable": "Możliwy do podłączenia",
"Connectable peers": "Połączeni użytkownicy równorzędni",
"Data transfer": "Transfer danych",
"Received": "Odebrane",
"Received bytes": "Odebrany bajty",
"Sent": "Wysłane",
"Sent bytes": "Wysłane bajty",
"Files": "Pliki",
"Total": "Sumarycznie",
"Image": "Obraz",
"Other": "Inne",
"User data": "Dane użytkownika",
"Size limit": "Rozmiar limitu",
"limit used": "zużyty limit",
"free space": "wolna przestrzeń",
"Set": "Ustaw",
"Optional files": "Pliki opcjonalne",
"Downloaded": "Ściągnięte",
"Download and help distribute all files": "Ściągnij i pomóż rozpowszechniać wszystkie pliki",
"Total size": "Rozmiar sumaryczny",
"Downloaded files": "Ściągnięte pliki",
"Database": "Baza danych",
"search feeds": "przeszukaj zasoby",
"{feeds} query": "{feeds} pytanie",
"Reload": "Odśwież",
"Rebuild": "Odbuduj",
"No database found": "Nie odnaleziono bazy danych",
"Identity address": "Adres identyfikacyjny",
"Change": "Zmień",
"Site control": "Kontrola strony",
"Update": "Zaktualizuj",
"Pause": "Wstrzymaj",
"Resume": "Wznów",
"Delete": "Skasuj",
"Are you sure?": "Jesteś pewien?",
"Site address": "Adres strony",
"Donate": "Wspomóż",
"Missing files": "Brakujące pliki",
"{} try": "{} próba",
"{} tries": "{} próby",
"+ {num_bad_files} more": "+ {num_bad_files} więcej",
"This is my site": "To moja strona",
"Site title": "Tytuł strony",
"Site description": "Opis strony",
"Save site settings": "Zapisz ustawienia strony",
"Content publishing": "Publikowanie treści",
"Choose": "Wybierz",
"Sign": "Podpisz",
"Publish": "Opublikuj",
"This function is disabled on this proxy": "Ta funkcja jest zablokowana w tym proxy",
"GeoLite2 City database download error: {}!<br>Please download manually and unpack to data dir:<br>{}": "Błąd ściągania bazy danych GeoLite2 City: {}!<br>Proszę ściągnąć ją recznie i wypakować do katalogu danych:<br>{}",
"Downloading GeoLite2 City database (one time only, ~20MB)...": "Ściąganie bazy danych GeoLite2 City (tylko jednorazowo, ok. 20MB)...",
"GeoLite2 City database downloaded!": "Baza danych GeoLite2 City ściagnięta!",
"Are you sure?": "Jesteś pewien?",
"Site storage limit modified!": "Limit pamięci strony zmodyfikowany!",
"Database schema reloaded!": "Schemat bazy danych załadowany ponownie!",
"Database rebuilding....": "Przebudowywanie bazy danych...",
"Database rebuilt!": "Baza danych przebudowana!",
"Site updated!": "Strona zaktualizowana!",
"Delete this site": "Usuń tę stronę",
"File write error: ": "Błąd zapisu pliku: ",
"Site settings saved!": "Ustawienia strony zapisane!",
"Enter your private key:": "Wpisz swój prywatny klucz:",
" Signed!": " Podpisane!",
"WebGL not supported": "WebGL nie jest obsługiwany"
}

View file

@ -1,81 +0,0 @@
{
"Peers": "Peers",
"Connected": "Ligados",
"Connectable": "Disponíveis",
"Connectable peers": "Peers disponíveis",
"Data transfer": "Transferência de dados",
"Received": "Recebidos",
"Received bytes": "Bytes recebidos",
"Sent": "Enviados",
"Sent bytes": "Dados enviados",
"Files": "Arquivos",
"Total": "Total",
"Image": "Imagem",
"Other": "Outros",
"User data": "Dados do usuário",
"Size limit": "Limite de tamanho",
"limit used": "limite utilizado",
"free space": "espaço livre",
"Set": "Definir",
"Optional files": "Arquivos opcionais",
"Downloaded": "Baixados",
"Download and help distribute all files": "Baixar e ajudar a distribuir todos os arquivos",
"Total size": "Tamanho total",
"Downloaded files": "Arquivos baixados",
"Database": "Base de dados",
"search feeds": "pesquisar feeds",
"{feeds} query": "consulta de {feeds}",
"Reload": "Recarregar",
"Rebuild": "Reconstruir",
"No database found": "Base de dados não encontrada",
"Identity address": "Endereço de identidade",
"Change": "Alterar",
"Update": "Atualizar",
"Pause": "Suspender",
"Resume": "Continuar",
"Delete": "Remover",
"Are you sure?": "Tem certeza?",
"Site address": "Endereço do site",
"Donate": "Doar",
"Missing files": "Arquivos em falta",
"{} try": "{} tentativa",
"{} tries": "{} tentativas",
"+ {num_bad_files} more": "+ {num_bad_files} adicionais",
"This is my site": "Este é o meu site",
"Site title": "Título do site",
"Site description": "Descrição do site",
"Save site settings": "Salvar definições do site",
"Content publishing": "Publicação do conteúdo",
"Choose": "Escolher",
"Sign": "Assinar",
"Publish": "Publicar",
"This function is disabled on this proxy": "Esta função encontra-se desativada neste proxy",
"GeoLite2 City database download error: {}!<br>Please download manually and unpack to data dir:<br>{}": "Erro ao baixar a base de dados GeoLite2 City: {}!<br>Por favor baixe manualmente e descompacte os dados para a seguinte pasta:<br>{}",
"Downloading GeoLite2 City database (one time only, ~20MB)...": "Baixando a base de dados GeoLite2 City (uma única vez, ~20MB)...",
"GeoLite2 City database downloaded!": "A base de dados GeoLite2 City foi baixada!",
"Are you sure?": "Tem certeza?",
"Site storage limit modified!": "O limite de armazenamento do site foi modificado!",
"Database schema reloaded!": "O esquema da base de dados foi atualizado!",
"Database rebuilding....": "Reconstruindo base de dados...",
"Database rebuilt!": "Base de dados reconstruída!",
"Site updated!": "Site atualizado!",
"Delete this site": "Remover este site",
"File write error: ": "Erro de escrita de arquivo: ",
"Site settings saved!": "Definições do site salvas!",
"Enter your private key:": "Digite sua chave privada:",
" Signed!": " Assinado!",
"WebGL not supported": "WebGL não é suportado"
}

View file

@ -1,82 +0,0 @@
{
"Peers": "Пиры",
"Connected": "Подключенные",
"Connectable": "Доступные",
"Connectable peers": "Пиры доступны для подключения",
"Data transfer": "Передача данных",
"Received": "Получено",
"Received bytes": "Получено байн",
"Sent": "Отправлено",
"Sent bytes": "Отправлено байт",
"Files": "Файлы",
"Total": "Всего",
"Image": "Изображений",
"Other": "Другое",
"User data": "Ваш контент",
"Size limit": "Ограничение по размеру",
"limit used": "Использовано",
"free space": "Доступно",
"Set": "Установить",
"Optional files": "Опциональные файлы",
"Downloaded": "Загружено",
"Download and help distribute all files": "Загрузить опциональные файлы для помощи сайту",
"Total size": "Объём",
"Downloaded files": "Загруженные файлы",
"Database": "База данных",
"search feeds": "поиск подписок",
"{feeds} query": "{feeds} запрос",
"Reload": "Перезагрузить",
"Rebuild": "Перестроить",
"No database found": "База данных не найдена",
"Identity address": "Уникальный адрес",
"Change": "Изменить",
"Site control": "Управление сайтом",
"Update": "Обновить",
"Pause": "Пауза",
"Resume": "Продолжить",
"Delete": "Удалить",
"Are you sure?": "Вы уверены?",
"Site address": "Адрес сайта",
"Donate": "Пожертвовать",
"Missing files": "Отсутствующие файлы",
"{} try": "{} попробовать",
"{} tries": "{} попыток",
"+ {num_bad_files} more": "+ {num_bad_files} ещё",
"This is my site": "Это мой сайт",
"Site title": "Название сайта",
"Site description": "Описание сайта",
"Save site settings": "Сохранить настройки сайта",
"Content publishing": "Публикация контента",
"Choose": "Выбрать",
"Sign": "Подписать",
"Publish": "Опубликовать",
"This function is disabled on this proxy": "Эта функция отключена на этом прокси",
"GeoLite2 City database download error: {}!<br>Please download manually and unpack to data dir:<br>{}": "Ошибка загрузки базы городов GeoLite2: {}!<br>Пожалуйста, загрузите её вручную и распакуйте в папку:<br>{}",
"Downloading GeoLite2 City database (one time only, ~20MB)...": "Загрузка базы городов GeoLite2 (это делается только 1 раз, ~20MB)...",
"GeoLite2 City database downloaded!": "База GeoLite2 успешно загружена!",
"Are you sure?": "Вы уверены?",
"Site storage limit modified!": "Лимит хранилища для сайта изменен!",
"Database schema reloaded!": "Схема базы данных перезагружена!",
"Database rebuilding....": "Перестройка базы данных...",
"Database rebuilt!": "База данных перестроена!",
"Site updated!": "Сайт обновлён!",
"Delete this site": "Удалить этот сайт",
"File write error: ": "Ошибка записи файла:",
"Site settings saved!": "Настройки сайта сохранены!",
"Enter your private key:": "Введите свой приватный ключ:",
" Signed!": " Подписано!",
"WebGL not supported": "WebGL не поддерживается"
}

View file

@ -1,82 +0,0 @@
{
"Peers": "Eşler",
"Connected": "Bağlı",
"Connectable": "Erişilebilir",
"Connectable peers": "Bağlanılabilir eşler",
"Data transfer": "Veri aktarımı",
"Received": "Alınan",
"Received bytes": "Bayt alındı",
"Sent": "Gönderilen",
"Sent bytes": "Bayt gönderildi",
"Files": "Dosyalar",
"Total": "Toplam",
"Image": "Resim",
"Other": "Diğer",
"User data": "Kullanıcı verisi",
"Size limit": "Boyut sınırı",
"limit used": "kullanılan",
"free space": "boş",
"Set": "Ayarla",
"Optional files": "İsteğe bağlı dosyalar",
"Downloaded": "İndirilen",
"Download and help distribute all files": "Tüm dosyaları indir ve yayılmalarına yardım et",
"Total size": "Toplam boyut",
"Downloaded files": "İndirilen dosyalar",
"Database": "Veritabanı",
"search feeds": "kaynak ara",
"{feeds} query": "{feeds} sorgu",
"Reload": "Yenile",
"Rebuild": "Yapılandır",
"No database found": "Veritabanı yok",
"Identity address": "Kimlik adresi",
"Change": "Değiştir",
"Site control": "Site kontrolü",
"Update": "Güncelle",
"Pause": "Duraklat",
"Resume": "Sürdür",
"Delete": "Sil",
"Are you sure?": "Emin misin?",
"Site address": "Site adresi",
"Donate": "Bağış yap",
"Missing files": "Eksik dosyalar",
"{} try": "{} deneme",
"{} tries": "{} deneme",
"+ {num_bad_files} more": "+ {num_bad_files} tane daha",
"This is my site": "Bu benim sitem",
"Site title": "Site başlığı",
"Site description": "Site açıklaması",
"Save site settings": "Site ayarlarını kaydet",
"Content publishing": "İçerik yayımlanıyor",
"Choose": "Seç",
"Sign": "İmzala",
"Publish": "Yayımla",
"This function is disabled on this proxy": "Bu özellik bu vekilde kullanılamaz",
"GeoLite2 City database download error: {}!<br>Please download manually and unpack to data dir:<br>{}": "GeoLite2 Şehir veritabanı indirme hatası: {}!<br>Lütfen kendiniz indirip aşağıdaki konuma açınınız:<br>{}",
"Downloading GeoLite2 City database (one time only, ~20MB)...": "GeoLite2 Şehir veritabanı indiriliyor (sadece bir kere, ~20MB)...",
"GeoLite2 City database downloaded!": "GeoLite2 Şehir veritabanı indirildi!",
"Are you sure?": "Emin misiniz?",
"Site storage limit modified!": "Site saklama sınırı değiştirildi!",
"Database schema reloaded!": "Veritabanı şeması yeniden yüklendi!",
"Database rebuilding....": "Veritabanı yeniden inşa ediliyor...",
"Database rebuilt!": "Veritabanı yeniden inşa edildi!",
"Site updated!": "Site güncellendi!",
"Delete this site": "Bu siteyi sil",
"File write error: ": "Dosya yazma hatası: ",
"Site settings saved!": "Site ayarları kaydedildi!",
"Enter your private key:": "Özel anahtarınızı giriniz:",
" Signed!": " İmzala!",
"WebGL not supported": "WebGL desteklenmiyor"
}

View file

@ -1,81 +0,0 @@
{
"Peers": "節點數",
"Connected": "已連線",
"Connectable": "可連線",
"Connectable peers": "可連線節點",
"Data transfer": "數據傳輸",
"Received": "已收到",
"Received bytes": "收到字節",
"Sent": "已傳送",
"Sent bytes": "傳送字節",
"Files": "檔",
"Total": "共計",
"Image": "圖片",
"Other": "其他",
"User data": "用戶數據",
"Size limit": "大小限制",
"limit used": "限额",
"free space": "可用空間",
"Set": "設定",
"Optional files": "可選文件",
"Downloaded": "已下載",
"Download and help distribute all files": "下載並幫助分發所有文件",
"Total size": "總大小",
"Downloaded files": "下載的文件",
"Database": "資料庫",
"search feeds": "搜尋供稿",
"{feeds} query": "{feeds} 查詢 ",
"Reload": "重載",
"Rebuild": "重建",
"No database found": "未找到資料庫",
"Identity address": "身份地址",
"Change": "改變",
"Site control": "網站控制",
"Update": "更新",
"Pause": "暫停",
"Resume": "恢復",
"Delete": "刪除",
"Are you sure?": "你確定?",
"Site address": "網站地址",
"Donate": "捐贈",
"Missing files": "缺少的檔",
"{} try": "{} 嘗試",
"{} tries": "{} 已嘗試",
"+ {num_bad_files} more": "+ {num_bad_files} 更多",
"This is my site": "這是我的網站",
"Site title": "網站標題",
"Site description": "網站描寫",
"Save site settings": "存儲網站設定",
"Content publishing": "內容髮布",
"Choose": "選擇",
"Sign": "簽署",
"Publish": "發佈",
"This function is disabled on this proxy": "此代理上禁用此功能",
"GeoLite2 City database download error: {}!<br>Please download manually and unpack to data dir:<br>{}": "GeoLite2 地理位置資料庫下載錯誤:{}!<br>請手動下載並解壓到數據目錄:<br>{}",
"Downloading GeoLite2 City database (one time only, ~20MB)...": "正在下載 GeoLite2 地理位置資料庫 (僅一次,約 20MB ...",
"GeoLite2 City database downloaded!": "GeoLite2 地理位置資料庫已下載!",
"Are you sure?": "你確定?",
"Site storage limit modified!": "網站存儲限制已改變!",
"Database schema reloaded!": "資料庫架構重新加載!",
"Database rebuilding....": "資料庫重建中...",
"Database rebuilt!": "資料庫已重建!",
"Site updated!": "網站已更新!",
"Delete this site": "刪除此網站",
"File write error: ": "檔寫入錯誤:",
"Site settings saved!": "網站設置已保存!",
"Enter your private key:": "輸入您的私鑰:",
" Signed!": " 已簽署!",
"WebGL not supported": "不支持 WebGL"
}

View file

@ -1,81 +0,0 @@
{
"Peers": "节点数",
"Connected": "已连接",
"Connectable": "可连接",
"Connectable peers": "可连接节点",
"Data transfer": "数据传输",
"Received": "已接收",
"Received bytes": "已接收字节",
"Sent": "已发送",
"Sent bytes": "已发送字节",
"Files": "文件",
"Total": "总计",
"Image": "图像",
"Other": "其他",
"User data": "用户数据",
"Size limit": "大小限制",
"limit used": "限额",
"free space": "剩余空间",
"Set": "设置",
"Optional files": "可选文件",
"Downloaded": "已下载",
"Download and help distribute all files": "下载并帮助分发所有文件",
"Total size": "总大小",
"Downloaded files": "已下载文件",
"Database": "数据库",
"search feeds": "搜索数据源",
"{feeds} query": "{feeds} 请求",
"Reload": "重载",
"Rebuild": "重建",
"No database found": "没有找到数据库",
"Identity address": "身份地址",
"Change": "更改",
"Site control": "站点控制",
"Update": "更新",
"Pause": "暂停",
"Resume": "恢复",
"Delete": "删除",
"Are you sure?": "你确定吗?",
"Site address": "站点地址",
"Donate": "捐赠",
"Missing files": "丢失的文件",
"{} try": "{} 尝试",
"{} tries": "{} 已尝试",
"+ {num_bad_files} more": "+ {num_bad_files} 更多",
"This is my site": "这是我的站点",
"Site title": "站点标题",
"Site description": "站点描述",
"Save site settings": "保存站点设置",
"Content publishing": "内容发布",
"Choose": "选择",
"Sign": "签名",
"Publish": "发布",
"This function is disabled on this proxy": "此功能在代理上被禁用",
"GeoLite2 City database download error: {}!<br>Please download manually and unpack to data dir:<br>{}": "GeoLite2 地理位置数据库下载错误:{}!<br>请手动下载并解压在数据目录:<br>{}",
"Downloading GeoLite2 City database (one time only, ~20MB)...": "正在下载 GeoLite2 地理位置数据库 (仅需一次,约 20MB ...",
"GeoLite2 City database downloaded!": "GeoLite2 地理位置数据库已下载!",
"Are you sure?": "你确定吗?",
"Site storage limit modified!": "站点存储限制已更改!",
"Database schema reloaded!": "数据库模式已重新加载!",
"Database rebuilding....": "数据库重建中...",
"Database rebuilt!": "数据库已重建!",
"Site updated!": "站点已更新!",
"Delete this site": "删除这个站点",
"File write error: ": "文件写入错误:",
"Site settings saved!": "站点设置已保存!",
"Enter your private key:": "输入你的私钥:",
" Signed!": " 已签名!",
"WebGL not supported": "不支持 WebGL"
}

View file

@ -1,46 +0,0 @@
# pylint:disable=C0111
import os
import maxminddb.reader
try:
import maxminddb.extension
except ImportError:
maxminddb.extension = None
from maxminddb.const import (MODE_AUTO, MODE_MMAP, MODE_MMAP_EXT, MODE_FILE,
MODE_MEMORY)
from maxminddb.decoder import InvalidDatabaseError
def open_database(database, mode=MODE_AUTO):
"""Open a Maxmind DB database
Arguments:
database -- A path to a valid MaxMind DB file such as a GeoIP2
database file.
mode -- mode to open the database with. Valid mode are:
* MODE_MMAP_EXT - use the C extension with memory map.
* MODE_MMAP - read from memory map. Pure Python.
* MODE_FILE - read database as standard file. Pure Python.
* MODE_MEMORY - load database into memory. Pure Python.
* MODE_AUTO - tries MODE_MMAP_EXT, MODE_MMAP, MODE_FILE in that
order. Default mode.
"""
if (mode == MODE_AUTO and maxminddb.extension and
hasattr(maxminddb.extension, 'Reader')) or mode == MODE_MMAP_EXT:
return maxminddb.extension.Reader(database)
elif mode in (MODE_AUTO, MODE_MMAP, MODE_FILE, MODE_MEMORY):
return maxminddb.reader.Reader(database, mode)
raise ValueError('Unsupported open mode: {0}'.format(mode))
def Reader(database): # pylint: disable=invalid-name
"""This exists for backwards compatibility. Use open_database instead"""
return open_database(database)
__title__ = 'maxminddb'
__version__ = '1.2.0'
__author__ = 'Gregory Oschwald'
__license__ = 'Apache License, Version 2.0'
__copyright__ = 'Copyright 2014 Maxmind, Inc.'

View file

@ -1,28 +0,0 @@
import sys
# pylint: skip-file
if sys.version_info[0] == 2:
import ipaddr as ipaddress # pylint:disable=F0401
ipaddress.ip_address = ipaddress.IPAddress
int_from_byte = ord
FileNotFoundError = IOError
def int_from_bytes(b):
if b:
return int(b.encode("hex"), 16)
return 0
byte_from_int = chr
else:
import ipaddress # pylint:disable=F0401
int_from_byte = lambda x: x
FileNotFoundError = FileNotFoundError
int_from_bytes = lambda x: int.from_bytes(x, 'big')
byte_from_int = lambda x: bytes([x])

View file

@ -1,7 +0,0 @@
"""Constants used in the API"""
MODE_AUTO = 0
MODE_MMAP_EXT = 1
MODE_MMAP = 2
MODE_FILE = 4
MODE_MEMORY = 8

View file

@ -1,173 +0,0 @@
"""
maxminddb.decoder
~~~~~~~~~~~~~~~~~
This package contains code for decoding the MaxMind DB data section.
"""
from __future__ import unicode_literals
import struct
from maxminddb.compat import byte_from_int, int_from_bytes
from maxminddb.errors import InvalidDatabaseError
class Decoder(object): # pylint: disable=too-few-public-methods
"""Decoder for the data section of the MaxMind DB"""
def __init__(self, database_buffer, pointer_base=0, pointer_test=False):
"""Created a Decoder for a MaxMind DB
Arguments:
database_buffer -- an mmap'd MaxMind DB file.
pointer_base -- the base number to use when decoding a pointer
pointer_test -- used for internal unit testing of pointer code
"""
self._pointer_test = pointer_test
self._buffer = database_buffer
self._pointer_base = pointer_base
def _decode_array(self, size, offset):
array = []
for _ in range(size):
(value, offset) = self.decode(offset)
array.append(value)
return array, offset
def _decode_boolean(self, size, offset):
return size != 0, offset
def _decode_bytes(self, size, offset):
new_offset = offset + size
return self._buffer[offset:new_offset], new_offset
# pylint: disable=no-self-argument
# |-> I am open to better ways of doing this as long as it doesn't involve
# lots of code duplication.
def _decode_packed_type(type_code, type_size, pad=False):
# pylint: disable=protected-access, missing-docstring
def unpack_type(self, size, offset):
if not pad:
self._verify_size(size, type_size)
new_offset = offset + type_size
packed_bytes = self._buffer[offset:new_offset]
if pad:
packed_bytes = packed_bytes.rjust(type_size, b'\x00')
(value,) = struct.unpack(type_code, packed_bytes)
return value, new_offset
return unpack_type
def _decode_map(self, size, offset):
container = {}
for _ in range(size):
(key, offset) = self.decode(offset)
(value, offset) = self.decode(offset)
container[key] = value
return container, offset
_pointer_value_offset = {
1: 0,
2: 2048,
3: 526336,
4: 0,
}
def _decode_pointer(self, size, offset):
pointer_size = ((size >> 3) & 0x3) + 1
new_offset = offset + pointer_size
pointer_bytes = self._buffer[offset:new_offset]
packed = pointer_bytes if pointer_size == 4 else struct.pack(
b'!c', byte_from_int(size & 0x7)) + pointer_bytes
unpacked = int_from_bytes(packed)
pointer = unpacked + self._pointer_base + \
self._pointer_value_offset[pointer_size]
if self._pointer_test:
return pointer, new_offset
(value, _) = self.decode(pointer)
return value, new_offset
def _decode_uint(self, size, offset):
new_offset = offset + size
uint_bytes = self._buffer[offset:new_offset]
return int_from_bytes(uint_bytes), new_offset
def _decode_utf8_string(self, size, offset):
new_offset = offset + size
return self._buffer[offset:new_offset].decode('utf-8'), new_offset
_type_decoder = {
1: _decode_pointer,
2: _decode_utf8_string,
3: _decode_packed_type(b'!d', 8), # double,
4: _decode_bytes,
5: _decode_uint, # uint16
6: _decode_uint, # uint32
7: _decode_map,
8: _decode_packed_type(b'!i', 4, pad=True), # int32
9: _decode_uint, # uint64
10: _decode_uint, # uint128
11: _decode_array,
14: _decode_boolean,
15: _decode_packed_type(b'!f', 4), # float,
}
def decode(self, offset):
"""Decode a section of the data section starting at offset
Arguments:
offset -- the location of the data structure to decode
"""
new_offset = offset + 1
(ctrl_byte,) = struct.unpack(b'!B', self._buffer[offset:new_offset])
type_num = ctrl_byte >> 5
# Extended type
if not type_num:
(type_num, new_offset) = self._read_extended(new_offset)
if not type_num in self._type_decoder:
raise InvalidDatabaseError('Unexpected type number ({type}) '
'encountered'.format(type=type_num))
(size, new_offset) = self._size_from_ctrl_byte(
ctrl_byte, new_offset, type_num)
return self._type_decoder[type_num](self, size, new_offset)
def _read_extended(self, offset):
(next_byte,) = struct.unpack(b'!B', self._buffer[offset:offset + 1])
type_num = next_byte + 7
if type_num < 7:
raise InvalidDatabaseError(
'Something went horribly wrong in the decoder. An '
'extended type resolved to a type number < 8 '
'({type})'.format(type=type_num))
return type_num, offset + 1
def _verify_size(self, expected, actual):
if expected != actual:
raise InvalidDatabaseError(
'The MaxMind DB file\'s data section contains bad data '
'(unknown data type or corrupt data)'
)
def _size_from_ctrl_byte(self, ctrl_byte, offset, type_num):
size = ctrl_byte & 0x1f
if type_num == 1:
return size, offset
bytes_to_read = 0 if size < 29 else size - 28
new_offset = offset + bytes_to_read
size_bytes = self._buffer[offset:new_offset]
# Using unpack rather than int_from_bytes as it is about 200 lookups
# per second faster here.
if size == 29:
size = 29 + struct.unpack(b'!B', size_bytes)[0]
elif size == 30:
size = 285 + struct.unpack(b'!H', size_bytes)[0]
elif size > 30:
size = struct.unpack(
b'!I', size_bytes.rjust(4, b'\x00'))[0] + 65821
return size, new_offset

View file

@ -1,11 +0,0 @@
"""
maxminddb.errors
~~~~~~~~~~~~~~~~
This module contains custom errors for the MaxMind DB reader
"""
class InvalidDatabaseError(RuntimeError):
"""This error is thrown when unexpected data is found in the database."""

View file

@ -1,570 +0,0 @@
#include <Python.h>
#include <maxminddb.h>
#include "structmember.h"
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
static PyTypeObject Reader_Type;
static PyTypeObject Metadata_Type;
static PyObject *MaxMindDB_error;
typedef struct {
PyObject_HEAD /* no semicolon */
MMDB_s *mmdb;
} Reader_obj;
typedef struct {
PyObject_HEAD /* no semicolon */
PyObject *binary_format_major_version;
PyObject *binary_format_minor_version;
PyObject *build_epoch;
PyObject *database_type;
PyObject *description;
PyObject *ip_version;
PyObject *languages;
PyObject *node_count;
PyObject *record_size;
} Metadata_obj;
static PyObject *from_entry_data_list(MMDB_entry_data_list_s **entry_data_list);
static PyObject *from_map(MMDB_entry_data_list_s **entry_data_list);
static PyObject *from_array(MMDB_entry_data_list_s **entry_data_list);
static PyObject *from_uint128(const MMDB_entry_data_list_s *entry_data_list);
#if PY_MAJOR_VERSION >= 3
#define MOD_INIT(name) PyMODINIT_FUNC PyInit_ ## name(void)
#define RETURN_MOD_INIT(m) return (m)
#define FILE_NOT_FOUND_ERROR PyExc_FileNotFoundError
#else
#define MOD_INIT(name) PyMODINIT_FUNC init ## name(void)
#define RETURN_MOD_INIT(m) return
#define PyInt_FromLong PyLong_FromLong
#define FILE_NOT_FOUND_ERROR PyExc_IOError
#endif
#ifdef __GNUC__
# define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
#else
# define UNUSED(x) UNUSED_ ## x
#endif
static int Reader_init(PyObject *self, PyObject *args, PyObject *kwds)
{
char *filename;
int mode = 0;
static char *kwlist[] = {"database", "mode", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i", kwlist, &filename, &mode)) {
return -1;
}
if (mode != 0 && mode != 1) {
PyErr_Format(PyExc_ValueError, "Unsupported open mode (%i). Only "
"MODE_AUTO and MODE_MMAP_EXT are supported by this extension.",
mode);
return -1;
}
if (0 != access(filename, R_OK)) {
PyErr_Format(FILE_NOT_FOUND_ERROR,
"No such file or directory: '%s'",
filename);
return -1;
}
MMDB_s *mmdb = (MMDB_s *)malloc(sizeof(MMDB_s));
if (NULL == mmdb) {
PyErr_NoMemory();
return -1;
}
Reader_obj *mmdb_obj = (Reader_obj *)self;
if (!mmdb_obj) {
free(mmdb);
PyErr_NoMemory();
return -1;
}
uint16_t status = MMDB_open(filename, MMDB_MODE_MMAP, mmdb);
if (MMDB_SUCCESS != status) {
free(mmdb);
PyErr_Format(
MaxMindDB_error,
"Error opening database file (%s). Is this a valid MaxMind DB file?",
filename
);
return -1;
}
mmdb_obj->mmdb = mmdb;
return 0;
}
static PyObject *Reader_get(PyObject *self, PyObject *args)
{
char *ip_address = NULL;
Reader_obj *mmdb_obj = (Reader_obj *)self;
if (!PyArg_ParseTuple(args, "s", &ip_address)) {
return NULL;
}
MMDB_s *mmdb = mmdb_obj->mmdb;
if (NULL == mmdb) {
PyErr_SetString(PyExc_ValueError,
"Attempt to read from a closed MaxMind DB.");
return NULL;
}
int gai_error = 0;
int mmdb_error = MMDB_SUCCESS;
MMDB_lookup_result_s result =
MMDB_lookup_string(mmdb, ip_address, &gai_error,
&mmdb_error);
if (0 != gai_error) {
PyErr_Format(PyExc_ValueError,
"'%s' does not appear to be an IPv4 or IPv6 address.",
ip_address);
return NULL;
}
if (MMDB_SUCCESS != mmdb_error) {
PyObject *exception;
if (MMDB_IPV6_LOOKUP_IN_IPV4_DATABASE_ERROR == mmdb_error) {
exception = PyExc_ValueError;
} else {
exception = MaxMindDB_error;
}
PyErr_Format(exception, "Error looking up %s. %s",
ip_address, MMDB_strerror(mmdb_error));
return NULL;
}
if (!result.found_entry) {
Py_RETURN_NONE;
}
MMDB_entry_data_list_s *entry_data_list = NULL;
int status = MMDB_get_entry_data_list(&result.entry, &entry_data_list);
if (MMDB_SUCCESS != status) {
PyErr_Format(MaxMindDB_error,
"Error while looking up data for %s. %s",
ip_address, MMDB_strerror(status));
MMDB_free_entry_data_list(entry_data_list);
return NULL;
}
MMDB_entry_data_list_s *original_entry_data_list = entry_data_list;
PyObject *py_obj = from_entry_data_list(&entry_data_list);
MMDB_free_entry_data_list(original_entry_data_list);
return py_obj;
}
static PyObject *Reader_metadata(PyObject *self, PyObject *UNUSED(args))
{
Reader_obj *mmdb_obj = (Reader_obj *)self;
if (NULL == mmdb_obj->mmdb) {
PyErr_SetString(PyExc_IOError,
"Attempt to read from a closed MaxMind DB.");
return NULL;
}
MMDB_entry_data_list_s *entry_data_list;
MMDB_get_metadata_as_entry_data_list(mmdb_obj->mmdb, &entry_data_list);
MMDB_entry_data_list_s *original_entry_data_list = entry_data_list;
PyObject *metadata_dict = from_entry_data_list(&entry_data_list);
MMDB_free_entry_data_list(original_entry_data_list);
if (NULL == metadata_dict || !PyDict_Check(metadata_dict)) {
PyErr_SetString(MaxMindDB_error,
"Error decoding metadata.");
return NULL;
}
PyObject *args = PyTuple_New(0);
if (NULL == args) {
Py_DECREF(metadata_dict);
return NULL;
}
PyObject *metadata = PyObject_Call((PyObject *)&Metadata_Type, args,
metadata_dict);
Py_DECREF(metadata_dict);
return metadata;
}
static PyObject *Reader_close(PyObject *self, PyObject *UNUSED(args))
{
Reader_obj *mmdb_obj = (Reader_obj *)self;
if (NULL != mmdb_obj->mmdb) {
MMDB_close(mmdb_obj->mmdb);
free(mmdb_obj->mmdb);
mmdb_obj->mmdb = NULL;
}
Py_RETURN_NONE;
}
static void Reader_dealloc(PyObject *self)
{
Reader_obj *obj = (Reader_obj *)self;
if (NULL != obj->mmdb) {
Reader_close(self, NULL);
}
PyObject_Del(self);
}
static int Metadata_init(PyObject *self, PyObject *args, PyObject *kwds)
{
PyObject
*binary_format_major_version,
*binary_format_minor_version,
*build_epoch,
*database_type,
*description,
*ip_version,
*languages,
*node_count,
*record_size;
static char *kwlist[] = {
"binary_format_major_version",
"binary_format_minor_version",
"build_epoch",
"database_type",
"description",
"ip_version",
"languages",
"node_count",
"record_size",
NULL
};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOOOOOOO", kwlist,
&binary_format_major_version,
&binary_format_minor_version,
&build_epoch,
&database_type,
&description,
&ip_version,
&languages,
&node_count,
&record_size)) {
return -1;
}
Metadata_obj *obj = (Metadata_obj *)self;
obj->binary_format_major_version = binary_format_major_version;
obj->binary_format_minor_version = binary_format_minor_version;
obj->build_epoch = build_epoch;
obj->database_type = database_type;
obj->description = description;
obj->ip_version = ip_version;
obj->languages = languages;
obj->node_count = node_count;
obj->record_size = record_size;
Py_INCREF(obj->binary_format_major_version);
Py_INCREF(obj->binary_format_minor_version);
Py_INCREF(obj->build_epoch);
Py_INCREF(obj->database_type);
Py_INCREF(obj->description);
Py_INCREF(obj->ip_version);
Py_INCREF(obj->languages);
Py_INCREF(obj->node_count);
Py_INCREF(obj->record_size);
return 0;
}
static void Metadata_dealloc(PyObject *self)
{
Metadata_obj *obj = (Metadata_obj *)self;
Py_DECREF(obj->binary_format_major_version);
Py_DECREF(obj->binary_format_minor_version);
Py_DECREF(obj->build_epoch);
Py_DECREF(obj->database_type);
Py_DECREF(obj->description);
Py_DECREF(obj->ip_version);
Py_DECREF(obj->languages);
Py_DECREF(obj->node_count);
Py_DECREF(obj->record_size);
PyObject_Del(self);
}
static PyObject *from_entry_data_list(MMDB_entry_data_list_s **entry_data_list)
{
if (NULL == entry_data_list || NULL == *entry_data_list) {
PyErr_SetString(
MaxMindDB_error,
"Error while looking up data. Your database may be corrupt or you have found a bug in libmaxminddb."
);
return NULL;
}
switch ((*entry_data_list)->entry_data.type) {
case MMDB_DATA_TYPE_MAP:
return from_map(entry_data_list);
case MMDB_DATA_TYPE_ARRAY:
return from_array(entry_data_list);
case MMDB_DATA_TYPE_UTF8_STRING:
return PyUnicode_FromStringAndSize(
(*entry_data_list)->entry_data.utf8_string,
(*entry_data_list)->entry_data.data_size
);
case MMDB_DATA_TYPE_BYTES:
return PyByteArray_FromStringAndSize(
(const char *)(*entry_data_list)->entry_data.bytes,
(Py_ssize_t)(*entry_data_list)->entry_data.data_size);
case MMDB_DATA_TYPE_DOUBLE:
return PyFloat_FromDouble((*entry_data_list)->entry_data.double_value);
case MMDB_DATA_TYPE_FLOAT:
return PyFloat_FromDouble((*entry_data_list)->entry_data.float_value);
case MMDB_DATA_TYPE_UINT16:
return PyLong_FromLong( (*entry_data_list)->entry_data.uint16);
case MMDB_DATA_TYPE_UINT32:
return PyLong_FromLong((*entry_data_list)->entry_data.uint32);
case MMDB_DATA_TYPE_BOOLEAN:
return PyBool_FromLong((*entry_data_list)->entry_data.boolean);
case MMDB_DATA_TYPE_UINT64:
return PyLong_FromUnsignedLongLong(
(*entry_data_list)->entry_data.uint64);
case MMDB_DATA_TYPE_UINT128:
return from_uint128(*entry_data_list);
case MMDB_DATA_TYPE_INT32:
return PyLong_FromLong((*entry_data_list)->entry_data.int32);
default:
PyErr_Format(MaxMindDB_error,
"Invalid data type arguments: %d",
(*entry_data_list)->entry_data.type);
return NULL;
}
return NULL;
}
static PyObject *from_map(MMDB_entry_data_list_s **entry_data_list)
{
PyObject *py_obj = PyDict_New();
if (NULL == py_obj) {
PyErr_NoMemory();
return NULL;
}
const uint32_t map_size = (*entry_data_list)->entry_data.data_size;
uint i;
// entry_data_list cannot start out NULL (see from_entry_data_list). We
// check it in the loop because it may become NULL.
// coverity[check_after_deref]
for (i = 0; i < map_size && entry_data_list; i++) {
*entry_data_list = (*entry_data_list)->next;
PyObject *key = PyUnicode_FromStringAndSize(
(char *)(*entry_data_list)->entry_data.utf8_string,
(*entry_data_list)->entry_data.data_size
);
*entry_data_list = (*entry_data_list)->next;
PyObject *value = from_entry_data_list(entry_data_list);
if (NULL == value) {
Py_DECREF(key);
Py_DECREF(py_obj);
return NULL;
}
PyDict_SetItem(py_obj, key, value);
Py_DECREF(value);
Py_DECREF(key);
}
return py_obj;
}
static PyObject *from_array(MMDB_entry_data_list_s **entry_data_list)
{
const uint32_t size = (*entry_data_list)->entry_data.data_size;
PyObject *py_obj = PyList_New(size);
if (NULL == py_obj) {
PyErr_NoMemory();
return NULL;
}
uint i;
// entry_data_list cannot start out NULL (see from_entry_data_list). We
// check it in the loop because it may become NULL.
// coverity[check_after_deref]
for (i = 0; i < size && entry_data_list; i++) {
*entry_data_list = (*entry_data_list)->next;
PyObject *value = from_entry_data_list(entry_data_list);
if (NULL == value) {
Py_DECREF(py_obj);
return NULL;
}
// PyList_SetItem 'steals' the reference
PyList_SetItem(py_obj, i, value);
}
return py_obj;
}
static PyObject *from_uint128(const MMDB_entry_data_list_s *entry_data_list)
{
uint64_t high = 0;
uint64_t low = 0;
#if MMDB_UINT128_IS_BYTE_ARRAY
int i;
for (i = 0; i < 8; i++) {
high = (high << 8) | entry_data_list->entry_data.uint128[i];
}
for (i = 8; i < 16; i++) {
low = (low << 8) | entry_data_list->entry_data.uint128[i];
}
#else
high = entry_data_list->entry_data.uint128 >> 64;
low = (uint64_t)entry_data_list->entry_data.uint128;
#endif
char *num_str = malloc(33);
if (NULL == num_str) {
PyErr_NoMemory();
return NULL;
}
snprintf(num_str, 33, "%016" PRIX64 "%016" PRIX64, high, low);
PyObject *py_obj = PyLong_FromString(num_str, NULL, 16);
free(num_str);
return py_obj;
}
static PyMethodDef Reader_methods[] = {
{ "get", Reader_get, METH_VARARGS,
"Get record for IP address" },
{ "metadata", Reader_metadata, METH_NOARGS,
"Returns metadata object for database" },
{ "close", Reader_close, METH_NOARGS, "Closes database"},
{ NULL, NULL, 0, NULL }
};
static PyTypeObject Reader_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_basicsize = sizeof(Reader_obj),
.tp_dealloc = Reader_dealloc,
.tp_doc = "Reader object",
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_methods = Reader_methods,
.tp_name = "Reader",
.tp_init = Reader_init,
};
static PyMethodDef Metadata_methods[] = {
{ NULL, NULL, 0, NULL }
};
/* *INDENT-OFF* */
static PyMemberDef Metadata_members[] = {
{ "binary_format_major_version", T_OBJECT, offsetof(
Metadata_obj, binary_format_major_version), READONLY, NULL },
{ "binary_format_minor_version", T_OBJECT, offsetof(
Metadata_obj, binary_format_minor_version), READONLY, NULL },
{ "build_epoch", T_OBJECT, offsetof(Metadata_obj, build_epoch),
READONLY, NULL },
{ "database_type", T_OBJECT, offsetof(Metadata_obj, database_type),
READONLY, NULL },
{ "description", T_OBJECT, offsetof(Metadata_obj, description),
READONLY, NULL },
{ "ip_version", T_OBJECT, offsetof(Metadata_obj, ip_version),
READONLY, NULL },
{ "languages", T_OBJECT, offsetof(Metadata_obj, languages), READONLY,
NULL },
{ "node_count", T_OBJECT, offsetof(Metadata_obj, node_count),
READONLY, NULL },
{ "record_size", T_OBJECT, offsetof(Metadata_obj, record_size),
READONLY, NULL },
{ NULL, 0, 0, 0, NULL }
};
/* *INDENT-ON* */
static PyTypeObject Metadata_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_basicsize = sizeof(Metadata_obj),
.tp_dealloc = Metadata_dealloc,
.tp_doc = "Metadata object",
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_members = Metadata_members,
.tp_methods = Metadata_methods,
.tp_name = "Metadata",
.tp_init = Metadata_init
};
static PyMethodDef MaxMindDB_methods[] = {
{ NULL, NULL, 0, NULL }
};
#if PY_MAJOR_VERSION >= 3
static struct PyModuleDef MaxMindDB_module = {
PyModuleDef_HEAD_INIT,
.m_name = "extension",
.m_doc = "This is a C extension to read MaxMind DB file format",
.m_methods = MaxMindDB_methods,
};
#endif
MOD_INIT(extension){
PyObject *m;
#if PY_MAJOR_VERSION >= 3
m = PyModule_Create(&MaxMindDB_module);
#else
m = Py_InitModule("extension", MaxMindDB_methods);
#endif
if (!m) {
RETURN_MOD_INIT(NULL);
}
Reader_Type.tp_new = PyType_GenericNew;
if (PyType_Ready(&Reader_Type)) {
RETURN_MOD_INIT(NULL);
}
Py_INCREF(&Reader_Type);
PyModule_AddObject(m, "Reader", (PyObject *)&Reader_Type);
Metadata_Type.tp_new = PyType_GenericNew;
if (PyType_Ready(&Metadata_Type)) {
RETURN_MOD_INIT(NULL);
}
PyModule_AddObject(m, "extension", (PyObject *)&Metadata_Type);
PyObject* error_mod = PyImport_ImportModule("maxminddb.errors");
if (error_mod == NULL) {
RETURN_MOD_INIT(NULL);
}
MaxMindDB_error = PyObject_GetAttrString(error_mod, "InvalidDatabaseError");
Py_DECREF(error_mod);
if (MaxMindDB_error == NULL) {
RETURN_MOD_INIT(NULL);
}
Py_INCREF(MaxMindDB_error);
/* We primarily add it to the module for backwards compatibility */
PyModule_AddObject(m, "InvalidDatabaseError", MaxMindDB_error);
RETURN_MOD_INIT(m);
}

View file

@ -1,65 +0,0 @@
"""For internal use only. It provides a slice-like file reader."""
import os
try:
from multiprocessing import Lock
except ImportError:
from threading import Lock
class FileBuffer(object):
"""A slice-able file reader"""
def __init__(self, database):
self._handle = open(database, 'rb')
self._size = os.fstat(self._handle.fileno()).st_size
if not hasattr(os, 'pread'):
self._lock = Lock()
def __getitem__(self, key):
if isinstance(key, slice):
return self._read(key.stop - key.start, key.start)
elif isinstance(key, int):
return self._read(1, key)
else:
raise TypeError("Invalid argument type.")
def rfind(self, needle, start):
"""Reverse find needle from start"""
pos = self._read(self._size - start - 1, start).rfind(needle)
if pos == -1:
return pos
return start + pos
def size(self):
"""Size of file"""
return self._size
def close(self):
"""Close file"""
self._handle.close()
if hasattr(os, 'pread'):
def _read(self, buffersize, offset):
"""read that uses pread"""
# pylint: disable=no-member
return os.pread(self._handle.fileno(), buffersize, offset)
else:
def _read(self, buffersize, offset):
"""read with a lock
This lock is necessary as after a fork, the different processes
will share the same file table entry, even if we dup the fd, and
as such the same offsets. There does not appear to be a way to
duplicate the file table entry and we cannot re-open based on the
original path as that file may have replaced with another or
unlinked.
"""
with self._lock:
self._handle.seek(offset)
return self._handle.read(buffersize)

File diff suppressed because it is too large Load diff

View file

@ -1,221 +0,0 @@
"""
maxminddb.reader
~~~~~~~~~~~~~~~~
This module contains the pure Python database reader and related classes.
"""
from __future__ import unicode_literals
try:
import mmap
except ImportError:
# pylint: disable=invalid-name
mmap = None
import struct
from maxminddb.compat import byte_from_int, int_from_byte, ipaddress
from maxminddb.const import MODE_AUTO, MODE_MMAP, MODE_FILE, MODE_MEMORY
from maxminddb.decoder import Decoder
from maxminddb.errors import InvalidDatabaseError
from maxminddb.file import FileBuffer
class Reader(object):
"""
Instances of this class provide a reader for the MaxMind DB format. IP
addresses can be looked up using the ``get`` method.
"""
_DATA_SECTION_SEPARATOR_SIZE = 16
_METADATA_START_MARKER = b"\xAB\xCD\xEFMaxMind.com"
_ipv4_start = None
def __init__(self, database, mode=MODE_AUTO):
"""Reader for the MaxMind DB file format
Arguments:
database -- A path to a valid MaxMind DB file such as a GeoIP2
database file.
mode -- mode to open the database with. Valid mode are:
* MODE_MMAP - read from memory map.
* MODE_FILE - read database as standard file.
* MODE_MEMORY - load database into memory.
* MODE_AUTO - tries MODE_MMAP and then MODE_FILE. Default.
"""
if (mode == MODE_AUTO and mmap) or mode == MODE_MMAP:
with open(database, 'rb') as db_file:
self._buffer = mmap.mmap(
db_file.fileno(), 0, access=mmap.ACCESS_READ)
self._buffer_size = self._buffer.size()
elif mode in (MODE_AUTO, MODE_FILE):
self._buffer = FileBuffer(database)
self._buffer_size = self._buffer.size()
elif mode == MODE_MEMORY:
with open(database, 'rb') as db_file:
self._buffer = db_file.read()
self._buffer_size = len(self._buffer)
else:
raise ValueError('Unsupported open mode ({0}). Only MODE_AUTO, '
' MODE_FILE, and MODE_MEMORY are support by the pure Python '
'Reader'.format(mode))
metadata_start = self._buffer.rfind(self._METADATA_START_MARKER,
max(0, self._buffer_size
- 128 * 1024))
if metadata_start == -1:
self.close()
raise InvalidDatabaseError('Error opening database file ({0}). '
'Is this a valid MaxMind DB file?'
''.format(database))
metadata_start += len(self._METADATA_START_MARKER)
metadata_decoder = Decoder(self._buffer, metadata_start)
(metadata, _) = metadata_decoder.decode(metadata_start)
self._metadata = Metadata(
**metadata) # pylint: disable=bad-option-value
self._decoder = Decoder(self._buffer, self._metadata.search_tree_size
+ self._DATA_SECTION_SEPARATOR_SIZE)
def metadata(self):
"""Return the metadata associated with the MaxMind DB file"""
return self._metadata
def get(self, ip_address):
"""Return the record for the ip_address in the MaxMind DB
Arguments:
ip_address -- an IP address in the standard string notation
"""
address = ipaddress.ip_address(ip_address)
if address.version == 6 and self._metadata.ip_version == 4:
raise ValueError('Error looking up {0}. You attempted to look up '
'an IPv6 address in an IPv4-only database.'.format(
ip_address))
pointer = self._find_address_in_tree(address)
return self._resolve_data_pointer(pointer) if pointer else None
def _find_address_in_tree(self, ip_address):
packed = ip_address.packed
bit_count = len(packed) * 8
node = self._start_node(bit_count)
for i in range(bit_count):
if node >= self._metadata.node_count:
break
bit = 1 & (int_from_byte(packed[i >> 3]) >> 7 - (i % 8))
node = self._read_node(node, bit)
if node == self._metadata.node_count:
# Record is empty
return 0
elif node > self._metadata.node_count:
return node
raise InvalidDatabaseError('Invalid node in search tree')
def _start_node(self, length):
if self._metadata.ip_version != 6 or length == 128:
return 0
# We are looking up an IPv4 address in an IPv6 tree. Skip over the
# first 96 nodes.
if self._ipv4_start:
return self._ipv4_start
node = 0
for _ in range(96):
if node >= self._metadata.node_count:
break
node = self._read_node(node, 0)
self._ipv4_start = node
return node
def _read_node(self, node_number, index):
base_offset = node_number * self._metadata.node_byte_size
record_size = self._metadata.record_size
if record_size == 24:
offset = base_offset + index * 3
node_bytes = b'\x00' + self._buffer[offset:offset + 3]
elif record_size == 28:
(middle,) = struct.unpack(
b'!B', self._buffer[base_offset + 3:base_offset + 4])
if index:
middle &= 0x0F
else:
middle = (0xF0 & middle) >> 4
offset = base_offset + index * 4
node_bytes = byte_from_int(
middle) + self._buffer[offset:offset + 3]
elif record_size == 32:
offset = base_offset + index * 4
node_bytes = self._buffer[offset:offset + 4]
else:
raise InvalidDatabaseError(
'Unknown record size: {0}'.format(record_size))
return struct.unpack(b'!I', node_bytes)[0]
def _resolve_data_pointer(self, pointer):
resolved = pointer - self._metadata.node_count + \
self._metadata.search_tree_size
if resolved > self._buffer_size:
raise InvalidDatabaseError(
"The MaxMind DB file's search tree is corrupt")
(data, _) = self._decoder.decode(resolved)
return data
def close(self):
"""Closes the MaxMind DB file and returns the resources to the system"""
# pylint: disable=unidiomatic-typecheck
if type(self._buffer) not in (str, bytes):
self._buffer.close()
class Metadata(object):
"""Metadata for the MaxMind DB reader"""
# pylint: disable=too-many-instance-attributes
def __init__(self, **kwargs):
"""Creates new Metadata object. kwargs are key/value pairs from spec"""
# Although I could just update __dict__, that is less obvious and it
# doesn't work well with static analysis tools and some IDEs
self.node_count = kwargs['node_count']
self.record_size = kwargs['record_size']
self.ip_version = kwargs['ip_version']
self.database_type = kwargs['database_type']
self.languages = kwargs['languages']
self.binary_format_major_version = kwargs[
'binary_format_major_version']
self.binary_format_minor_version = kwargs[
'binary_format_minor_version']
self.build_epoch = kwargs['build_epoch']
self.description = kwargs['description']
@property
def node_byte_size(self):
"""The size of a node in bytes"""
return self.record_size // 4
@property
def search_tree_size(self):
"""The size of the search tree"""
return self.node_count * self.node_byte_size
def __repr__(self):
args = ', '.join('%s=%r' % x for x in self.__dict__.items())
return '{module}.{class_name}({data})'.format(
module=self.__module__,
class_name=self.__class__.__name__,
data=args)

Some files were not shown because too many files have changed in this diff Show more