Skip to content

Commit e43e446

Browse files
zmiany
poprawki wizualne i techniczne
1 parent 93b8c29 commit e43e446

File tree

8 files changed

+1687
-232
lines changed

8 files changed

+1687
-232
lines changed

cli/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ function getCurrentRepoName() {
2222
if (process.env.REPO_NAME && process.env.REPO_NAME.trim() !== "") {
2323
return process.env.REPO_NAME.trim();
2424
}
25-
// W przeciwnym razie nazwa bieżącego katalogu (lokalnie)
25+
// W przeciwnym razie - nazwa bieżącego katalogu (lokalnie)
2626
return path.basename(process.cwd());
2727
}
2828

@@ -399,13 +399,13 @@ Autor: Paffcio
399399
// === HELP ===
400400
program
401401
.name("mygit")
402-
.description("🧠 mygit lokalny system wersjonowania od Paffcia 💾")
402+
.description("🧠 mygit - lokalny system wersjonowania od Paffcia 💾")
403403
.version("1.0.0");
404404

405405
program.action(() => {
406406
console.log(`
407407
╭────────────────────────────────────╮
408-
│ 🧠 mygit system wersjonowania │
408+
│ 🧠 mygit - system wersjonowania │
409409
╰────────────────────────────────────╯
410410
Użycie:
411411
mygit <komenda> [argumenty]

core/repoManager.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ export async function deleteCommit(repoId, commitFile) {
132132
// Usuń plik .zip
133133
await fs.remove(commitPath);
134134

135-
// Zaktualizuj commits.json — usuń wpis
135+
// Zaktualizuj commits.json
136136
const commFile = path.join(repoDir, "commits.json");
137137
const commits = (await fs.pathExists(commFile)) ? await fs.readJson(commFile) : [];
138138
const keep = commits.filter(c => path.basename(c.file) !== path.basename(commitPath));

screenshots/1.png

93 Bytes
Loading

screenshots/4.png

79.3 KB
Loading

screenshots/5.png

90.2 KB
Loading

screenshots/6.png

77.5 KB
Loading

server.mjs

Lines changed: 175 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,33 @@ console.log(" Data dir:", path.join(PROJECT_ROOT, "data"));
4848
const dataDir = path.join(PROJECT_ROOT, "data");
4949
await fs.ensureDir(path.join(dataDir, "repos"));
5050

51+
// Ścieżka do pliku z ulubionymi
52+
const favouritesPath = path.join(dataDir, "favourites.json");
53+
54+
// Inicjalizacja pliku z ulubionymi jeśli nie istnieje
55+
if (!(await fs.pathExists(favouritesPath))) {
56+
await fs.writeJson(favouritesPath, { favourites: [] });
57+
}
58+
59+
// Funkcje do zarządzania ulubionymi
60+
async function loadFavourites() {
61+
try {
62+
const data = await fs.readJson(favouritesPath);
63+
return data.favourites || [];
64+
} catch (error) {
65+
console.error("Błąd ładowania ulubionych:", error);
66+
return [];
67+
}
68+
}
69+
70+
async function saveFavourites(favourites) {
71+
try {
72+
await fs.writeJson(favouritesPath, { favourites }, { spaces: 2 });
73+
} catch (error) {
74+
console.error("Błąd zapisywania ulubionych:", error);
75+
}
76+
}
77+
5178
// === TRASY INTERFEJSU WEB ===
5279
app.get("/", (req, res) => {
5380
const indexPath = path.join(PROJECT_ROOT, "web", "index.html");
@@ -104,11 +131,61 @@ app.use('/api/repos/:id/info', (req, res, next) => {
104131

105132
// === API ROUTES ===
106133

107-
// Lista repozytoriów
134+
// Lista repozytoriów (z ulubionymi)
108135
app.get("/api/repos", async (req, res) => {
109136
try {
110137
const repos = await listRepos();
111-
res.json(repos);
138+
const favourites = await loadFavourites();
139+
140+
// Dodaj flagę isFavourite do każdego repozytorium
141+
const reposWithFavourites = repos.map(repo => ({
142+
...repo,
143+
isFavourite: favourites.includes(repo.id)
144+
}));
145+
146+
res.json(reposWithFavourites);
147+
} catch (e) {
148+
res.status(500).json({ error: e.message });
149+
}
150+
});
151+
152+
// Pobierz ulubione
153+
app.get("/api/favourites", async (req, res) => {
154+
try {
155+
const favourites = await loadFavourites();
156+
res.json({ favourites });
157+
} catch (e) {
158+
res.status(500).json({ error: e.message });
159+
}
160+
});
161+
162+
// Dodaj do ulubionych
163+
app.post("/api/favourites/:id", async (req, res) => {
164+
try {
165+
const repoId = req.params.id;
166+
const favourites = await loadFavourites();
167+
168+
if (!favourites.includes(repoId)) {
169+
favourites.push(repoId);
170+
await saveFavourites(favourites);
171+
}
172+
173+
res.json({ success: true, favourites });
174+
} catch (e) {
175+
res.status(500).json({ error: e.message });
176+
}
177+
});
178+
179+
// Usuń z ulubionych
180+
app.delete("/api/favourites/:id", async (req, res) => {
181+
try {
182+
const repoId = req.params.id;
183+
let favourites = await loadFavourites();
184+
185+
favourites = favourites.filter(id => id !== repoId);
186+
await saveFavourites(favourites);
187+
188+
res.json({ success: true, favourites });
112189
} catch (e) {
113190
res.status(500).json({ error: e.message });
114191
}
@@ -222,10 +299,17 @@ app.delete("/api/repos/:id/commit/:file", async (req, res) => {
222299
// Usuwanie repo
223300
app.delete("/api/repos/:id", async (req, res) => {
224301
try {
225-
const repoDir = path.join(dataDir, "repos", req.params.id);
302+
const repoId = req.params.id;
303+
const repoDir = path.join(dataDir, "repos", repoId);
226304
if (!(await fs.pathExists(repoDir))) {
227305
return res.status(404).json({ error: "Repozytorium nie istnieje." });
228306
}
307+
308+
// Usuń również z ulubionych
309+
const favourites = await loadFavourites();
310+
const newFavourites = favourites.filter(id => id !== repoId);
311+
await saveFavourites(newFavourites);
312+
229313
await fs.remove(repoDir);
230314
res.json({ success: true });
231315
} catch (e) {
@@ -420,6 +504,53 @@ app.get("*", (req, res) => {
420504
res.sendFile(indexPath);
421505
});
422506

507+
// Sprawdź czy plik jest tekstowy
508+
app.get("/api/repos/:id/checkfile/:commitFile/:filePath(*)", async (req, res) => {
509+
try {
510+
const { id, commitFile, filePath } = req.params;
511+
const zipPath = path.join(dataDir, "repos", id, "versions", commitFile);
512+
513+
if (!(await fs.pathExists(zipPath))) {
514+
return res.status(404).json({ error: "Snapshot nie istnieje." });
515+
}
516+
517+
const zip = new AdmZip(zipPath);
518+
const entry = zip.getEntry(filePath);
519+
520+
if (!entry) {
521+
return res.status(404).json({ error: "Plik nie istnieje w archiwum." });
522+
}
523+
524+
// Sprawdź czy plik jest tekstowy
525+
const isText = isTextFile(filePath);
526+
527+
// Możemy też spróbować sprawdzić zawartość
528+
let isContentText = false;
529+
try {
530+
const data = entry.getData();
531+
// Próbujemy odczytać jako tekst UTF-8
532+
const text = data.toString('utf8');
533+
// Sprawdzamy czy zawiera znaki kontrolne (oprócz typowych dla tekstu)
534+
const controlChars = text.split('').filter(c => {
535+
const code = c.charCodeAt(0);
536+
return (code < 32 && code !== 9 && code !== 10 && code !== 13) || code === 127;
537+
}).length;
538+
isContentText = controlChars / text.length < 0.1; // Mniej niż 10% znaków kontrolnych
539+
} catch (e) {
540+
isContentText = false;
541+
}
542+
543+
res.json({
544+
isText,
545+
isContentText,
546+
size: entry.header.size,
547+
filename: path.basename(filePath)
548+
});
549+
} catch (err) {
550+
res.status(500).json({ error: "Błąd sprawdzania pliku: " + err.message });
551+
}
552+
});
553+
423554
// Pomocnicze funkcje
424555
function getContentType(filename) {
425556
const ext = path.extname(filename).toLowerCase();
@@ -445,8 +576,46 @@ function getContentType(filename) {
445576

446577
function isTextFile(filename) {
447578
const ext = path.extname(filename).toLowerCase();
448-
const textExtensions = ['.txt', '.js', '.json', '.html', '.css', '.md', '.xml', '.yml', '.yaml', '.php', '.py', '.java', '.c', '.cpp', '.h', '.cs', '.rb', '.go', '.rs', '.ts', '.jsx', '.tsx', '.vue', '.svelte'];
449-
return textExtensions.includes(ext);
579+
const textExtensions = [
580+
'.txt', '.js', '.json', '.html', '.css', '.md', '.xml', '.yml', '.yaml',
581+
'.php', '.py', '.java', '.c', '.cpp', '.h', '.cs', '.rb', '.go', '.rs',
582+
'.ts', '.jsx', '.tsx', '.vue', '.svelte', '.sql', '.ini', '.cfg', '.conf',
583+
'.log', '.sh', '.bash', '.zsh', '.fish', '.mjs', '.cjs', '.env', '.gitignore',
584+
'.dockerignore', '.editorconfig', '.prettierrc', '.eslintrc', '.babelrc',
585+
'.npmrc', '.yarnrc', '.gitattributes', '.gitmodules', '.htaccess', '.env.example',
586+
'.env.local', '.env.development', '.env.production', '.env.test'
587+
];
588+
589+
// Sprawdź po rozszerzeniu
590+
if (textExtensions.includes(ext)) {
591+
return true;
592+
}
593+
594+
// Sprawdź czy to plik ukryty (z kropką na początku nazwy)
595+
const fileName = path.basename(filename).toLowerCase();
596+
if (fileName.startsWith('.') && fileName.length > 1) {
597+
// Wyjątek: niektóre pliki binarne mogą mieć kropkę, ale są binarne
598+
const binaryHiddenFiles = ['.DS_Store', '.localized'];
599+
if (binaryHiddenFiles.includes(fileName)) {
600+
return false;
601+
}
602+
return true;
603+
}
604+
605+
// Sprawdź czy to znany plik tekstowy bez rozszerzenia
606+
const knownTextFiles = [
607+
'dockerfile', 'makefile', 'procfile', 'docker-compose.yml', 'docker-compose.yaml',
608+
'docker-compose.override.yml', 'package.json', 'package-lock.json', 'yarn.lock',
609+
'composer.json', 'composer.lock', 'gemfile', 'gemfile.lock', 'cargo.toml',
610+
'cargo.lock', 'go.mod', 'go.sum', 'pom.xml', 'build.gradle', 'build.gradle.kts',
611+
'settings.gradle', 'settings.gradle.kts', 'gradle.properties', 'gradle-wrapper.properties'
612+
];
613+
614+
if (knownTextFiles.includes(fileName)) {
615+
return true;
616+
}
617+
618+
return false;
450619
}
451620

452621
// === Start serwera ===
@@ -467,5 +636,6 @@ app.listen(PORT, "0.0.0.0", () => {
467636
console.log("\n🚀 mygit uruchomiony!");
468637
console.log(`🌍 http://${localIp}:${PORT}`);
469638
console.log(`📁 Katalog danych: ${dataDir}/repos/`);
639+
console.log(`💖 Plik ulubionych: ${favouritesPath}`);
470640
console.log(`🕓 Start: ${dayjs().format("DD.MM.YYYY | HH:mm:ss")}\n`);
471641
});

0 commit comments

Comments
 (0)