-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbackground.js
More file actions
225 lines (192 loc) · 7.51 KB
/
Copy pathbackground.js
File metadata and controls
225 lines (192 loc) · 7.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
// background.js - Background script for handling saves
console.log("Crates Packer background script loaded");
// Default save format
const DEFAULT_SAVE_FORMAT = 'toml'; // or 'json', 'text'
// Generate TOML content from crates
function generateTOML(crates) {
let toml = '# Crates.io Saved Packages\n';
toml += '# Generated by Crates Packer Extension\n';
toml += `# Last updated: ${new Date().toISOString()}\n\n`;
crates.forEach(crate => {
toml += `[[package]]\n`;
toml += `name = "${crate.name}"\n`;
toml += `version = "${crate.version}"\n`;
toml += `description = """${crate.description}"""\n`;
toml += `dependencies = ${crate.dependencies}\n`;
toml += `updated = "${crate.updated}"\n`;
toml += `url = "${crate.url}"\n`;
toml += `saved = "${crate.timestamp}"\n\n`;
});
return toml;
}
// Generate JSON content
function generateJSON(crates) {
return JSON.stringify({
meta: {
generated: new Date().toISOString(),
count: crates.length,
source: "Crates Packer Extension"
},
packages: crates
}, null, 2);
}
// Generate plain text content
function generateText(crates) {
let text = `Crates.io Saved Packages\n`;
text += `Generated: ${new Date().toISOString()}\n`;
text += `Total: ${crates.length} packages\n\n`;
crates.forEach((crate, index) => {
text += `${index + 1}. ${crate.name} @ ${crate.version}\n`;
text += ` Description: ${crate.description}\n`;
text += ` Dependencies: ${crate.dependencies}\n`;
text += ` Updated: ${crate.updated}\n`;
text += ` URL: ${crate.url}\n`;
text += ` Saved: ${crate.timestamp}\n\n`;
});
return text;
}
// Save crates to file
async function saveCratesToFile(crates, format = DEFAULT_SAVE_FORMAT) {
let content;
let filename;
switch(format.toLowerCase()) {
case 'toml':
content = generateTOML(crates);
filename = `crates-${new Date().toISOString().split('T')[0]}.toml`;
break;
case 'json':
content = generateJSON(crates);
filename = `crates-${new Date().toISOString().split('T')[0]}.json`;
break;
case 'text':
default:
content = generateText(crates);
filename = `crates-${new Date().toISOString().split('T')[0]}.txt`;
}
// Convert to blob
const blob = new Blob([content], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
// Download the file
try {
await browser.downloads.download({
url: url,
filename: `crates-io/${filename}`,
saveAs: false, // Auto-save to downloads folder
conflictAction: 'overwrite' // Overwrite previous file
});
console.log(`Saved ${crates.length} crates to ${filename}`);
return { success: true, filename, count: crates.length };
} catch (error) {
console.error("Download error:", error);
return { success: false, error: error.message };
} finally {
// Clean up the blob URL
setTimeout(() => URL.revokeObjectURL(url), 1000);
}
}
// Get all saved crates from storage
async function getSavedCrates() {
const result = await browser.storage.local.get('savedCrates');
return result.savedCrates || [];
}
// Save a single crate to storage
async function saveCrateToStorage(crateInfo) {
try {
// Get existing crates
const savedCrates = await getSavedCrates();
// Check if crate already exists
const existingIndex = savedCrates.findIndex(c =>
c.name === crateInfo.name && c.version === crateInfo.version
);
if (existingIndex >= 0) {
// Update existing entry
savedCrates[existingIndex] = {
...savedCrates[existingIndex],
...crateInfo,
timestamp: new Date().toISOString() // Update timestamp
};
console.log(`Updated existing crate: ${crateInfo.name}`);
} else {
// Add new crate
savedCrates.push(crateInfo);
console.log(`Added new crate: ${crateInfo.name}`);
}
// Save back to storage
await browser.storage.local.set({ savedCrates });
// Get auto-save setting
const settings = await browser.storage.local.get(['autoSave', 'saveFormat']);
// Auto-save to file if enabled
if (settings.autoSave) {
const format = settings.saveFormat || DEFAULT_SAVE_FORMAT;
await saveCratesToFile(savedCrates, format);
}
return {
success: true,
action: existingIndex >= 0 ? 'updated' : 'added',
count: savedCrates.length,
crate: crateInfo
};
} catch (error) {
console.error("Storage error:", error);
return { success: false, error: error.message };
}
}
// Listen for messages from content script and popup
browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
console.log("Background received:", message);
if (message.action === "saveCrate") {
// Save the crate and respond
saveCrateToStorage(message.crate)
.then(response => sendResponse(response))
.catch(error => sendResponse({ success: false, error: error.message }));
return true; // Keep message channel open for async response
}
if (message.action === "getSavedCrates") {
getSavedCrates()
.then(crates => sendResponse({ success: true, crates }))
.catch(error => sendResponse({ success: false, error: error.message }));
return true;
}
if (message.action === "exportCrates") {
const format = message.format || DEFAULT_SAVE_FORMAT;
getSavedCrates()
.then(crates => saveCratesToFile(crates, format))
.then(result => sendResponse(result))
.catch(error => sendResponse({ success: false, error: error.message }));
return true;
}
if (message.action === "clearCrates") {
browser.storage.local.remove('savedCrates')
.then(() => sendResponse({ success: true }))
.catch(error => sendResponse({ success: false, error: error.message }));
return true;
}
if (message.action === "getSettings") {
browser.storage.local.get(['autoSave', 'saveFormat', 'lastExport'])
.then(settings => sendResponse({ success: true, settings }))
.catch(error => sendResponse({ success: false, error: error.message }));
return true;
}
if (message.action === "saveSettings") {
browser.storage.local.set(message.settings)
.then(() => sendResponse({ success: true }))
.catch(error => sendResponse({ success: false, error: error.message }));
return true;
}
// Return false if we don't handle the message
return false;
});
// Initialize default settings if not exist
async function initializeSettings() {
const result = await browser.storage.local.get(['autoSave', 'saveFormat']);
if (result.autoSave === undefined) {
await browser.storage.local.set({
autoSave: true, // Enable auto-save by default
saveFormat: 'toml'
});
console.log("Initialized default settings");
}
}
// Initialize on load
initializeSettings();
console.log("Crates Packer background script ready!");