xref: /MusicFree/src/utils/fileUtils.ts (revision 2aa881935ca35b8fb1abc4206e0dc35149231456)
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';
14
15const basePath = `${PicturesDirectoryPath}/MusicFree/`;
16export async function saveToGallery(src: string) {
17    const fileName = `${basePath}${Date.now()}.png`;
18    if (!(await exists(basePath))) {
19        await mkdir(basePath);
20    }
21    if (await exists(src)) {
22        try {
23            await copyFile(src, fileName);
24        } catch (e) {
25            console.log('... ', e);
26        }
27    }
28    if (src.startsWith('http')) {
29        await downloadFile({
30            fromUrl: src,
31            toFile: fileName,
32            background: true,
33        });
34    }
35    if (src.startsWith('data')) {
36        await writeFile(fileName, src);
37    }
38}
39
40export function sizeFormatter(bytes: number | string) {
41    if (typeof bytes === 'string') {
42        return bytes;
43    }
44    if (bytes === 0) return '0B';
45    let k = 1024,
46        sizes = ['B', 'KB', 'MB', 'GB'],
47        i = Math.floor(Math.log(bytes) / Math.log(k));
48    return (bytes / Math.pow(k, i)).toFixed(1) + sizes[i];
49}
50
51export async function checkAndCreateDir(path: string) {
52    const filePath = path;
53    try {
54        if (!(await exists(filePath))) {
55            await mkdir(filePath);
56        }
57    } catch (e) {
58        errorLog('无法初始化目录', {path, e});
59    }
60}
61
62async function getFolderSize(path: string): Promise<number> {
63    let size = 0;
64    try {
65        const fns = await readDir(path);
66        for (let fn of fns) {
67            if (fn.isFile()) {
68                size += fn.size;
69            }
70            // todo: 可以改成并行 promise.all
71            if (fn.isDirectory()) {
72                size += await getFolderSize(fn.path);
73            }
74        }
75    } catch {}
76    return size;
77}
78
79export async function getCacheSize(
80    type: 'music' | 'lyric' | 'image',
81): Promise<number> {
82    if (type === 'music') {
83        return getFolderSize(pathConst.musicCachePath);
84    } else if (type === 'lyric') {
85        return getFolderSize(pathConst.lrcCachePath);
86    } else if (type === 'image') {
87        return getFolderSize(pathConst.imageCachePath);
88    }
89    throw new Error();
90}
91
92export async function clearCache(type: 'music' | 'lyric' | 'image') {
93    if (type === 'music') {
94        try {
95            if (await exists(pathConst.musicCachePath)) {
96                return unlink(pathConst.musicCachePath);
97            }
98        } catch {}
99    } else if (type === 'lyric') {
100        try {
101            const lrcs = readDir(pathConst.lrcCachePath);
102            return Promise.all((await lrcs).map(_ => unlink(_.path)));
103        } catch {}
104    } else if (type === 'image') {
105        return FastImage.clearDiskCache();
106    }
107}
108
109export function addFileScheme(fileName: string) {
110    if (fileName.startsWith('/')) {
111        return `file://${fileName}`;
112    }
113    return fileName;
114}
115
116export function addRandomHash(url: string) {
117    if (url.indexOf('#') === -1) {
118        return `${url}#${Date.now()}`;
119    }
120    return url;
121}
122
123export function trimHash(url: string) {
124    const index = url.lastIndexOf('#');
125    if (index === -1) {
126        return url;
127    }
128    return url.substring(0, index);
129}
130