anscom 0.4.0__tar.gz

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.
anscom-0.4.0/PKG-INFO ADDED
@@ -0,0 +1,60 @@
1
+ Metadata-Version: 2.4
2
+ Name: anscom
3
+ Version: 0.4.0
4
+ Summary: A fast native C recursive file scanner and analyzer
5
+ Home-page: https://github.com/PC5518
6
+ Author: Aditya Narayan Singh
7
+ Author-email: adityansdsdc@outlook.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: C
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.6
13
+ Description-Content-Type: text/markdown
14
+ Dynamic: author
15
+ Dynamic: author-email
16
+ Dynamic: classifier
17
+ Dynamic: description
18
+ Dynamic: description-content-type
19
+ Dynamic: home-page
20
+ Dynamic: requires-python
21
+ Dynamic: summary
22
+
23
+ # Anscom
24
+
25
+ **Anscom** is a high-performance, native C extension for Python that recursively scans directories and categorizes files with blazingly fast speed.
26
+
27
+ ## Features
28
+ - **Native C Speed:** Written in pure C (C89 compliant).
29
+ - **Visual Tree:** Prints a diagrammatic folder tree in the terminal.
30
+ - **Detailed Analysis:** Breakdowns by category and specific file extensions.
31
+ - **Cross-Platform:** Works on Windows, Linux, and macOS.
32
+
33
+ ## Installation
34
+ ```bash
35
+ pip install anscom
36
+
37
+
38
+
39
+ Usage
40
+ code
41
+ Python
42
+ import anscom
43
+
44
+ # Scan the current directory
45
+ anscom.scan(".")
46
+
47
+ # Scan a specific path
48
+ anscom.scan("C:/Users/Documents")
49
+ code
50
+ Code
51
+ ---
52
+
53
+ ### Step 2: Create a `MANIFEST.in`
54
+ When you package C modules, Python needs to know exactly which source files to include. Create a file named `MANIFEST.in`:
55
+
56
+ ```text
57
+ include *.c
58
+ include *.h
59
+ include LICENSE
60
+ include README.md
anscom-0.4.0/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # Anscom
2
+
3
+ **Anscom** is a high-performance, native C extension for Python that recursively scans directories and categorizes files with blazingly fast speed.
4
+
5
+ ## Features
6
+ - **Native C Speed:** Written in pure C (C89 compliant).
7
+ - **Visual Tree:** Prints a diagrammatic folder tree in the terminal.
8
+ - **Detailed Analysis:** Breakdowns by category and specific file extensions.
9
+ - **Cross-Platform:** Works on Windows, Linux, and macOS.
10
+
11
+ ## Installation
12
+ ```bash
13
+ pip install anscom
14
+
15
+
16
+
17
+ Usage
18
+ code
19
+ Python
20
+ import anscom
21
+
22
+ # Scan the current directory
23
+ anscom.scan(".")
24
+
25
+ # Scan a specific path
26
+ anscom.scan("C:/Users/Documents")
27
+ code
28
+ Code
29
+ ---
30
+
31
+ ### Step 2: Create a `MANIFEST.in`
32
+ When you package C modules, Python needs to know exactly which source files to include. Create a file named `MANIFEST.in`:
33
+
34
+ ```text
35
+ include *.c
36
+ include *.h
37
+ include LICENSE
38
+ include README.md
anscom-0.4.0/anscom.c ADDED
@@ -0,0 +1,367 @@
1
+ /*
2
+ * anscom.c
3
+ *
4
+ * Version: v0.4 (The Analyst Edition)
5
+ * Description: Native Python extension with:
6
+ * 1. Visual Directory Tree Map
7
+ * 2. Category Summary
8
+ * 3. Detailed Extension Breakdown
9
+ *
10
+ * Compilation: python setup.py build_ext --inplace
11
+ */
12
+
13
+ #define PY_SSIZE_T_CLEAN
14
+ #include <Python.h>
15
+ #include <stdio.h>
16
+ #include <stdlib.h>
17
+ #include <string.h>
18
+ #include <ctype.h>
19
+
20
+ /* Cross-platform headers */
21
+ #ifdef _WIN32
22
+ #include <windows.h>
23
+ #define PATH_SEP '\\'
24
+ #else
25
+ #include <dirent.h>
26
+ #include <sys/stat.h>
27
+ #include <unistd.h>
28
+ #define PATH_SEP '/'
29
+ #endif
30
+
31
+ /* -------------------------------------------------------------------------
32
+ Data Structures
33
+ ------------------------------------------------------------------------- */
34
+
35
+ typedef enum {
36
+ CAT_CODE = 0,
37
+ CAT_DOCUMENT,
38
+ CAT_IMAGE,
39
+ CAT_VIDEO,
40
+ CAT_AUDIO,
41
+ CAT_ARCHIVE,
42
+ CAT_EXECUTABLE,
43
+ CAT_SYSTEM,
44
+ CAT_UNKNOWN,
45
+ CAT_COUNT
46
+ } FileCategory;
47
+
48
+ static const char* CAT_NAMES[CAT_COUNT] = {
49
+ "Code/Source", "Documents", "Images", "Videos", "Audio",
50
+ "Archives", "Executables", "System/Config", "Other/Unknown"
51
+ };
52
+
53
+ /*
54
+ * Modified Struct: Now holds a mutable 'count' for specific extensions
55
+ */
56
+ typedef struct {
57
+ char ext[16]; /* File extension string */
58
+ FileCategory category; /* General Category */
59
+ unsigned long long count; /* Specific counter for this extension */
60
+ } ExtMap;
61
+
62
+ /*
63
+ * MASTER EXTENSION DATABASE
64
+ * Note: Not 'const' anymore because we update the 'count' inside it.
65
+ */
66
+ static ExtMap EXTENSION_TABLE[] = {
67
+ {"3g2", CAT_VIDEO, 0}, {"3gp", CAT_VIDEO, 0}, {"7z", CAT_ARCHIVE, 0}, {"aac", CAT_AUDIO, 0},
68
+ {"accdb", CAT_DOCUMENT, 0}, {"ai", CAT_IMAGE, 0}, {"aif", CAT_AUDIO, 0}, {"apk", CAT_ARCHIVE, 0},
69
+ {"app", CAT_EXECUTABLE, 0}, {"asf", CAT_VIDEO, 0}, {"asm", CAT_CODE, 0}, {"asp", CAT_CODE, 0},
70
+ {"aspx", CAT_CODE, 0}, {"avi", CAT_VIDEO, 0}, {"avif", CAT_IMAGE, 0}, {"awk", CAT_CODE, 0},
71
+ {"bak", CAT_SYSTEM, 0}, {"bas", CAT_CODE, 0}, {"bat", CAT_CODE, 0}, {"bin", CAT_EXECUTABLE, 0},
72
+ {"bmp", CAT_IMAGE, 0}, {"bz2", CAT_ARCHIVE, 0}, {"c", CAT_CODE, 0}, {"cab", CAT_ARCHIVE, 0},
73
+ {"cbr", CAT_ARCHIVE, 0}, {"cc", CAT_CODE, 0}, {"cfg", CAT_SYSTEM, 0}, {"class", CAT_EXECUTABLE, 0},
74
+ {"cmd", CAT_CODE, 0}, {"cnf", CAT_SYSTEM, 0}, {"com", CAT_EXECUTABLE, 0}, {"conf", CAT_SYSTEM, 0},
75
+ {"cpp", CAT_CODE, 0}, {"cr2", CAT_IMAGE, 0}, {"crt", CAT_SYSTEM, 0}, {"cs", CAT_CODE, 0},
76
+ {"css", CAT_CODE, 0}, {"csv", CAT_DOCUMENT, 0}, {"cue", CAT_AUDIO, 0}, {"cur", CAT_IMAGE, 0},
77
+ {"dat", CAT_SYSTEM, 0}, {"db", CAT_SYSTEM, 0}, {"dbf", CAT_DOCUMENT, 0}, {"deb", CAT_ARCHIVE, 0},
78
+ {"dll", CAT_EXECUTABLE, 0}, {"dmg", CAT_ARCHIVE, 0}, {"doc", CAT_DOCUMENT, 0}, {"docx", CAT_DOCUMENT, 0},
79
+ {"dot", CAT_DOCUMENT, 0}, {"dotx", CAT_DOCUMENT, 0}, {"drw", CAT_IMAGE, 0}, {"dxf", CAT_IMAGE, 0},
80
+ {"ebook", CAT_DOCUMENT, 0}, {"elf", CAT_EXECUTABLE, 0}, {"eml", CAT_DOCUMENT, 0}, {"env", CAT_SYSTEM, 0},
81
+ {"eps", CAT_IMAGE, 0}, {"epub", CAT_DOCUMENT, 0}, {"exe", CAT_EXECUTABLE, 0}, {"flac", CAT_AUDIO, 0},
82
+ {"flv", CAT_VIDEO, 0}, {"fnt", CAT_SYSTEM, 0}, {"fon", CAT_SYSTEM, 0}, {"fth", CAT_CODE, 0},
83
+ {"gif", CAT_IMAGE, 0}, {"git", CAT_SYSTEM, 0}, {"gitignore", CAT_SYSTEM, 0}, {"go", CAT_CODE, 0},
84
+ {"gpg", CAT_SYSTEM, 0}, {"gradle", CAT_CODE, 0}, {"groovy", CAT_CODE, 0}, {"gz", CAT_ARCHIVE, 0},
85
+ {"h", CAT_CODE, 0}, {"heic", CAT_IMAGE, 0}, {"heif", CAT_IMAGE, 0}, {"hpp", CAT_CODE, 0},
86
+ {"htm", CAT_CODE, 0}, {"html", CAT_CODE, 0}, {"hwp", CAT_DOCUMENT, 0}, {"ico", CAT_IMAGE, 0},
87
+ {"ics", CAT_DOCUMENT, 0}, {"iff", CAT_IMAGE, 0}, {"img", CAT_ARCHIVE, 0}, {"indd", CAT_DOCUMENT, 0},
88
+ {"ini", CAT_SYSTEM, 0}, {"iso", CAT_ARCHIVE, 0}, {"jar", CAT_ARCHIVE, 0}, {"java", CAT_CODE, 0},
89
+ {"jpeg", CAT_IMAGE, 0}, {"jpg", CAT_IMAGE, 0}, {"js", CAT_CODE, 0}, {"json", CAT_CODE, 0},
90
+ {"jsp", CAT_CODE, 0}, {"jsx", CAT_CODE, 0}, {"key", CAT_DOCUMENT, 0}, {"kt", CAT_CODE, 0},
91
+ {"kts", CAT_CODE, 0}, {"less", CAT_CODE, 0}, {"log", CAT_SYSTEM, 0}, {"lua", CAT_CODE, 0},
92
+ {"m", CAT_CODE, 0}, {"m3u", CAT_AUDIO, 0}, {"m4a", CAT_AUDIO, 0}, {"m4v", CAT_VIDEO, 0},
93
+ {"mak", CAT_CODE, 0}, {"md", CAT_DOCUMENT, 0}, {"mdb", CAT_DOCUMENT, 0}, {"mid", CAT_AUDIO, 0},
94
+ {"midi", CAT_AUDIO, 0}, {"mkv", CAT_VIDEO, 0}, {"mm", CAT_CODE, 0}, {"mobi", CAT_DOCUMENT, 0},
95
+ {"mov", CAT_VIDEO, 0}, {"mp3", CAT_AUDIO, 0}, {"mp4", CAT_VIDEO, 0}, {"mpeg", CAT_VIDEO, 0},
96
+ {"mpg", CAT_VIDEO, 0}, {"msi", CAT_EXECUTABLE, 0}, {"nef", CAT_IMAGE, 0}, {"numbers", CAT_DOCUMENT, 0},
97
+ {"obj", CAT_SYSTEM, 0}, {"odp", CAT_DOCUMENT, 0}, {"ods", CAT_DOCUMENT, 0}, {"odt", CAT_DOCUMENT, 0},
98
+ {"ogg", CAT_AUDIO, 0}, {"ogv", CAT_VIDEO, 0}, {"orf", CAT_IMAGE, 0}, {"otf", CAT_SYSTEM, 0},
99
+ {"pages", CAT_DOCUMENT, 0}, {"pak", CAT_ARCHIVE, 0}, {"pas", CAT_CODE, 0}, {"pdf", CAT_DOCUMENT, 0},
100
+ {"pem", CAT_SYSTEM, 0}, {"php", CAT_CODE, 0}, {"pkg", CAT_ARCHIVE, 0}, {"pl", CAT_CODE, 0},
101
+ {"pm", CAT_CODE, 0}, {"png", CAT_IMAGE, 0}, {"ppt", CAT_DOCUMENT, 0}, {"pptx", CAT_DOCUMENT, 0},
102
+ {"ps", CAT_IMAGE, 0}, {"ps1", CAT_CODE, 0}, {"psd", CAT_IMAGE, 0}, {"pub", CAT_DOCUMENT, 0},
103
+ {"py", CAT_CODE, 0}, {"pyc", CAT_SYSTEM, 0}, {"pyd", CAT_EXECUTABLE, 0}, {"pyw", CAT_CODE, 0},
104
+ {"r", CAT_CODE, 0}, {"rar", CAT_ARCHIVE, 0}, {"raw", CAT_IMAGE, 0}, {"rb", CAT_CODE, 0},
105
+ {"reg", CAT_SYSTEM, 0}, {"rm", CAT_VIDEO, 0}, {"rpm", CAT_ARCHIVE, 0}, {"rs", CAT_CODE, 0},
106
+ {"rst", CAT_DOCUMENT, 0}, {"rtf", CAT_DOCUMENT, 0}, {"sass", CAT_CODE, 0}, {"scala", CAT_CODE, 0},
107
+ {"scss", CAT_CODE, 0}, {"sh", CAT_CODE, 0}, {"sln", CAT_CODE, 0}, {"so", CAT_EXECUTABLE, 0},
108
+ {"sql", CAT_CODE, 0}, {"srt", CAT_VIDEO, 0}, {"svg", CAT_IMAGE, 0}, {"swf", CAT_VIDEO, 0},
109
+ {"swift", CAT_CODE, 0}, {"sys", CAT_SYSTEM, 0}, {"tar", CAT_ARCHIVE, 0}, {"tga", CAT_IMAGE, 0},
110
+ {"tgz", CAT_ARCHIVE, 0}, {"tif", CAT_IMAGE, 0}, {"tiff", CAT_IMAGE, 0}, {"tmp", CAT_SYSTEM, 0},
111
+ {"ts", CAT_CODE, 0}, {"tsv", CAT_DOCUMENT, 0}, {"ttf", CAT_SYSTEM, 0}, {"txt", CAT_DOCUMENT, 0},
112
+ {"vb", CAT_CODE, 0}, {"vbox", CAT_SYSTEM, 0}, {"vcd", CAT_ARCHIVE, 0}, {"vcf", CAT_DOCUMENT, 0},
113
+ {"vcxproj", CAT_CODE, 0}, {"vob", CAT_VIDEO, 0}, {"vue", CAT_CODE, 0}, {"wav", CAT_AUDIO, 0},
114
+ {"webm", CAT_VIDEO, 0}, {"webp", CAT_IMAGE, 0}, {"wma", CAT_AUDIO, 0}, {"wmv", CAT_VIDEO, 0},
115
+ {"woff", CAT_SYSTEM, 0}, {"woff2", CAT_SYSTEM, 0}, {"wpd", CAT_DOCUMENT, 0}, {"wps", CAT_DOCUMENT, 0},
116
+ {"wsf", CAT_CODE, 0}, {"xcodeproj", CAT_CODE, 0}, {"xls", CAT_DOCUMENT, 0}, {"xlsm", CAT_DOCUMENT, 0},
117
+ {"xlsx", CAT_DOCUMENT, 0}, {"xml", CAT_CODE, 0}, {"yaml", CAT_CODE, 0}, {"yml", CAT_CODE, 0},
118
+ {"zip", CAT_ARCHIVE, 0}
119
+ };
120
+
121
+ static const int EXTENSION_COUNT = sizeof(EXTENSION_TABLE) / sizeof(ExtMap);
122
+
123
+ typedef struct {
124
+ unsigned long long counts[CAT_COUNT];
125
+ unsigned long long total_files;
126
+ } ScanStats;
127
+
128
+ /* -------------------------------------------------------------------------
129
+ Helper Functions
130
+ ------------------------------------------------------------------------- */
131
+
132
+ static int compare_ext(const void *key, const void *elem) {
133
+ const char *k = (const char *)key;
134
+ const ExtMap *m = (const ExtMap *)elem;
135
+ return strcmp(k, m->ext);
136
+ }
137
+
138
+ static FileCategory identify_and_count(const char *filename) {
139
+ const char *dot = strrchr(filename, '.');
140
+ char ext_lower[32];
141
+ const char *ext_ptr;
142
+ size_t i = 0;
143
+ ExtMap *found;
144
+
145
+ if (!dot || dot == filename) return CAT_UNKNOWN;
146
+ ext_ptr = dot + 1;
147
+
148
+ while (ext_ptr[i] && i < 31) {
149
+ ext_lower[i] = tolower((unsigned char)ext_ptr[i]);
150
+ i++;
151
+ }
152
+ ext_lower[i] = '\0';
153
+
154
+ if (i == 0) return CAT_UNKNOWN;
155
+
156
+ /* Binary Search */
157
+ found = (ExtMap *)bsearch(ext_lower, EXTENSION_TABLE, EXTENSION_COUNT, sizeof(ExtMap), compare_ext);
158
+
159
+ if (found) {
160
+ found->count++; /* Increment specific extension counter */
161
+ return found->category;
162
+ }
163
+ return CAT_UNKNOWN;
164
+ }
165
+
166
+ /* Print Visual Tree Indentation */
167
+ static void print_tree_prefix(int depth) {
168
+ int i;
169
+ for (i = 0; i < depth; i++) {
170
+ printf(" | ");
171
+ }
172
+ printf(" |-- ");
173
+ }
174
+
175
+ /* -------------------------------------------------------------------------
176
+ Core Scanning Logic
177
+ ------------------------------------------------------------------------- */
178
+
179
+ #ifdef _WIN32
180
+ static void scan_recursive(const wchar_t *path, ScanStats *stats, int depth) {
181
+ WIN32_FIND_DATAW findData;
182
+ HANDLE hFind;
183
+ wchar_t searchPath[32768];
184
+ wchar_t subPath[32768];
185
+ char filenameUtf8[1024];
186
+ int ret;
187
+ FileCategory cat;
188
+
189
+ if (wcslen(path) + 3 >= 32768) return;
190
+ swprintf(searchPath, 32768, L"%s\\*", path);
191
+
192
+ hFind = FindFirstFileW(searchPath, &findData);
193
+ if (hFind == INVALID_HANDLE_VALUE) return;
194
+
195
+ do {
196
+ if (wcscmp(findData.cFileName, L".") == 0 || wcscmp(findData.cFileName, L"..") == 0)
197
+ continue;
198
+
199
+ /* Prepare UTF-8 name for display/logic */
200
+ ret = WideCharToMultiByte(CP_UTF8, 0, findData.cFileName, -1,
201
+ filenameUtf8, sizeof(filenameUtf8), NULL, NULL);
202
+
203
+ if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
204
+ /* Diagrammatic Output for Folder */
205
+ if (ret > 0) {
206
+ print_tree_prefix(depth);
207
+ printf("[%s]\n", filenameUtf8);
208
+ }
209
+
210
+ if (wcslen(path) + wcslen(findData.cFileName) + 2 < 32768) {
211
+ swprintf(subPath, 32768, L"%s\\%s", path, findData.cFileName);
212
+ scan_recursive(subPath, stats, depth + 1);
213
+ }
214
+ } else {
215
+ /* File handling */
216
+ if (ret > 0) {
217
+ cat = identify_and_count(filenameUtf8);
218
+ stats->counts[cat]++;
219
+ stats->total_files++;
220
+ }
221
+ }
222
+ } while (FindNextFileW(hFind, &findData) != 0);
223
+
224
+ FindClose(hFind);
225
+ }
226
+
227
+ #else
228
+ static void scan_recursive(const char *path, ScanStats *stats, int depth) {
229
+ DIR *dir;
230
+ struct dirent *entry;
231
+ char full_path[4096];
232
+ struct stat path_stat;
233
+ FileCategory cat;
234
+
235
+ if (!(dir = opendir(path))) return;
236
+
237
+ while ((entry = readdir(dir)) != NULL) {
238
+ if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
239
+ continue;
240
+
241
+ if (snprintf(full_path, sizeof(full_path), "%s/%s", path, entry->d_name) >= (int)sizeof(full_path))
242
+ continue;
243
+
244
+ if (lstat(full_path, &path_stat) != 0) continue;
245
+
246
+ if (S_ISDIR(path_stat.st_mode)) {
247
+ /* Diagrammatic Output */
248
+ print_tree_prefix(depth);
249
+ printf("[%s]\n", entry->d_name);
250
+ scan_recursive(full_path, stats, depth + 1);
251
+ } else if (S_ISREG(path_stat.st_mode)) {
252
+ cat = identify_and_count(entry->d_name);
253
+ stats->counts[cat]++;
254
+ stats->total_files++;
255
+ }
256
+ }
257
+ closedir(dir);
258
+ }
259
+ #endif
260
+
261
+ /* -------------------------------------------------------------------------
262
+ Python Interface
263
+ ------------------------------------------------------------------------- */
264
+
265
+ static PyObject* anscom_scan(PyObject *self, PyObject *args) {
266
+ const char *input_path;
267
+ ScanStats stats;
268
+ int i;
269
+ double percent;
270
+ #ifdef _WIN32
271
+ int wlen;
272
+ wchar_t *wpath;
273
+ #endif
274
+
275
+ /* Reset global stats */
276
+ memset(&stats, 0, sizeof(stats));
277
+ for (i = 0; i < EXTENSION_COUNT; i++) {
278
+ EXTENSION_TABLE[i].count = 0;
279
+ }
280
+
281
+ if (!PyArg_ParseTuple(args, "s", &input_path)) {
282
+ return NULL;
283
+ }
284
+
285
+ printf("\nAnscom Analyst v0.4\n");
286
+ printf("Target: %s\n", input_path);
287
+ printf("Structure Map:\n");
288
+ printf(".\n"); /* Root dot */
289
+
290
+ #ifdef _WIN32
291
+ wlen = MultiByteToWideChar(CP_UTF8, 0, input_path, -1, NULL, 0);
292
+ if (wlen > 0) {
293
+ wpath = (wchar_t *)malloc(wlen * sizeof(wchar_t));
294
+ if (wpath) {
295
+ MultiByteToWideChar(CP_UTF8, 0, input_path, -1, wpath, wlen);
296
+ scan_recursive(wpath, &stats, 0);
297
+ free(wpath);
298
+ }
299
+ }
300
+ #else
301
+ scan_recursive(input_path, &stats, 0);
302
+ #endif
303
+
304
+ /* 1. General Summary Table */
305
+ printf("\n");
306
+ printf("=== SUMMARY REPORT ================================\n");
307
+ printf("+-----------------+--------------+----------+\n");
308
+ printf("| %-15s | %-12s | %-8s |\n", "Category", "Count", "Percent");
309
+ printf("+-----------------+--------------+----------+\n");
310
+
311
+ if (stats.total_files == 0) {
312
+ printf("| %-38s |\n", "No files found.");
313
+ } else {
314
+ for (i = 0; i < CAT_COUNT; i++) {
315
+ if (stats.counts[i] == 0 && i != CAT_UNKNOWN) continue;
316
+
317
+ percent = (double)stats.counts[i] / (double)stats.total_files * 100.0;
318
+ printf("| %-15s | %12llu | %7.2f%% |\n",
319
+ CAT_NAMES[i],
320
+ stats.counts[i],
321
+ percent);
322
+ }
323
+ }
324
+ printf("+-----------------+--------------+----------+\n");
325
+ printf("| %-15s | %12llu | %-8s |\n", "TOTAL FILES", stats.total_files, "100.00%");
326
+ printf("+-----------------+--------------+----------+\n");
327
+
328
+ /* 2. Detailed Extension Table */
329
+ if (stats.total_files > 0) {
330
+ printf("\n=== DETAILED BREAKDOWN ============================\n");
331
+ printf("+-----------------+--------------+\n");
332
+ printf("| %-15s | %-12s |\n", "Extension Type", "Count");
333
+ printf("+-----------------+--------------+\n");
334
+
335
+ for (i = 0; i < EXTENSION_COUNT; i++) {
336
+ if (EXTENSION_TABLE[i].count > 0) {
337
+ printf("| .%-14s | %12llu |\n",
338
+ EXTENSION_TABLE[i].ext,
339
+ EXTENSION_TABLE[i].count);
340
+ }
341
+ }
342
+ printf("+-----------------+--------------+\n");
343
+ }
344
+
345
+ return Py_BuildValue("K", stats.total_files);
346
+ }
347
+
348
+ /* -------------------------------------------------------------------------
349
+ Module Registration
350
+ ------------------------------------------------------------------------- */
351
+
352
+ static PyMethodDef AnscomMethods[] = {
353
+ {"scan", anscom_scan, METH_VARARGS, "Scan directory with diagrammatic tree and detailed analysis."},
354
+ {NULL, NULL, 0, NULL}
355
+ };
356
+
357
+ static struct PyModuleDef anscommodule = {
358
+ PyModuleDef_HEAD_INIT,
359
+ "anscom",
360
+ "Analyst grade recursive file scanner.",
361
+ -1,
362
+ AnscomMethods
363
+ };
364
+
365
+ PyMODINIT_FUNC PyInit_anscom(void) {
366
+ return PyModule_Create(&anscommodule);
367
+ }
@@ -0,0 +1,60 @@
1
+ Metadata-Version: 2.4
2
+ Name: anscom
3
+ Version: 0.4.0
4
+ Summary: A fast native C recursive file scanner and analyzer
5
+ Home-page: https://github.com/PC5518
6
+ Author: Aditya Narayan Singh
7
+ Author-email: adityansdsdc@outlook.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: C
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.6
13
+ Description-Content-Type: text/markdown
14
+ Dynamic: author
15
+ Dynamic: author-email
16
+ Dynamic: classifier
17
+ Dynamic: description
18
+ Dynamic: description-content-type
19
+ Dynamic: home-page
20
+ Dynamic: requires-python
21
+ Dynamic: summary
22
+
23
+ # Anscom
24
+
25
+ **Anscom** is a high-performance, native C extension for Python that recursively scans directories and categorizes files with blazingly fast speed.
26
+
27
+ ## Features
28
+ - **Native C Speed:** Written in pure C (C89 compliant).
29
+ - **Visual Tree:** Prints a diagrammatic folder tree in the terminal.
30
+ - **Detailed Analysis:** Breakdowns by category and specific file extensions.
31
+ - **Cross-Platform:** Works on Windows, Linux, and macOS.
32
+
33
+ ## Installation
34
+ ```bash
35
+ pip install anscom
36
+
37
+
38
+
39
+ Usage
40
+ code
41
+ Python
42
+ import anscom
43
+
44
+ # Scan the current directory
45
+ anscom.scan(".")
46
+
47
+ # Scan a specific path
48
+ anscom.scan("C:/Users/Documents")
49
+ code
50
+ Code
51
+ ---
52
+
53
+ ### Step 2: Create a `MANIFEST.in`
54
+ When you package C modules, Python needs to know exactly which source files to include. Create a file named `MANIFEST.in`:
55
+
56
+ ```text
57
+ include *.c
58
+ include *.h
59
+ include LICENSE
60
+ include README.md
@@ -0,0 +1,7 @@
1
+ README.md
2
+ anscom.c
3
+ setup.py
4
+ anscom.egg-info/PKG-INFO
5
+ anscom.egg-info/SOURCES.txt
6
+ anscom.egg-info/dependency_links.txt
7
+ anscom.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ anscom
anscom-0.4.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
anscom-0.4.0/setup.py ADDED
@@ -0,0 +1,31 @@
1
+ from setuptools import setup, Extension
2
+
3
+ # Read the long description from README
4
+ with open("README.md", "r", encoding="utf-8") as fh:
5
+ long_description = fh.read()
6
+
7
+ module = Extension(
8
+ 'anscom',
9
+ sources=['anscom.c'],
10
+ # Optional: Compile arguments can be added here if needed
11
+ # extra_compile_args = ['-O3']
12
+ )
13
+
14
+ setup(
15
+ name='anscom', # Check PyPI if this name is taken!
16
+ version='0.4.0',
17
+ author='Aditya Narayan Singh',
18
+ author_email='adityansdsdc@outlook.com',
19
+ description='A fast native C recursive file scanner and analyzer',
20
+ long_description=long_description,
21
+ long_description_content_type="text/markdown",
22
+ url='https://github.com/PC5518', # Optional
23
+ ext_modules=[module],
24
+ classifiers=[
25
+ "Programming Language :: Python :: 3",
26
+ "Programming Language :: C",
27
+ "License :: OSI Approved :: MIT License",
28
+ "Operating System :: OS Independent",
29
+ ],
30
+ python_requires='>=3.6',
31
+ )