| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550 | const multer = require("multer");const upload = require("express").Router();const { exec } = require("child_process");const { mkdir, readdir, readFile } = require("fs");const { homedir } = require("os");const { join } = require("path");const aws = require("aws-sdk");const multerS3 = require("multer-s3");const config = require('./config');const axios = require('axios');const spacesEndpoint = new aws.Endpoint("sgp1.digitaloceanspaces.com");const s3 = new aws.S3({ endpoint: spacesEndpoint });const temp = `${homedir()}/temp`;const updateStatus = (urlType,courseId=null, chapterId=null, property,status,roomId=null) =>{  axios({    method:'put',    url:`${config.server}/${urlType}/upload`,    data:{      courseId:courseId,      chapterId:chapterId,      [property]:status,      roomId:roomId    },    headers:{      'Authorization':'yezicoco'    }  })  .then((res) => {    console.log(res.data)  })  .catch((err) => {    console.log(err)  })}const updateDBdata = (urlType,payload) => {    //params    //urlType: chapter or curriculum    axios({      method:'put',      url:`${config.server}/${urlType}/upload`,      data:payload,      headers:{        'Authorization':'yezicoco'      }    })    .then((res)=>{      console.log(res.data)    })    .catch((err)=>{      console.log(err)    })}const queryLastIndex = (urlType, chapterId,property) =>  new Promise(function(resolve, reject){        axios({          method:'get',          url:`${config.server}/${urlType}/pre/id/${chapterId}`,          headers:{            'Authorization':'yezicoco'          }        })        .then((res)=>{          resolve(res.data[property].length)        })        .catch((err)=>{          console.log(err)        })  })const queryLatestData = (urlType, chapterId, property) =>  new Promise ((resolve, reject) => {    axios({      method:'get',      url:`${config.server}/${urlType}/pre/id/${chapterId}`,      headers:{        'Authorization':'yezicoco'      }    })    .then((res)=>{      resolve(res.data[property])    })    .catch((err)=>{      console.log(err)    })  })const generatorMultipleArray = (courseId, chapterId, type,length,format='',filename='') =>{  let arr = [];  let baseUrl = `https://ccrb-cs.sgp1.digitaloceanspaces.com/course/${courseId}/${type}/${chapterId}/${chapterId}_`  for(let index = 1 ; index <= length;index++){    arr.push(baseUrl+index+'.'+format + filename);  }  return arr;};const generatorRoomMultipleArray = (roomId, type,length,format='',filename='') =>{  let arr = [];  let baseUrl = `https://ccrb-cs.sgp1.digitaloceanspaces.com/room/${roomId}/${type}/${roomId}_`  for(let index = 1 ; index <= length;index++){    arr.push(baseUrl+index+'.'+format + filename);  }  return arr;};const uploadAttachment2space = () => multer({  storage: multerS3({    s3: s3,    bucket: (req, file, cb) => {      cb(null, `ccrb-cs/course/${req.body.courseId}/attachments/${req.body.chapterId}`);    },    acl: "public-read",    key: function(req, file, cb) {      cb(null,file.originalname);    }  })});const uploadFile2Space = (type,category) =>{  if(category === 'course'){    return (course, bucket='', dir, file) => new Promise((resovle, reject) => {      const params = {        Bucket: `ccrb-cs/course/${course}/${type}${bucket?'/':''}${bucket}`,        Key: `${file}`,        ACL: "public-read"      };      readFile(`${dir}/${file}`, (err, buf) => {        if (err)          return console.error(err);        params.Body = buf;        s3.putObject(params, (err,data) => {          if (err) {            console.error(err);            return reject(err);          }else{            let response = {              status:200,              url:`${config.space}/course/${course}/${type}${bucket?'/':''}${bucket}/${file}`,            }            return resovle(response);          }        });      });    })  }else if(category === 'room'){    return (roomId, bucket='', dir, file) => new Promise((resovle, reject) => {      const params = {        Bucket: `ccrb-cs/room/${roomId}/${type}${bucket?'/':''}${bucket}`,        Key: `${file}`,        ACL: "public-read"      };      readFile(`${dir}/${file}`, (err, buf) => {        if (err)          return console.error(err);        params.Body = buf;        s3.putObject(params, (err,data) => {          if (err) {            console.error(err);            return reject(err);          }else{            let response = {              status:200,              url:`${config.space}/room/${roomId}/${type}${bucket?'/':''}${bucket}/${file}`,            }            return resovle(response);          }        });      });    })  }};//courseconst slide2SpacePromise = uploadFile2Space('slides','course');const clip2SpacePromise = uploadFile2Space('clips','course');const thumb2SpacePromise = uploadFile2Space('thumbs','course');const cover2SpacePromise = uploadFile2Space('covers','course');const demo2SpacePromise = uploadFile2Space('demos','course');//pdfconst roomSlide2SpacePromise = uploadFile2Space('slides','room');const uploadPdf2Server = () => multer({  storage: multer.diskStorage({    destination: (req, file, cb) => {      const filename = req.body.roomId? req.body.roomId:req.body.chapterId;      const dir = `${temp}/pdf/${filename}`;      mkdir(dir, { recursive: true }, () => cb(null, dir));    },    filename: (req, file, cb) => {      const filename = req.body.roomId? req.body.roomId:req.body.chapterId;      return cb(null, `${filename}.pdf`)    }  })});const runBash = command => new Promise((resovle, reject) => {  exec(command, (err,stdout, stderr) => err? reject(err): resovle(stdout));});const uploadJpg2Space = (courseId, chapterId, dir, files, index,bashmsg,category) =>  {if(category === 'course'){    slide2SpacePromise(courseId, chapterId, dir, files[index])      .then((res) => {        delete files[index];        if (Object.keys(files).length === 0) {          console.log(bashmsg);          let pages = bashmsg.slice(bashmsg.indexOf('Total pages: ')+13);          let slides = generatorMultipleArray(courseId, chapterId, 'slides', pages, 'jpg');          updateDBdata('chapter',{courseId:courseId,chapterId:chapterId,slideUrl:slides})          exec(`rm -rf ${dir}`, err => err? console.error(err): '');        }      })      .catch(err => {        // catch the error from uploading jpg file to spaces        console.error(err);        uploadJpg2Space(courseId, chapterId, dir, files, index);      });  }else if(category === 'room'){    roomSlide2SpacePromise(courseId, chapterId, dir, files[index])      .then((res) => {        delete files[index];        if (Object.keys(files).length === 0) {          console.log(bashmsg);          let pages = bashmsg.slice(bashmsg.indexOf('Total pages: ')+13);          let slides = generatorRoomMultipleArray(courseId,'slides', pages, 'jpg');          updateDBdata('room',{roomId:courseId,slideUrl:slides})          exec(`rm -rf ${dir}`, err => err? console.error(err): '');        }      })      .catch(err => {        // catch the error from uploading jpg file to spaces        console.error(err);        uploadJpg2Space(courseId, chapterId, dir, files, index);      });  }}upload.post("/pdf", (req, res) => {  uploadPdf2Server().single("pdf")(req, res, err => {    if (err) {      console.error(err);      return res.status(401).send("upload pdf failed");    }    const { courseId, chapterId ,roomId} = req.body;    if(req.body.courseId && req.body.chapterId){      const raw = `${temp}/pdf/${chapterId}`;      const slide = `${raw}/slides`;      //Update status before run bash      //to declare property is not empty      updateStatus('chapter',courseId, chapterId, 'slideUrl','pending');      runBash(`./pdf2jpg.bash ${raw} ${chapterId}`)        .then((res) => {          readdir(slide, (err, files) => {            if (err)              return console.error(err);            const filesTree = {};            files.forEach((file, i) => (filesTree[i] = file));            files.forEach((file, i) => {              let bash = {                message:res              }              uploadJpg2Space(courseId, chapterId, slide, filesTree, i, bash.message,'course');            });          });        })        .catch(err => console.error(err));      res.send("OK");    }else if (req.body.roomId) {      const raw = `${temp}/pdf/${roomId}`;      const slide = `${raw}/slides`;      //Update status before run bash      //to declare property is not empty      updateStatus('room',null,null, 'slideUrl','pending',req.body.roomId);      runBash(`./pdf2jpg.bash ${raw} ${roomId}`)        .then((res) => {          readdir(slide, (err, files) => {            if (err)              return console.error(err);            const filesTree = {};            files.forEach((file, i) => (filesTree[i] = file));            files.forEach((file, i) => {              let bash = {                message:res              }              uploadJpg2Space(roomId, chapterId, slide, filesTree, i, bash.message,'room');            });          });        })        .catch(err => console.error(err));      res.send("OK");    }else{      res.status(422).send('INVALID PAYLOAD');    }  });});const uploadClip2Server = () => multer({  storage: multer.diskStorage({    destination: (req, file, cb) => {      const dir = `${temp}/raw-clips/`;      mkdir(dir, { recursive: true }, () => cb(null, dir));    },    filename: (req, file, cb) => {      const suffix = file.originalname.match(/\.[\w]+$/);      cb(null, `${req.body.uuid}${suffix ? suffix[0] : ""}`);    }  })});const uploadClip2Space = (courseId, chapterId, dir, filename) =>  clip2SpacePromise(courseId, chapterId, dir, filename)    .then((res) =>{      if(res.status === 200){        exec(`rm ${dir}/${filename}`,err => err? console.error(err): '');        queryLastIndex('chapter',chapterId,'clipUrl')          .then((lastIndex)=>{            console.log(lastIndex);            let clipUrl = generatorMultipleArray(courseId, chapterId, 'clips', lastIndex+1, 'mp4');            let thumbUrl = generatorMultipleArray(courseId, chapterId, 'thumbs', lastIndex+1, 'jpg');            updateDBdata('chapter',{chapterId:chapterId, clipUrl:clipUrl})            updateDBdata('chapter',{chapterId:chapterId, thumbUrl:thumbUrl})          })          .catch((err)=>{console.log(err)});        // updateDBdata('curriculum',{courseId:courseId,demo:res.url})      }else{        console.log('Upload clips Something Wrong.')      }    })    .catch(err => {      // catch the error from uploading jpg file to spaces      console.error(err);      uploadClip2Space(courseId, chapterId, dir, filename);    });const uploadThumb2Space = (courseId, chapterId, dir, filename) =>  thumb2SpacePromise(courseId, chapterId, dir, filename)    .then(() => exec(`rm ${dir}/${filename}`,      err => err? console.error(err): ''))    .catch(err => {      // catch the error from uploading jpg file to spaces      console.error(err);      uploadThumb2Space(courseId, chapterId, dir, filename);    });upload.post("/clip", (req, res) => {  uploadClip2Server().single("clip")(req, res, err => {    if (err) {      console.error(err);      return res.status(401).send("upload clip failed");    }    const { courseId, chapterId, uuid } = req.body;    const { filename } = req.file;    const raw = `${temp}/raw-clips/${filename}`;    runBash(`./videoProcess.bash ${raw} ${temp}`)      .then(() => {        exec(`rm ${raw}`, err => err? console.error(err): '');        uploadClip2Space(courseId, chapterId, `${temp}/clips`, `${uuid}.mp4`);        uploadThumb2Space(courseId, chapterId, `${temp}/thumbs`, `${uuid}.jpg`);      })      .catch(err => console.error(err))    return res.send("upload clip successfully");  });});upload.post("/attach", (req, res) => {  uploadAttachment2space().single("attachment")(req, res, err => {    if (err) {      console.error(err);      return res.status(401).send("upload attachment failed");    }else{      let {courseId, chapterId } = req.body;      const { originalname } = req.file;      queryLatestData('chapter',chapterId,'attachmentUrl')        .then((latestData) => {          let baseUrl = `https://ccrb-cs.sgp1.digitaloceanspaces.com/course/${courseId}/attachments/${chapterId}/${originalname}`          let attachmentUrl = latestData;          attachmentUrl.push(baseUrl);          updateDBdata('chapter',{courseId:courseId,chapterId:chapterId,attachmentUrl:attachmentUrl})          res.send("upload attachment successfully");        })        .catch(err=>{          console.log(err);        })    }  });});const uploadCover2Server = () => multer({  storage: multer.diskStorage({    destination: (req, file, cb) => {      const dir = `${temp}/raw-covers`;      mkdir(dir, { recursive: true }, () => cb(null, dir));    },    filename: (req, file, cb) => {      const suffix = file.originalname.match(/\.[\w]+$/);      cb(null, `${req.body.name}${suffix? suffix[0]: ''}`);    }  })});const uploadCover2Space = (courseId, dir, filename,chapterId) =>  cover2SpacePromise(courseId, '', dir, filename)    .then((res) =>{      if(res.status === 200){        exec(`rm ${dir}/${filename}`,err => err? console.error(err): '')        //Due to upload cover use same route path        //verify chapterId is exist        if(chapterId){          updateDBdata('chapter',{courseId:courseId,chapterId:chapterId,bg:res.url})        }else{          updateDBdata('curriculum',{courseId:courseId,poster:res.url})        }      }else{        console.log('Something Wrong.')      }    })    .catch(err => {      // catch the error from uploading jpg file to spaces      console.error(err);      uploadCover2Space(courseId, dir, filename);    });upload.post("/cover", (req, res) => {  uploadCover2Server().single("cover")(req, res, err => {    if (err) {      console.error(err);      return res.status(401).send("upload cover failed");    }    const { courseId, name , chapterId } = req.body;    const { filename } = req.file;    const raw = `${temp}/raw-covers/${filename}`;    const cover = `${temp}/covers`    runBash(`./coverResize.bash ${raw} ${cover}/${name}`)      .then(() => {        exec(`rm ${raw}`, err => err? console.error(err): '');        uploadCover2Space(courseId, cover, `${name}.jpg`,chapterId||null);      })      .catch(err => console.error(err));    return res.send("upload cover successfully");  });});const uploadDemo2Server = () => multer({  storage: multer.diskStorage({    destination: (req, file, cb) => {      const dir = `${temp}/raw-demos`;      mkdir(dir, { recursive: true }, () => cb(null, dir));    },    filename: (req, file, cb) => {      const suffix = file.originalname.match(/\.[\w]+$/);      cb(null, `${req.body.courseId}${suffix? suffix[0]: ''}`);    }  })});const uploadDemo2Space = (courseId, dir, filename) =>  demo2SpacePromise(courseId, '', dir, filename)    .then((res) =>{      if(res.status === 200){        exec(`rm ${dir}/${filename}`,err => err? console.error(err): '')        updateDBdata('curriculum',{courseId:courseId,demo:res.url})      }else{        console.log('Upload demo Something Wrong.')      }    })    .catch(err => {      // catch the error from uploading jpg file to spaces      console.error(err);      uploadDemo2Space(courseId, dir, filename);    });upload.post("/demo", (req, res) => {  uploadDemo2Server().single('demo')(req, res, err => {    if (err) {      console.error(err);      return res.status(401).send("upload demo failed");    }    const { courseId } = req.body;    const { filename } = req.file;    const raw = `${temp}/raw-demos/${filename}`;    const type = req.file.mimetype.split('/')[0];    let bash = '';    if (type === 'image') {      bash = './demoImageResize.bash';    } else if (type === 'video') {      bash = './demoVideoResize.bash';    } else {      return res.status(401).send("wrong file type");    }    runBash(`${bash} ${raw} ${temp}/demos/${courseId}`)      .then(() => {        exec(`rm ${raw}`, err => err? console.error(err): '');        const suffix = type === 'image'? '.jpg': '.mp4';        uploadDemo2Space(courseId, `${temp}/demos`, `${courseId}${suffix}`);      })      .catch(err => console.error(err));    return res.send("upload demo successfully");  });})// ---------------------------------------------------------------------------- //const photoDirPath = join(__dirname, "static", "images", "workshop", "3");const imageStorage = multer.diskStorage({  destination: photoDirPath,  filename: (req, file, cb) => {    const { username } = req.body;    const types = file.mimetype.split("/");    if (types[0] === "image") {      cb(        null,        (username ? username : "Untitled") + `-${Date.now()}.${types[1]}`      );    }  }});const singleImageStore = multer({ storage: imageStorage }).single("userphoto");upload.get("/all_photos", (req, res) => {  readdir(photoDirPath, (err, files) => {    if (err) return res.json({ message: "error", error: err });    else return res.json({ message: "ok", files: files });  });});upload.post("/images", singleImageStore, (req, res) => {  console.log("save photo");  res.json({ msg: "Upload photo successfully" });});module.exports = upload;
 |