xref: /MusicFree/src/utils/fileUtils.ts (revision e0caf3427c927f4cf2efda9969f9a6f4fb0ef565)
1import pathConst from '@/constants/pathConst';
2import FastImage from 'react-native-fast-image';
3import {
4    copyFile,
5    downloadFile,
6    exists,
7    mkdir,
8    PicturesDirectoryPath,
9    readDir,
10    unlink,
11    writeFile,
12} from 'react-native-fs';
13import {errorLog} from './log';
14import path from 'path-browserify';
15
16export const galleryBasePath = `${PicturesDirectoryPath}/MusicFree/`;
17
18export async function saveToGallery(src: string) {
19    const fileName = `${galleryBasePath}${Date.now()}.png`;
20    if (!(await exists(galleryBasePath))) {
21        await mkdir(galleryBasePath);
22    }
23    if (await exists(src)) {
24        try {
25            await copyFile(src, fileName);
26        } catch (e) {
27            console.log('... ', e);
28        }
29    }
30    if (src.startsWith('http')) {
31        await downloadFile({
32            fromUrl: src,
33            toFile: fileName,
34            background: true,
35        });
36    }
37    if (src.startsWith('data')) {
38        await writeFile(fileName, src);
39    }
40}
41
42export function sizeFormatter(bytes: number | string) {
43    if (typeof bytes === 'string') {
44        return bytes;
45    }
46    if (bytes === 0) return '0B';
47    let k = 1024,
48        sizes = ['B', 'KB', 'MB', 'GB'],
49        i = Math.floor(Math.log(bytes) / Math.log(k));
50    return (bytes / Math.pow(k, i)).toFixed(1) + sizes[i];
51}
52
53export async function checkAndCreateDir(path: string) {
54    const filePath = path;
55    try {
56        if (!(await exists(filePath))) {
57            await mkdir(filePath);
58        }
59    } catch (e) {
60        errorLog('无法初始化目录', {path, e});
61    }
62}
63
64async function getFolderSize(path: string): Promise<number> {
65    let size = 0;
66    try {
67        const fns = await readDir(path);
68        for (let fn of fns) {
69            if (fn.isFile()) {
70                size += fn.size;
71            }
72            // todo: 可以改成并行 promise.all
73            if (fn.isDirectory()) {
74                size += await getFolderSize(fn.path);
75            }
76        }
77    } catch {}
78    return size;
79}
80
81export async function getCacheSize(
82    type: 'music' | 'lyric' | 'image',
83): Promise<number> {
84    if (type === 'music') {
85        return getFolderSize(pathConst.musicCachePath);
86    } else if (type === 'lyric') {
87        return getFolderSize(pathConst.lrcCachePath);
88    } else if (type === 'image') {
89        return getFolderSize(pathConst.imageCachePath);
90    }
91    throw new Error();
92}
93
94export async function clearCache(type: 'music' | 'lyric' | 'image') {
95    if (type === 'music') {
96        try {
97            if (await exists(pathConst.musicCachePath)) {
98                return unlink(pathConst.musicCachePath);
99            }
100        } catch {}
101    } else if (type === 'lyric') {
102        try {
103            const lrcs = readDir(pathConst.lrcCachePath);
104            return Promise.all((await lrcs).map(_ => unlink(_.path)));
105        } catch {}
106    } else if (type === 'image') {
107        return FastImage.clearDiskCache();
108    }
109}
110
111export function addFileScheme(fileName: string) {
112    if (fileName.startsWith('/')) {
113        return `file://${fileName}`;
114    }
115    return fileName;
116}
117
118export function addRandomHash(url: string) {
119    if (url.indexOf('#') === -1) {
120        return `${url}#${Date.now()}`;
121    }
122    return url;
123}
124
125export function trimHash(url: string) {
126    const index = url.lastIndexOf('#');
127    if (index === -1) {
128        return url;
129    }
130    return url.substring(0, index);
131}
132
133export function escapeCharacter(str?: string) {
134    return str !== undefined ? `${str}`.replace(/\//g, '_') : '';
135}
136
137export function getDirectory(path: string) {
138    const lastSlash = path.lastIndexOf('/');
139    if (lastSlash === -1) {
140        return path;
141    }
142    return path.slice(0, lastSlash);
143}
144
145export async function mkdirR(directory: string) {
146    let folder = directory;
147    const checkStack = [];
148    while (folder.length > 15) {
149        checkStack.push(folder);
150        folder = path.dirname(folder);
151    }
152    let existPos = 0;
153    for (let i = 0; i < checkStack.length; ++i) {
154        const isExist = await exists(checkStack[i]);
155        if (isExist) {
156            existPos = i;
157            break;
158        }
159    }
160
161    for (let j = existPos - 1; j >= 0; --j) {
162        try {
163            await mkdir(checkStack[j]);
164        } catch (e) {
165            console.log('error', e);
166        }
167    }
168}
169