copyparty 1.16.5__tar.gz → 1.16.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. {copyparty-1.16.5 → copyparty-1.16.6}/PKG-INFO +14 -2
  2. {copyparty-1.16.5 → copyparty-1.16.6}/README.md +13 -1
  3. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/__init__.py +3 -0
  4. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/__main__.py +4 -1
  5. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/__version__.py +2 -2
  6. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/authsrv.py +31 -18
  7. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/fsutil.py +4 -4
  8. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/httpcli.py +212 -68
  9. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/httpsrv.py +6 -5
  10. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/mtag.py +4 -4
  11. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/smbd.py +1 -1
  12. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/sutil.py +1 -1
  13. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/tftpd.py +1 -1
  14. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/th_cli.py +3 -3
  15. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/th_srv.py +6 -6
  16. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/u2idx.py +3 -3
  17. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/up2k.py +91 -86
  18. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/util.py +13 -13
  19. copyparty-1.16.6/copyparty/web/rups.css.gz +0 -0
  20. copyparty-1.16.6/copyparty/web/rups.html +67 -0
  21. copyparty-1.16.6/copyparty/web/rups.js.gz +0 -0
  22. copyparty-1.16.6/copyparty/web/shares.css.gz +0 -0
  23. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/shares.html +2 -0
  24. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/splash.html +1 -0
  25. copyparty-1.16.6/copyparty/web/splash.js.gz +0 -0
  26. copyparty-1.16.6/copyparty/web/up2k.js.gz +0 -0
  27. copyparty-1.16.6/copyparty/web/util.js.gz +0 -0
  28. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty.egg-info/PKG-INFO +14 -2
  29. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty.egg-info/SOURCES.txt +3 -0
  30. copyparty-1.16.5/copyparty/web/shares.css.gz +0 -0
  31. copyparty-1.16.5/copyparty/web/splash.js.gz +0 -0
  32. copyparty-1.16.5/copyparty/web/up2k.js.gz +0 -0
  33. copyparty-1.16.5/copyparty/web/util.js.gz +0 -0
  34. {copyparty-1.16.5 → copyparty-1.16.6}/LICENSE +0 -0
  35. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/bos/__init__.py +0 -0
  36. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/bos/bos.py +0 -0
  37. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/bos/path.py +0 -0
  38. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/broker_mp.py +0 -0
  39. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/broker_mpw.py +0 -0
  40. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/broker_thr.py +0 -0
  41. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/broker_util.py +0 -0
  42. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/cert.py +0 -0
  43. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/cfg.py +0 -0
  44. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/dxml.py +0 -0
  45. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/ftpd.py +0 -0
  46. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/httpconn.py +0 -0
  47. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/ico.py +0 -0
  48. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/mdns.py +0 -0
  49. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/metrics.py +0 -0
  50. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/multicast.py +0 -0
  51. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/pwhash.py +0 -0
  52. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/res/COPYING.txt +0 -0
  53. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/res/__init__.py +0 -0
  54. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/res/insecure.pem +0 -0
  55. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/ssdp.py +0 -0
  56. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/star.py +0 -0
  57. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/stolen/__init__.py +0 -0
  58. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/stolen/dnslib/__init__.py +0 -0
  59. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/stolen/dnslib/bimap.py +0 -0
  60. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/stolen/dnslib/bit.py +0 -0
  61. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/stolen/dnslib/buffer.py +0 -0
  62. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/stolen/dnslib/dns.py +0 -0
  63. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/stolen/dnslib/label.py +0 -0
  64. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/stolen/dnslib/lex.py +0 -0
  65. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/stolen/dnslib/ranges.py +0 -0
  66. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/stolen/ifaddr/__init__.py +0 -0
  67. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/stolen/ifaddr/_posix.py +0 -0
  68. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/stolen/ifaddr/_shared.py +0 -0
  69. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/stolen/ifaddr/_win32.py +0 -0
  70. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/stolen/qrcodegen.py +0 -0
  71. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/stolen/surrogateescape.py +0 -0
  72. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/svchub.py +0 -0
  73. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/szip.py +0 -0
  74. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/tcpsrv.py +0 -0
  75. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/a/__init__.py +0 -0
  76. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/a/partyfuse.py +0 -0
  77. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/a/u2c.py +0 -0
  78. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/a/webdav-cfg.bat +0 -0
  79. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/baguettebox.js.gz +0 -0
  80. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/browser.css.gz +0 -0
  81. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/browser.html +0 -0
  82. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/browser.js.gz +0 -0
  83. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/browser2.html +0 -0
  84. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/cf.html +0 -0
  85. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/dbg-audio.js.gz +0 -0
  86. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/dd/2.png +0 -0
  87. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/dd/3.png +0 -0
  88. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/dd/4.png +0 -0
  89. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/dd/5.png +0 -0
  90. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/dd/__init__.py +0 -0
  91. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/deps/__init__.py +0 -0
  92. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/deps/busy.mp3.gz +0 -0
  93. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/deps/easymde.css.gz +0 -0
  94. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/deps/easymde.js.gz +0 -0
  95. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/deps/fuse.py +0 -0
  96. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/deps/marked.js.gz +0 -0
  97. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/deps/mini-fa.css.gz +0 -0
  98. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/deps/mini-fa.woff +0 -0
  99. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/deps/prism.css.gz +0 -0
  100. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/deps/prism.js.gz +0 -0
  101. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/deps/prismd.css.gz +0 -0
  102. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/deps/scp.woff2 +0 -0
  103. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/deps/sha512.ac.js.gz +0 -0
  104. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/deps/sha512.hw.js.gz +0 -0
  105. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/md.css.gz +0 -0
  106. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/md.html +0 -0
  107. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/md.js.gz +0 -0
  108. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/md2.css.gz +0 -0
  109. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/md2.js.gz +0 -0
  110. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/mde.css.gz +0 -0
  111. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/mde.html +0 -0
  112. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/mde.js.gz +0 -0
  113. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/msg.css.gz +0 -0
  114. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/msg.html +0 -0
  115. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/shares.js.gz +0 -0
  116. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/splash.css.gz +0 -0
  117. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/svcs.html +0 -0
  118. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/svcs.js.gz +0 -0
  119. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/ui.css.gz +0 -0
  120. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty/web/w.hash.js.gz +0 -0
  121. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty.egg-info/dependency_links.txt +0 -0
  122. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty.egg-info/entry_points.txt +0 -0
  123. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty.egg-info/requires.txt +0 -0
  124. {copyparty-1.16.5 → copyparty-1.16.6}/copyparty.egg-info/top_level.txt +0 -0
  125. {copyparty-1.16.5 → copyparty-1.16.6}/pyproject.toml +0 -0
  126. {copyparty-1.16.5 → copyparty-1.16.6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: copyparty
3
- Version: 1.16.5
3
+ Version: 1.16.6
4
4
  Summary: Portable file server with accelerated resumable uploads, deduplication, WebDAV, FTP, zeroconf, media indexer, video thumbnails, audio transcoding, and write-only folders
5
5
  Author-email: ed <copyparty@ocv.me>
6
6
  License: MIT
@@ -103,6 +103,7 @@ turn almost any device into a file server with resumable uploads/downloads using
103
103
  * [shares](#shares) - share a file or folder by creating a temporary link
104
104
  * [batch rename](#batch-rename) - select some files and press `F2` to bring up the rename UI
105
105
  * [rss feeds](#rss-feeds) - monitor a folder with your RSS reader
106
+ * [recent uploads](#recent-uploads) - list all recent uploads
106
107
  * [media player](#media-player) - plays almost every audio format there is
107
108
  * [audio equalizer](#audio-equalizer) - and [dynamic range compressor](https://en.wikipedia.org/wiki/Dynamic_range_compression)
108
109
  * [fix unreliable playback on android](#fix-unreliable-playback-on-android) - due to phone / app settings
@@ -772,7 +773,7 @@ files go into `[ok]` if they exist (and you get a link to where it is), otherwis
772
773
 
773
774
  ### unpost
774
775
 
775
- undo/delete accidental uploads
776
+ undo/delete accidental uploads using the `[🧯]` tab in the UI
776
777
 
777
778
  ![copyparty-unpost-fs8](https://user-images.githubusercontent.com/241032/129635368-3afa6634-c20f-418c-90dc-ec411f3b3897.png)
778
779
 
@@ -931,6 +932,17 @@ url parameters:
931
932
  * uppercase = reverse-sort; `M` = oldest file first
932
933
 
933
934
 
935
+ ## recent uploads
936
+
937
+ list all recent uploads by clicking "show recent uploads" in the controlpanel
938
+
939
+ will show uploader IP and upload-time if the visitor has the admin permission
940
+
941
+ * global-option `--ups-when` makes upload-time visible to all users, and not just admins
942
+
943
+ note that the [🧯 unpost](#unpost) feature is better suited for viewing *your own* recent uploads, as it includes the option to undo/delete them
944
+
945
+
934
946
  ## media player
935
947
 
936
948
  plays almost every audio format there is (if the server has FFmpeg installed for on-demand transcoding)
@@ -48,6 +48,7 @@ turn almost any device into a file server with resumable uploads/downloads using
48
48
  * [shares](#shares) - share a file or folder by creating a temporary link
49
49
  * [batch rename](#batch-rename) - select some files and press `F2` to bring up the rename UI
50
50
  * [rss feeds](#rss-feeds) - monitor a folder with your RSS reader
51
+ * [recent uploads](#recent-uploads) - list all recent uploads
51
52
  * [media player](#media-player) - plays almost every audio format there is
52
53
  * [audio equalizer](#audio-equalizer) - and [dynamic range compressor](https://en.wikipedia.org/wiki/Dynamic_range_compression)
53
54
  * [fix unreliable playback on android](#fix-unreliable-playback-on-android) - due to phone / app settings
@@ -717,7 +718,7 @@ files go into `[ok]` if they exist (and you get a link to where it is), otherwis
717
718
 
718
719
  ### unpost
719
720
 
720
- undo/delete accidental uploads
721
+ undo/delete accidental uploads using the `[🧯]` tab in the UI
721
722
 
722
723
  ![copyparty-unpost-fs8](https://user-images.githubusercontent.com/241032/129635368-3afa6634-c20f-418c-90dc-ec411f3b3897.png)
723
724
 
@@ -876,6 +877,17 @@ url parameters:
876
877
  * uppercase = reverse-sort; `M` = oldest file first
877
878
 
878
879
 
880
+ ## recent uploads
881
+
882
+ list all recent uploads by clicking "show recent uploads" in the controlpanel
883
+
884
+ will show uploader IP and upload-time if the visitor has the admin permission
885
+
886
+ * global-option `--ups-when` makes upload-time visible to all users, and not just admins
887
+
888
+ note that the [🧯 unpost](#unpost) feature is better suited for viewing *your own* recent uploads, as it includes the option to undo/delete them
889
+
890
+
879
891
  ## media player
880
892
 
881
893
  plays almost every audio format there is (if the server has FFmpeg installed for on-demand transcoding)
@@ -88,6 +88,9 @@ web/mde.html
88
88
  web/mde.js
89
89
  web/msg.css
90
90
  web/msg.html
91
+ web/rups.css
92
+ web/rups.html
93
+ web/rups.js
91
94
  web/shares.css
92
95
  web/shares.html
93
96
  web/shares.js
@@ -1242,7 +1242,6 @@ def add_optouts(ap):
1242
1242
  ap2.add_argument("--no-zip", action="store_true", help="disable download as zip/tar")
1243
1243
  ap2.add_argument("--no-tarcmp", action="store_true", help="disable download as compressed tar (?tar=gz, ?tar=bz2, ?tar=xz, ?tar=gz:9, ...)")
1244
1244
  ap2.add_argument("--no-lifetime", action="store_true", help="do not allow clients (or server config) to schedule an upload to be deleted after a given time")
1245
- ap2.add_argument("--no-up-list", action="store_true", help="don't show list of incoming files in controlpanel")
1246
1245
  ap2.add_argument("--no-pipe", action="store_true", help="disable race-the-beam (lockstep download of files which are currently being uploaded) (volflag=nopipe)")
1247
1246
  ap2.add_argument("--no-db-ip", action="store_true", help="do not write uploader IPs into the database")
1248
1247
 
@@ -1318,7 +1317,10 @@ def add_admin(ap):
1318
1317
  ap2.add_argument("--no-reload", action="store_true", help="disable ?reload=cfg (reload users/volumes/volflags from config file)")
1319
1318
  ap2.add_argument("--no-rescan", action="store_true", help="disable ?scan (volume reindexing)")
1320
1319
  ap2.add_argument("--no-stack", action="store_true", help="disable ?stack (list all stacks)")
1320
+ ap2.add_argument("--no-ups-page", action="store_true", help="disable ?ru (list of recent uploads)")
1321
+ ap2.add_argument("--no-up-list", action="store_true", help="don't show list of incoming files in controlpanel")
1321
1322
  ap2.add_argument("--dl-list", metavar="LVL", type=int, default=2, help="who can see active downloads in the controlpanel? [\033[32m0\033[0m]=nobody, [\033[32m1\033[0m]=admins, [\033[32m2\033[0m]=everyone")
1323
+ ap2.add_argument("--ups-when", action="store_true", help="let everyone see upload timestamps on the ?ru page, not just admins")
1322
1324
 
1323
1325
 
1324
1326
  def add_thumbnail(ap):
@@ -1497,6 +1499,7 @@ def add_debug(ap):
1497
1499
  ap2.add_argument("--bf-nc", metavar="NUM", type=int, default=200, help="bak-flips: stop if there's more than \033[33mNUM\033[0m files at \033[33m--kf-dir\033[0m already; default: 6.3 GiB max (200*32M)")
1498
1500
  ap2.add_argument("--bf-dir", metavar="PATH", type=u, default="bf", help="bak-flips: store corrupted chunks at \033[33mPATH\033[0m; default: folder named 'bf' wherever copyparty was started")
1499
1501
  ap2.add_argument("--bf-log", metavar="PATH", type=u, default="", help="bak-flips: log corruption info to a textfile at \033[33mPATH\033[0m")
1502
+ ap2.add_argument("--no-cfg-cmt-warn", action="store_true", help=argparse.SUPPRESS)
1500
1503
 
1501
1504
 
1502
1505
  # fmt: on
@@ -1,8 +1,8 @@
1
1
  # coding: utf-8
2
2
 
3
- VERSION = (1, 16, 5)
3
+ VERSION = (1, 16, 6)
4
4
  CODENAME = "COPYparty"
5
- BUILD_DT = (2024, 12, 11)
5
+ BUILD_DT = (2024, 12, 19)
6
6
 
7
7
  S_VERSION = ".".join(map(str, VERSION))
8
8
  S_BUILD_DT = "{0:04d}-{1:02d}-{2:02d}".format(*BUILD_DT)
@@ -205,7 +205,7 @@ class Lim(object):
205
205
 
206
206
  df, du, err = get_df(abspath, True)
207
207
  if err:
208
- t = "failed to read disk space usage for [%s]: %s"
208
+ t = "failed to read disk space usage for %r: %s"
209
209
  self.log(t % (abspath, err), 3)
210
210
  self.dfv = 0xAAAAAAAAA # 42.6 GiB
211
211
  else:
@@ -519,7 +519,7 @@ class VFS(object):
519
519
  """returns [vfsnode,fs_remainder] if user has the requested permissions"""
520
520
  if relchk(vpath):
521
521
  if self.log:
522
- self.log("vfs", "invalid relpath [{}]".format(vpath))
522
+ self.log("vfs", "invalid relpath %r @%s" % (vpath, uname))
523
523
  raise Pebkac(422)
524
524
 
525
525
  cvpath = undot(vpath)
@@ -536,11 +536,11 @@ class VFS(object):
536
536
  if req and uname not in d and uname != LEELOO_DALLAS:
537
537
  if vpath != cvpath and vpath != "." and self.log:
538
538
  ap = vn.canonical(rem)
539
- t = "{} has no {} in [{}] => [{}] => [{}]"
540
- self.log("vfs", t.format(uname, msg, vpath, cvpath, ap), 6)
539
+ t = "%s has no %s in %r => %r => %r"
540
+ self.log("vfs", t % (uname, msg, vpath, cvpath, ap), 6)
541
541
 
542
- t = 'you don\'t have %s-access in "/%s" or below "/%s"'
543
- raise Pebkac(err, t % (msg, cvpath, vn.vpath))
542
+ t = "you don't have %s-access in %r or below %r"
543
+ raise Pebkac(err, t % (msg, "/" + cvpath, "/" + vn.vpath))
544
544
 
545
545
  return vn, rem
546
546
 
@@ -686,8 +686,8 @@ class VFS(object):
686
686
  and fsroot in seen
687
687
  ):
688
688
  if self.log:
689
- t = "bailing from symlink loop,\n prev: {}\n curr: {}\n from: {}/{}"
690
- self.log("vfs.walk", t.format(seen[-1], fsroot, self.vpath, rem), 3)
689
+ t = "bailing from symlink loop,\n prev: %r\n curr: %r\n from: %r / %r"
690
+ self.log("vfs.walk", t % (seen[-1], fsroot, self.vpath, rem), 3)
691
691
  return
692
692
 
693
693
  if "xdev" in self.flags or "xvol" in self.flags:
@@ -699,7 +699,7 @@ class VFS(object):
699
699
  rm1.append(le)
700
700
  _ = [vfs_ls.remove(x) for x in rm1] # type: ignore
701
701
 
702
- dots_ok = wantdots and uname in dbv.axs.udot
702
+ dots_ok = wantdots and (wantdots == 2 or uname in dbv.axs.udot)
703
703
  if not dots_ok:
704
704
  vfs_ls = [x for x in vfs_ls if "/." not in "/" + x[0]]
705
705
 
@@ -753,7 +753,7 @@ class VFS(object):
753
753
  # if single folder: the folder itself is the top-level item
754
754
  folder = "" if flt or not wrap else (vpath.split("/")[-1].lstrip(".") or "top")
755
755
 
756
- g = self.walk(folder, vrem, [], uname, [[True, False]], True, scandir, False)
756
+ g = self.walk(folder, vrem, [], uname, [[True, False]], 1, scandir, False)
757
757
  for _, _, vpath, apath, files, rd, vd in g:
758
758
  if flt:
759
759
  files = [x for x in files if x[0] in flt]
@@ -811,8 +811,8 @@ class VFS(object):
811
811
 
812
812
  if vdev != st.st_dev:
813
813
  if self.log:
814
- t = "xdev: {}[{}] => {}[{}]"
815
- self.log("vfs", t.format(vdev, self.realpath, st.st_dev, ap), 3)
814
+ t = "xdev: %s[%r] => %s[%r]"
815
+ self.log("vfs", t % (vdev, self.realpath, st.st_dev, ap), 3)
816
816
 
817
817
  return None
818
818
 
@@ -822,7 +822,7 @@ class VFS(object):
822
822
  return vn
823
823
 
824
824
  if self.log:
825
- self.log("vfs", "xvol: [{}]".format(ap), 3)
825
+ self.log("vfs", "xvol: %r" % (ap,), 3)
826
826
 
827
827
  return None
828
828
 
@@ -907,7 +907,7 @@ class AuthSrv(object):
907
907
 
908
908
  self.idp_accs[uname] = gnames
909
909
 
910
- t = "reinitializing due to new user from IdP: [%s:%s]"
910
+ t = "reinitializing due to new user from IdP: [%r:%r]"
911
911
  self.log(t % (uname, gnames), 3)
912
912
 
913
913
  if not broker:
@@ -1561,7 +1561,7 @@ class AuthSrv(object):
1561
1561
  continue
1562
1562
 
1563
1563
  if self.args.shr_v:
1564
- t = "loading %s share [%s] by [%s] => [%s]"
1564
+ t = "loading %s share %r by %r => %r"
1565
1565
  self.log(t % (s_pr, s_k, s_un, s_vp))
1566
1566
 
1567
1567
  if s_pw:
@@ -1758,7 +1758,7 @@ class AuthSrv(object):
1758
1758
  use = True
1759
1759
  try:
1760
1760
  _ = float(zs)
1761
- zs = "%sg" % (zs)
1761
+ zs = "%sg" % (zs,)
1762
1762
  except:
1763
1763
  pass
1764
1764
  lim.dfl = unhumanize(zs)
@@ -2530,7 +2530,7 @@ class AuthSrv(object):
2530
2530
  return
2531
2531
 
2532
2532
  elif self.args.chpw_v == 2:
2533
- t = "chpw: %d changed" % (len(uok))
2533
+ t = "chpw: %d changed" % (len(uok),)
2534
2534
  if urst:
2535
2535
  t += ", \033[0munchanged:\033[35m %s" % (", ".join(list(urst)))
2536
2536
 
@@ -2688,7 +2688,7 @@ class AuthSrv(object):
2688
2688
  [],
2689
2689
  u,
2690
2690
  [[True, False]],
2691
- True,
2691
+ 1,
2692
2692
  not self.args.no_scandir,
2693
2693
  False,
2694
2694
  False,
@@ -3009,6 +3009,19 @@ def expand_config_file(
3009
3009
 
3010
3010
  ret.append("#\033[36m closed{}\033[0m".format(ipath))
3011
3011
 
3012
+ zsl = []
3013
+ for ln in ret:
3014
+ zs = ln.split(" #")[0]
3015
+ if " #" in zs and zs.split("#")[0].strip():
3016
+ zsl.append(ln)
3017
+ if zsl and "no-cfg-cmt-warn" not in "\n".join(ret):
3018
+ t = "\033[33mWARNING: there is less than two spaces before the # in the following config lines, so instead of assuming that this is a comment, the whole line will become part of the config value:\n\n>>> %s\n\nif you are familiar with this and would like to mute this warning, specify the global-option no-cfg-cmt-warn\n\033[0m"
3019
+ t = t % ("\n>>> ".join(zsl),)
3020
+ if log:
3021
+ log(t)
3022
+ else:
3023
+ print(t, file=sys.stderr)
3024
+
3012
3025
 
3013
3026
  def upgrade_cfg_fmt(
3014
3027
  log , args , orig , cfg_fp
@@ -36,14 +36,14 @@ class Fstab(object):
36
36
  self.cache = {}
37
37
 
38
38
  fs = "ext4"
39
- msg = "failed to determine filesystem at [{}]; assuming {}\n{}"
39
+ msg = "failed to determine filesystem at %r; assuming %s\n%s"
40
40
 
41
41
  if ANYWIN:
42
42
  fs = "vfat"
43
43
  try:
44
44
  path = self._winpath(path)
45
45
  except:
46
- self.log(msg.format(path, fs, min_ex()), 3)
46
+ self.log(msg % (path, fs, min_ex()), 3)
47
47
  return fs
48
48
 
49
49
  path = undot(path)
@@ -55,11 +55,11 @@ class Fstab(object):
55
55
  try:
56
56
  fs = self.get_w32(path) if ANYWIN else self.get_unix(path)
57
57
  except:
58
- self.log(msg.format(path, fs, min_ex()), 3)
58
+ self.log(msg % (path, fs, min_ex()), 3)
59
59
 
60
60
  fs = fs.lower()
61
61
  self.cache[path] = fs
62
- self.log("found {} at {}".format(fs, path))
62
+ self.log("found %s at %r" % (fs, path))
63
63
  return fs
64
64
 
65
65
  def _winpath(self, path ) :