Files
navi/tools/fillstore/shots.go
T
NavisandCursor 50f7f71393 Add site contacts/FAQ and accept AWG 2.0 / naive pastes in Add config.
ImportSubscription no longer requires only http(s): paste awg://, AWG .conf/JSON, or naive links; subscription parser also reads hosted AWG and Clash wireguard/naive. Site lists support emails and FAQ; Store listing texts/tools updated.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-02 15:40:13 +03:00

186 lines
4.8 KiB
Go

package main
import (
"encoding/csv"
"fmt"
"os"
"path/filepath"
"strings"
)
func setField(all [][]string, header []string, field, col, value string) {
colIdx := -1
for i, h := range header {
if h == col {
colIdx = i
break
}
}
if colIdx < 0 {
panic(col)
}
for i := 1; i < len(all); i++ {
for len(all[i]) < len(header) {
all[i] = append(all[i], "")
}
if all[i][0] == field {
all[i][colIdx] = value
return
}
}
panic("missing " + field)
}
func getField(all [][]string, header []string, field, col string) string {
colIdx := -1
for i, h := range header {
if h == col {
colIdx = i
break
}
}
for i := 1; i < len(all); i++ {
if len(all[i]) > 0 && all[i][0] == field && colIdx >= 0 && colIdx < len(all[i]) {
return all[i][colIdx]
}
}
return ""
}
func main() {
root := `D:\vpn navi`
path := filepath.Join(root, "store.csv")
f, err := os.Open(path)
if err != nil {
panic(err)
}
r := csv.NewReader(f)
r.FieldsPerRecord = -1
r.LazyQuotes = true
all, err := r.ReadAll()
f.Close()
if err != nil {
panic(err)
}
header := all[0]
// Relative paths for Partner Center: upload folder with store.csv + screen/
ruShots := []string{
"screen/1.ru.png",
"screen/2.ru.png",
"screen/3.ru.png",
"screen/4.ru.png",
"screen/5.ru.png",
"screen/6.ru.png",
"screen/12dark.png",
"screen/13dark.png",
"screen/14dark.png",
"screen/15dark.png",
"screen/16dark.png",
"screen/9.png",
}
enShots := []string{
"screen/7.en.png",
"screen/8.en.png",
"screen/9.png",
"screen/10.en.png",
"screen/11.en.png",
"screen/12dark.png",
"screen/13dark.png",
"screen/14dark.png",
"screen/15dark.png",
"screen/16dark.png",
}
ruCaptions := [][2]string{
{"Главный экран: подключение и статус защиты", "Home: connect and protection status"},
{"Список серверов с флагами и пингом", "Server list with flags and ping"},
{"Настройки: тема, язык, Kill Switch", "Settings: theme, language, Kill Switch"},
{"Статистика использования", "Usage statistics"},
{"Помощь и полезные ссылки", "Help and useful links"},
{"Добавление конфигурации", "Add configuration"},
{"Тёмная тема: главный экран", "Dark theme: home"},
{"Тёмная тема: серверы", "Dark theme: servers"},
{"Тёмная тема: настройки", "Dark theme: settings"},
{"Тёмная тема: статистика", "Dark theme: statistics"},
{"Тёмная тема: помощь", "Dark theme: help"},
{"Общий вид приложения", "App overview"},
}
enCaptions := []string{
"Home: connect and protection status",
"Server list with flags and ping",
"App overview",
"Settings: theme, language, Kill Switch",
"Statistics and help",
"Dark theme: home",
"Dark theme: servers",
"Dark theme: settings",
"Dark theme: statistics",
"Dark theme: help",
}
for i, p := range ruShots {
setField(all, header, fmt.Sprintf("DesktopScreenshot%d", i+1), "default", p)
}
for i, p := range enShots {
setField(all, header, fmt.Sprintf("DesktopScreenshot%d", i+1), "en", p)
}
// Clear en slots beyond enShots so Partner Center falls back to default for RU-only extras
for i := len(enShots); i < 30; i++ {
setField(all, header, fmt.Sprintf("DesktopScreenshot%d", i+1), "en", "")
}
// Clear default slots beyond ruShots
for i := len(ruShots); i < 30; i++ {
setField(all, header, fmt.Sprintf("DesktopScreenshot%d", i+1), "default", "")
}
for i, c := range ruCaptions {
field := fmt.Sprintf("DesktopScreenshotCaption%d", i+1)
setField(all, header, field, "default", c[0])
en := c[1]
if i < len(enCaptions) {
en = enCaptions[i]
}
setField(all, header, field, "en", en)
}
for i := len(ruCaptions); i < 30; i++ {
field := fmt.Sprintf("DesktopScreenshotCaption%d", i+1)
setField(all, header, field, "default", "")
setField(all, header, field, "en", "")
}
out, err := os.Create(path)
if err != nil {
panic(err)
}
if _, err := out.Write([]byte{0xEF, 0xBB, 0xBF}); err != nil {
panic(err)
}
w := csv.NewWriter(out)
if err := w.WriteAll(all); err != nil {
panic(err)
}
w.Flush()
out.Close()
for i := 1; i <= 12; i++ {
d := getField(all, header, fmt.Sprintf("DesktopScreenshot%d", i), "default")
e := getField(all, header, fmt.Sprintf("DesktopScreenshot%d", i), "en")
if d == "" && e == "" {
continue
}
fmt.Printf("%d default=%s en=%s\n", i, d, e)
for _, p := range []string{d, e} {
if p == "" {
continue
}
full := filepath.Join(root, filepath.FromSlash(p))
if _, err := os.Stat(full); err != nil {
fmt.Println(" MISSING", full)
}
}
}
fmt.Println("updated", path, "rows", len(all))
_ = strings.TrimSpace
}