@@ -18,8 +18,16 @@ const TutorialView = require('../models/tutorialView');
1818const TutorialParser = require ( './tutorialParser' ) ;
1919const stripTitle = require ( 'markit' ) . stripTitle ;
2020const stripYamlMetadata = require ( 'markit' ) . stripYamlMetadata ;
21+ const mime = require ( 'mime' ) ;
22+ const stripIndents = require ( 'textUtil/stripIndents' ) ;
2123
2224
25+ const t = require ( 'i18n' ) ;
26+
27+ const LANG = require ( 'config' ) . lang ;
28+
29+ t . requirePhrase ( 'tutorial.importer' , require ( '../locales/importer/' + LANG + '.yml' ) ) ;
30+
2331module . exports = class TutorialImporter {
2432 constructor ( options ) {
2533 this . root = fs . realpathSync ( options . root ) ;
@@ -366,7 +374,7 @@ module.exports = class TutorialImporter {
366374 log . debug ( "Created new plunk (db empty)" , view ) ;
367375 }
368376
369- let filesForPlunk = plunkReadFs ( dir ) ;
377+ let filesForPlunk = readFs ( dir ) ;
370378 log . debug ( "Files for plunk" , filesForPlunk ) ;
371379
372380 if ( ! filesForPlunk ) return ; // had errors
@@ -421,7 +429,7 @@ module.exports = class TutorialImporter {
421429 webPath : sourceWebPath ,
422430 description : "Fork from https://" + config . domain . main
423431 } ) ;
424- TutorialView . storage [ webbPath ] = sourceView ;
432+ TutorialView . storage [ sourceWebPath ] = sourceView ;
425433 }
426434
427435 let sourceFilesForView = {
@@ -435,15 +443,15 @@ module.exports = class TutorialImporter {
435443 }
436444 } ;
437445
438- log . debug ( "save plunk for " , webPath ) ;
446+ log . debug ( "save plunk for " , sourceWebPath ) ;
439447 await sourceView . mergeAndSyncPlunk ( sourceFilesForView , this . plunkerToken ) ;
440448
441449 // Solution
442450 let solutionWebPath = task . getResourceWebRoot ( ) + '/solution' ;
443451
444452 let solution = makeSolution ( solutionJs , testJs ) ;
445453
446- let solutionView = TutorialView . storage [ webPath ] ;
454+ let solutionView = TutorialView . storage [ solutionWebPath ] ;
447455
448456 if ( ! solutionView ) {
449457 solutionView = new TutorialView ( {
@@ -544,4 +552,68 @@ function copySync(srcPath, dstPath) {
544552
545553 fse . copySync ( srcPath , dstPath ) ;
546554}
555+
556+
557+ function readFs ( dir ) {
558+
559+ var files = fs . readdirSync ( dir ) ;
560+
561+ var hadErrors = false ;
562+ files = files . filter ( function ( file ) {
563+ if ( file [ 0 ] == "." ) return false ;
564+
565+ var filePath = path . join ( dir , file ) ;
566+ if ( fs . statSync ( filePath ) . isDirectory ( ) ) {
567+ log . error ( "Directory not allowed: " + file ) ;
568+ hadErrors = true ;
569+ }
570+
571+ var type = mime . lookup ( file ) . split ( '/' ) ;
572+ if ( type [ 0 ] != 'text' && type [ 1 ] != 'json' && type [ 1 ] != 'javascript' && type [ 1 ] != 'svg+xml' ) {
573+ log . error ( "Bad file extension: " + file ) ;
574+ hadErrors = true ;
575+ }
576+
577+ return true ;
578+ } ) ;
579+
580+ if ( hadErrors ) {
581+ return null ;
582+ }
583+
584+ files = files . sort ( function ( fileA , fileB ) {
585+ var extA = fileA . slice ( fileA . lastIndexOf ( '.' ) + 1 ) ;
586+ var extB = fileB . slice ( fileB . lastIndexOf ( '.' ) + 1 ) ;
587+
588+ if ( extA == extB ) {
589+ return fileA > fileB ? 1 : - 1 ;
590+ }
591+
592+ // html always first
593+ if ( extA == 'html' ) return 1 ;
594+ if ( extB == 'html' ) return - 1 ;
595+
596+ // then goes CSS
597+ if ( extA == 'css' ) return 1 ;
598+ if ( extB == 'css' ) return - 1 ;
599+
600+ // then JS
601+ if ( extA == 'js' ) return 1 ;
602+ if ( extB == 'js' ) return - 1 ;
603+
604+ // then other extensions
605+ return fileA > fileB ? 1 : - 1 ;
606+ } ) ;
607+
608+ var filesForPlunk = { } ;
609+ for ( var i = 0 ; i < files . length ; i ++ ) {
610+ var file = files [ i ] ;
611+ filesForPlunk [ file ] = {
612+ filename : file ,
613+ content : stripIndents ( fs . readFileSync ( path . join ( dir , file ) , 'utf-8' ) )
614+ } ;
615+ }
616+
617+ return filesForPlunk ;
618+ }
547619
0 commit comments