mirror of
				https://github.com/9001/copyparty.git
				synced 2025-11-03 21:43:12 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			100 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			100 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env python3
 | 
						|
 | 
						|
"""
 | 
						|
unforget.py: rebuild db from logfiles
 | 
						|
2022-09-07, v0.1, ed <irc.rizon.net>, MIT-Licensed
 | 
						|
https://github.com/9001/copyparty/blob/hovudstraum/bin/unforget.py
 | 
						|
 | 
						|
only makes sense if running copyparty with --no-forget
 | 
						|
(e.g. immediately shifting uploads to other storage)
 | 
						|
 | 
						|
usage:
 | 
						|
  xz -d < log | ./unforget.py .hist/up2k.db
 | 
						|
 | 
						|
"""
 | 
						|
 | 
						|
import re
 | 
						|
import sys
 | 
						|
import json
 | 
						|
import base64
 | 
						|
import sqlite3
 | 
						|
import argparse
 | 
						|
 | 
						|
 | 
						|
FS_ENCODING = sys.getfilesystemencoding()
 | 
						|
 | 
						|
 | 
						|
class APF(argparse.ArgumentDefaultsHelpFormatter, argparse.RawDescriptionHelpFormatter):
 | 
						|
    pass
 | 
						|
 | 
						|
 | 
						|
mem_cur = sqlite3.connect(":memory:").cursor()
 | 
						|
mem_cur.execute(r"create table a (b text)")
 | 
						|
 | 
						|
 | 
						|
def s3enc(rd: str, fn: str) -> tuple[str, str]:
 | 
						|
    ret: list[str] = []
 | 
						|
    for v in [rd, fn]:
 | 
						|
        try:
 | 
						|
            mem_cur.execute("select * from a where b = ?", (v,))
 | 
						|
            ret.append(v)
 | 
						|
        except:
 | 
						|
            wtf8 = v.encode(FS_ENCODING, "surrogateescape")
 | 
						|
            ret.append("//" + base64.urlsafe_b64encode(wtf8).decode("ascii"))
 | 
						|
 | 
						|
    return ret[0], ret[1]
 | 
						|
 | 
						|
 | 
						|
def main():
 | 
						|
    ap = argparse.ArgumentParser()
 | 
						|
    ap.add_argument("db")
 | 
						|
    ar = ap.parse_args()
 | 
						|
 | 
						|
    db = sqlite3.connect(ar.db).cursor()
 | 
						|
    ptn_times = re.compile(r"no more chunks, setting times \(([0-9]+)")
 | 
						|
    at = 0
 | 
						|
    ctr = 0
 | 
						|
 | 
						|
    for ln in [x.decode("utf-8", "replace").rstrip() for x in sys.stdin.buffer]:
 | 
						|
        if "no more chunks, setting times (" in ln:
 | 
						|
            m = ptn_times.search(ln)
 | 
						|
            if m:
 | 
						|
                at = int(m.group(1))
 | 
						|
 | 
						|
        if '"hash": []' in ln:
 | 
						|
            try:
 | 
						|
                ofs = ln.find("{")
 | 
						|
                j = json.loads(ln[ofs:])
 | 
						|
            except:
 | 
						|
                pass
 | 
						|
 | 
						|
            w = j["wark"]
 | 
						|
            if db.execute("select w from up where w = ?", (w,)).fetchone():
 | 
						|
                continue
 | 
						|
 | 
						|
            # PYTHONPATH=/home/ed/dev/copyparty/ python3 -m copyparty -e2dsa  -v foo:foo:rwmd,ed -aed:wark --no-forget
 | 
						|
            # 05:34:43.845 127.0.0.1 42496       no more chunks, setting times (1662528883, 1658001882)
 | 
						|
            # 05:34:43.863 127.0.0.1 42496       {"name": "f\"2", "purl": "/foo/bar/baz/", "size": 1674, "lmod": 1658001882, "sprs": true, "hash": [], "wark": "LKIWpp2jEAh9dH3fu-DobuURFGEKlODXDGTpZ1otMhUg"}
 | 
						|
            # |                      w                       |     mt     |  sz  |   rd    | fn  |    ip     |     at     |
 | 
						|
            # | LKIWpp2jEAh9dH3fu-DobuURFGEKlODXDGTpZ1otMhUg | 1658001882 | 1674 | bar/baz | f"2 | 127.0.0.1 | 1662528883 |
 | 
						|
 | 
						|
            rd, fn = s3enc(j["purl"].strip("/"), j["name"])
 | 
						|
            ip = ln.split(" ")[1].split("m")[-1]
 | 
						|
 | 
						|
            q = "insert into up values (?,?,?,?,?,?,?)"
 | 
						|
            v = (w, int(j["lmod"]), int(j["size"]), rd, fn, ip, at)
 | 
						|
            db.execute(q, v)
 | 
						|
            ctr += 1
 | 
						|
            if ctr % 1024 == 1023:
 | 
						|
                print(f"{ctr} commit...")
 | 
						|
                db.connection.commit()
 | 
						|
 | 
						|
    if ctr:
 | 
						|
        db.connection.commit()
 | 
						|
 | 
						|
    print(f"unforgot {ctr} files")
 | 
						|
 | 
						|
 | 
						|
if __name__ == "__main__":
 | 
						|
    main()
 |