SmbFileCache.ets 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import { MD5 } from '@pura/harmony-utils';
  2. import { WebdavManager } from '../util/WebdavManager';
  3. import FileManager, { merge2paths } from '../util/FileManager';
  4. import { WebDavAccount } from '../../viewmodel/WebDavAccount';
  5. import nativeBridge from 'libentry.so';
  6. interface SmbDownloadBinding {
  7. downloadSmbFile(host: string, share: string, username: string, password: string, domain: string | undefined, remotePath: string, localPath: string): void;
  8. }
  9. const smbBinding: SmbDownloadBinding = nativeBridge as SmbDownloadBinding;
  10. async function buildCacheFileName(relativePath: string): Promise<string> {
  11. const hash = await MD5.digestSync(relativePath ?? '');
  12. const lastSlash = relativePath.lastIndexOf('/');
  13. const originalName = lastSlash >= 0 ? relativePath.substring(lastSlash + 1) : relativePath;
  14. const safeName = originalName ? originalName.replace(/[^a-zA-Z0-9_.-]/g, '_') : 'remote';
  15. return `${hash}_${safeName}`;
  16. }
  17. export async function ensureSmbFileCached(account: WebDavAccount, relativePath: string): Promise<string> {
  18. const manager = WebdavManager.getInstance();
  19. if (!manager.context) {
  20. throw new Error('App context is not initialized');
  21. }
  22. if (!account.smbShare) {
  23. throw new Error('SMB account missing share name');
  24. }
  25. const baseDir = manager.context.filesDir ?? manager.context.cacheDir;
  26. if (!baseDir) {
  27. throw new Error('Cache directory unavailable');
  28. }
  29. const cacheRoot = merge2paths(baseDir, 'smb_cache');
  30. await FileManager.createDir(cacheRoot);
  31. const accountDir = merge2paths(cacheRoot, account.id?.toString() ?? 'default');
  32. await FileManager.createDir(accountDir);
  33. const normalizedRelative = relativePath?.startsWith('/') ? relativePath : `/${relativePath}`;
  34. const cacheFileName = await buildCacheFileName(normalizedRelative);
  35. const localPath = merge2paths(accountDir, cacheFileName);
  36. let exists = await FileManager.isExist(localPath);
  37. if (exists) {
  38. const currentSize = await FileManager.getFileSize(localPath);
  39. if (currentSize <= 0) {
  40. await FileManager.deleteFile(localPath);
  41. exists = false;
  42. }
  43. }
  44. if (!exists) {
  45. const host = account.isUseLocalHost && account.localHost ? account.localHost : account.host;
  46. try {
  47. smbBinding.downloadSmbFile(
  48. host,
  49. account.smbShare,
  50. account.account,
  51. account.password,
  52. account.smbDomain,
  53. normalizedRelative,
  54. localPath
  55. );
  56. } catch (error) {
  57. await FileManager.deleteFile(localPath);
  58. const err = error as Error;
  59. throw err;
  60. }
  61. }
  62. return localPath;
  63. }