Live video on the AT Protocol
79
fork

Configure Feed

Select the types of activity you want to include in your feed.

at natb/blur-objectionable-content 149 lines 3.1 kB view raw
1package remote 2 3import ( 4 "archive/tar" 5 "compress/gzip" 6 "crypto/sha256" 7 "encoding/hex" 8 "fmt" 9 "io" 10 "net/http" 11 "os" 12 "path/filepath" 13 "strings" 14) 15 16// Streamplace team can add new files here with hack/upload-fixture.sh 17 18var fixtureURL = "https://storage.googleapis.com/streamplace-fixtures" 19 20func RemoteFixture(name string) string { 21 parts := strings.Split(name, "/") 22 if len(parts) != 2 { 23 panic("fixture name must be in format HASH/FILENAME") 24 } 25 expectedHash := parts[0] 26 filename := parts[1] 27 28 // Check if file already exists in cache 29 homeDir, err := os.UserHomeDir() 30 if err != nil { 31 panic(err) 32 } 33 cacheDir := filepath.Join(homeDir, ".streamplace-test-cache") 34 finalPath := filepath.Join(cacheDir, expectedHash, filename) 35 if _, err := os.Stat(finalPath); err == nil { 36 return finalPath 37 } 38 39 // Create temp dir if it doesn't exist 40 if err := os.MkdirAll(cacheDir, 0755); err != nil { 41 panic(err) 42 } 43 44 // Download to temporary file 45 resp, err := http.Get(fixtureURL + "/" + name) 46 if err != nil { 47 panic(err) 48 } 49 defer resp.Body.Close() 50 51 tmpFile, err := os.CreateTemp(cacheDir, "download-*") 52 if err != nil { 53 panic(err) 54 } 55 tmpPath := tmpFile.Name() 56 defer os.Remove(tmpPath) 57 58 // Calculate hash while downloading 59 hash := sha256.New() 60 writer := io.MultiWriter(tmpFile, hash) 61 62 if _, err := io.Copy(writer, resp.Body); err != nil { 63 panic(err) 64 } 65 tmpFile.Close() 66 67 // Verify hash 68 actualHash := hex.EncodeToString(hash.Sum(nil)) 69 if actualHash != expectedHash { 70 panic(fmt.Sprintf("hash mismatch: expected %s, got %s", expectedHash, actualHash)) 71 } 72 73 // Move to final location 74 finalDir := filepath.Join(cacheDir, expectedHash) 75 if err := os.MkdirAll(finalDir, 0755); err != nil { 76 panic(err) 77 } 78 79 if err := os.Rename(tmpPath, finalPath); err != nil { 80 panic(err) 81 } 82 83 return finalPath 84} 85 86// takes a tarball, returns a directory with the contents 87func RemoteArchive(name string) string { 88 fpath := RemoteFixture(name) 89 90 // Create extracted directory adjacent to the archive file 91 dir := filepath.Dir(fpath) 92 extractedDir := filepath.Join(dir, "extracted") 93 94 if err := os.MkdirAll(extractedDir, 0755); err != nil { 95 panic(err) 96 } 97 98 // Extract the tarball contents into the directory 99 file, err := os.Open(fpath) 100 if err != nil { 101 panic(err) 102 } 103 defer file.Close() 104 105 // Create gzip reader 106 gzr, err := gzip.NewReader(file) 107 if err != nil { 108 panic(err) 109 } 110 defer gzr.Close() 111 112 tr := tar.NewReader(gzr) 113 for { 114 header, err := tr.Next() 115 if err == io.EOF { 116 break 117 } 118 if err != nil { 119 panic(err) 120 } 121 122 target := filepath.Join(extractedDir, header.Name) 123 124 switch header.Typeflag { 125 case tar.TypeDir: 126 if err := os.MkdirAll(target, 0755); err != nil { 127 panic(err) 128 } 129 case tar.TypeReg: 130 // Create parent directories if needed 131 if err := os.MkdirAll(filepath.Dir(target), 0755); err != nil { 132 panic(err) 133 } 134 135 outFile, err := os.Create(target) 136 if err != nil { 137 panic(err) 138 } 139 140 if _, err := io.Copy(outFile, tr); err != nil { 141 outFile.Close() 142 panic(err) 143 } 144 outFile.Close() 145 } 146 } 147 148 return extractedDir 149}