Przeglądaj źródła

refactor zipFileStat object structure

Yuki Takei 6 lat temu
rodzic
commit
0a26bf5448

+ 2 - 2
src/client/js/components/Admin/ExportData/ZipFileTable.jsx

@@ -26,12 +26,12 @@ class ZipFileTable extends React.Component {
           </tr>
           </tr>
         </thead>
         </thead>
         <tbody>
         <tbody>
-          {this.props.zipFileStats.map(({ meta, fileName, fileStats }) => {
+          {this.props.zipFileStats.map(({ meta, fileName, innerFileStats }) => {
             return (
             return (
               <tr key={fileName}>
               <tr key={fileName}>
                 <th>{fileName}</th>
                 <th>{fileName}</th>
                 <td>{meta.version}</td>
                 <td>{meta.version}</td>
-                <td className="text-capitalize">{fileStats.map(fileStat => fileStat.collectionName).join(', ')}</td>
+                <td className="text-capitalize">{innerFileStats.map(fileStat => fileStat.collectionName).join(', ')}</td>
                 <td>{meta.exportedAt ? format(new Date(meta.exportedAt), 'yyyy/MM/dd HH:mm:ss') : ''}</td>
                 <td>{meta.exportedAt ? format(new Date(meta.exportedAt), 'yyyy/MM/dd HH:mm:ss') : ''}</td>
                 <td>
                 <td>
                   <ExportTableMenu
                   <ExportTableMenu

+ 2 - 2
src/client/js/components/Admin/ImportData/GrowiZipImportForm.jsx

@@ -40,7 +40,7 @@ class GrowiImportForm extends React.Component {
       errorsForOtherGroups: [],
       errorsForOtherGroups: [],
     };
     };
 
 
-    this.props.fileStats.forEach((fileStat) => {
+    this.props.innerFileStats.forEach((fileStat) => {
       const { fileName, collectionName } = fileStat;
       const { fileName, collectionName } = fileStat;
       this.initialState.collectionNameToFileNameMap[collectionName] = fileName;
       this.initialState.collectionNameToFileNameMap[collectionName] = fileName;
     });
     });
@@ -349,7 +349,7 @@ GrowiImportForm.propTypes = {
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
 
 
   fileName: PropTypes.string,
   fileName: PropTypes.string,
-  fileStats: PropTypes.arrayOf(PropTypes.object).isRequired,
+  innerFileStats: PropTypes.arrayOf(PropTypes.object).isRequired,
   onDiscard: PropTypes.func.isRequired,
   onDiscard: PropTypes.func.isRequired,
   onPostImport: PropTypes.func.isRequired,
   onPostImport: PropTypes.func.isRequired,
 };
 };

+ 6 - 6
src/client/js/components/Admin/ImportData/GrowiZipImportSection.jsx

@@ -16,8 +16,8 @@ class GrowiZipImportSection extends React.Component {
     super(props);
     super(props);
 
 
     this.initialState = {
     this.initialState = {
-      fileName: '',
-      fileStats: [],
+      fileName: null,
+      innerFileStats: null,
     };
     };
 
 
     this.state = this.initialState;
     this.state = this.initialState;
@@ -27,10 +27,10 @@ class GrowiZipImportSection extends React.Component {
     this.resetState = this.resetState.bind(this);
     this.resetState = this.resetState.bind(this);
   }
   }
 
 
-  handleUpload({ meta, fileName, fileStats }) {
+  handleUpload({ meta, fileName, innerFileStats }) {
     this.setState({
     this.setState({
       fileName,
       fileName,
-      fileStats,
+      innerFileStats,
     });
     });
   }
   }
 
 
@@ -79,11 +79,11 @@ class GrowiZipImportSection extends React.Component {
           <i className="icon-exclamation"></i> { t('importer_management.beta_warning') }
           <i className="icon-exclamation"></i> { t('importer_management.beta_warning') }
         </div>
         </div>
 
 
-        {this.state.fileName ? (
+        { this.state.fileName != null ? (
           <div className="px-4">
           <div className="px-4">
             <GrowiZipImportForm
             <GrowiZipImportForm
               fileName={this.state.fileName}
               fileName={this.state.fileName}
-              fileStats={this.state.fileStats}
+              innerFileStats={this.state.innerFileStats}
               onDiscard={this.discardData}
               onDiscard={this.discardData}
               onPostImport={this.resetState}
               onPostImport={this.resetState}
             />
             />

+ 4 - 4
src/server/routes/apiv3/import.js

@@ -165,19 +165,19 @@ module.exports = (crowi) => {
     // unzip
     // unzip
     await importService.unzip(zipFile);
     await importService.unzip(zipFile);
     // eslint-disable-next-line no-unused-vars
     // eslint-disable-next-line no-unused-vars
-    const { meta, fileStats } = await growiBridgeService.parseZipFile(zipFile);
+    const { meta, fileStats, innerFileStats } = await growiBridgeService.parseZipFile(zipFile);
 
 
     // delete zip file after unzipping and parsing it
     // delete zip file after unzipping and parsing it
     fs.unlinkSync(zipFile);
     fs.unlinkSync(zipFile);
 
 
-    // filter fileStats
-    const filteredFileStats = fileStats.filter(({ fileName, collectionName, size }) => { return collections.includes(collectionName) });
+    // filter innerFileStats
+    const filteredInnerFileStats = innerFileStats.filter(({ fileName, collectionName, size }) => { return collections.includes(collectionName) });
 
 
     try {
     try {
       // validate with meta.json
       // validate with meta.json
       importService.validate(meta);
       importService.validate(meta);
 
 
-      const results = await Promise.all(filteredFileStats.map(async({ fileName, collectionName, size }) => {
+      const results = await Promise.all(filteredInnerFileStats.map(async({ fileName, collectionName, size }) => {
         const Model = growiBridgeService.getModelFromCollectionName(collectionName);
         const Model = growiBridgeService.getModelFromCollectionName(collectionName);
         const jsonFile = importService.getFile(fileName);
         const jsonFile = importService.getFile(fileName);
 
 

+ 5 - 3
src/server/service/growi-bridge.js

@@ -99,7 +99,8 @@ class GrowiBridgeService {
    * @return {object} meta{object} and files{Array.<object>}
    * @return {object} meta{object} and files{Array.<object>}
    */
    */
   async parseZipFile(zipFile) {
   async parseZipFile(zipFile) {
-    const fileStats = [];
+    const fileStat = fs.statSync(zipFile);
+    const innerFileStats = [];
     let meta = {};
     let meta = {};
 
 
     const readStream = fs.createReadStream(zipFile);
     const readStream = fs.createReadStream(zipFile);
@@ -113,7 +114,7 @@ class GrowiBridgeService {
         meta = JSON.parse((await entry.buffer()).toString());
         meta = JSON.parse((await entry.buffer()).toString());
       }
       }
       else {
       else {
-        fileStats.push({
+        innerFileStats.push({
           fileName,
           fileName,
           collectionName: path.basename(fileName, '.json'),
           collectionName: path.basename(fileName, '.json'),
           size,
           size,
@@ -135,7 +136,8 @@ class GrowiBridgeService {
     return {
     return {
       meta,
       meta,
       fileName: path.basename(zipFile),
       fileName: path.basename(zipFile),
-      fileStats,
+      fileStat,
+      innerFileStats,
     };
     };
   }
   }
 
 

+ 6 - 3
src/server/service/import.js

@@ -73,19 +73,22 @@ class ImportService {
    * @return {object} info for zip files and whether currentProgressingStatus exists
    * @return {object} info for zip files and whether currentProgressingStatus exists
    */
    */
   async getStatus() {
   async getStatus() {
-    const zipFiles = fs.readdirSync(this.baseDir).filter((file) => { return path.extname(file) === '.zip' });
+    const zipFiles = fs.readdirSync(this.baseDir).filter(file => path.extname(file) === '.zip');
     const zipFileStats = await Promise.all(zipFiles.map((file) => {
     const zipFileStats = await Promise.all(zipFiles.map((file) => {
       const zipFile = this.getFile(file);
       const zipFile = this.getFile(file);
       return this.growiBridgeService.parseZipFile(zipFile);
       return this.growiBridgeService.parseZipFile(zipFile);
     }));
     }));
 
 
     // filter null object (broken zip)
     // filter null object (broken zip)
-    const filtered = zipFileStats.filter(element => element != null);
+    const filtered = zipFileStats
+      .filter(zipFileStat => zipFileStat != null);
+    // sort with ctime("Change Time" - Time when file status was last changed (inode data modification).)
+    filtered.sort((a, b) => { return a.fileStat.ctime - b.fileStat.ctime });
 
 
     const isImporting = this.currentProgressingStatus != null;
     const isImporting = this.currentProgressingStatus != null;
 
 
     return {
     return {
-      zipFileStats: filtered,
+      zipFileStat: filtered.pop(),
       isImporting,
       isImporting,
       progressList: isImporting ? this.currentProgressingStatus.progressList : null,
       progressList: isImporting ? this.currentProgressingStatus.progressList : null,
     };
     };