0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-01-04 23:22:42 +00:00

Admin script to compress old brews

Also fully delete the text field after compressed version is saved instead of leaving just an empty field.
This commit is contained in:
Trevor Buckner
2020-01-23 09:38:50 -05:00
parent 37eb0d0889
commit bc81e09686
6 changed files with 126 additions and 4 deletions

View File

@@ -4,6 +4,7 @@ const createClass = require('create-react-class');
const BrewCleanup = require('./brewCleanup/brewCleanup.jsx'); const BrewCleanup = require('./brewCleanup/brewCleanup.jsx');
const BrewLookup = require('./brewLookup/brewLookup.jsx'); const BrewLookup = require('./brewLookup/brewLookup.jsx');
const BrewCompress = require ('./brewCompress/brewCompress.jsx');
const Stats = require('./stats/stats.jsx'); const Stats = require('./stats/stats.jsx');
const Admin = createClass({ const Admin = createClass({
@@ -26,6 +27,8 @@ const Admin = createClass({
<BrewLookup /> <BrewLookup />
<hr /> <hr />
<BrewCleanup /> <BrewCleanup />
<hr />
<BrewCompress />
</div> </div>
</div>; </div>;
} }

View File

@@ -0,0 +1,77 @@
const React = require('react');
const createClass = require('create-react-class');
const cx = require('classnames');
const request = require('superagent');
const BrewCompress = createClass({
displayName : 'BrewCompress',
getDefaultProps(){
return {};
},
getInitialState() {
return {
count : 0,
pending : false,
primed : false,
err : null,
ids : null
};
},
prime(){
this.setState({ pending: true });
request.get('/admin/finduncompressed')
.then((res)=>this.setState({ count: res.body.count, primed: true, ids: res.body.ids }))
.catch((err)=>this.setState({ error: err }))
.finally(()=>this.setState({ pending: false }));
},
cleanup(){
this.setState({ pending: true });
this.state.ids.forEach((id) => {
console.log("trying to compress this one:");
console.log(id);
request.put(`/admin/compress/${id}`)
.catch((err)=>this.setState({ error: err }))
.finally(()=>this.setState({ pending: false, primed: false }));
});
},
renderPrimed(){
if(!this.state.primed) return;
if(!this.state.count){
return <div className='removeBox'>No Matching Brews found.</div>;
}
return <div className='removeBox'>
<button onClick={this.cleanup} className='remove'>
{this.state.pending
? <i className='fa fa-spin fa-spinner' />
: <span><i className='fa fa-compress' /> compress </span>
}
</button>
<span>Found {this.state.count} Brews that could be compressed. </span>
</div>;
},
render(){
return <div className='BrewCompress'>
<h2> Brew Compression </h2>
<p>Compresses the text in brews to binary</p>
<button onClick={this.prime} className='query'>
{this.state.pending
? <i className='fa fa-spin fa-spinner' />
: 'Query Brews'
}
</button>
{this.renderPrimed()}
{this.state.error
&& <div className='error'>{this.state.error.toString()}</div>
}
</div>;
}
});
module.exports = BrewCompress;

View File

@@ -0,0 +1,10 @@
.BrewCompress{
.removeBox{
margin-top: 20px;
button{
background-color: @red;
margin-right: 10px;
}
}
}

View File

@@ -3,6 +3,7 @@ const router = require('express').Router();
const Moment = require('moment'); const Moment = require('moment');
const render = require('vitreum/steps/render'); const render = require('vitreum/steps/render');
const templateFn = require('../client/template.js'); const templateFn = require('../client/template.js');
const zlib = require('zlib');
process.env.ADMIN_USER = process.env.ADMIN_USER || 'admin'; process.env.ADMIN_USER = process.env.ADMIN_USER || 'admin';
process.env.ADMIN_PASS = process.env.ADMIN_PASS || 'password3'; process.env.ADMIN_PASS = process.env.ADMIN_PASS || 'password3';
@@ -26,7 +27,7 @@ const mw = {
}; };
/* Removes all empty brews that are older than 3 days and that are shorter than a tweet */ /* Search for brews that are older than 3 days and that are shorter than a tweet */
const junkBrewQuery = HomebrewModel.find({ const junkBrewQuery = HomebrewModel.find({
'$where' : 'this.text.length < 140', '$where' : 'this.text.length < 140',
createdAt : { createdAt : {
@@ -34,6 +35,11 @@ const junkBrewQuery = HomebrewModel.find({
} }
}).limit(100).maxTime(60000); }).limit(100).maxTime(60000);
/* Search for brews that aren't compressed (missing the compressed text field) */
const uncompressedBrewQuery = HomebrewModel.find({
'textBin' : null
}).limit(50).distinct('_id');
router.get('/admin/cleanup', mw.adminOnly, (req, res)=>{ router.get('/admin/cleanup', mw.adminOnly, (req, res)=>{
junkBrewQuery.exec((err, objs)=>{ junkBrewQuery.exec((err, objs)=>{
if(err) return res.status(500).send(err); if(err) return res.status(500).send(err);
@@ -58,6 +64,32 @@ router.get('/admin/lookup/:id', mw.adminOnly, (req, res, next)=>{
}); });
}); });
/* Find 50 brews that aren't compressed yet */
router.get('/admin/finduncompressed', mw.adminOnly, (req, res)=>{
uncompressedBrewQuery.exec((err, objs)=>{
if(err) return res.status(500).send(err);
return res.json({ count: objs.length, ids: objs});
});
});
/* Compresses the "text" field of a brew to binary */
router.put('/admin/compress/:id', (req, res)=>{
HomebrewModel.get({ _id: req.params.id })
.then((brew)=>{
brew.textBin = zlib.deflateRawSync(brew.text); // Compress brew text to binary before saving
brew.text = undefined; // Delete the non-binary text field since it's not needed anymore
brew.save((err, obj)=>{
if(err) throw err;
return res.status(200).send(obj);
});
})
.catch((err)=>{
console.log(err);
return res.status(500).send('Error while saving');
});
});
router.get('/admin/stats', mw.adminOnly, (req, res)=>{ router.get('/admin/stats', mw.adminOnly, (req, res)=>{
HomebrewModel.count({}, (err, count)=>{ HomebrewModel.count({}, (err, count)=>{
return res.json({ return res.json({

View File

@@ -38,7 +38,7 @@ router.post('/api', (req, res)=>{
} }
newHomebrew.textBin = zlib.deflateRawSync(newHomebrew.text); // Compress brew text to binary before saving newHomebrew.textBin = zlib.deflateRawSync(newHomebrew.text); // Compress brew text to binary before saving
newHomebrew.text = ''; // Clear out the non-binary text field so its not saved twice newHomebrew.text = undefined; // Delete the non-binary text field since it's not needed anymore
newHomebrew.save((err, obj)=>{ newHomebrew.save((err, obj)=>{
if(err){ if(err){
@@ -54,7 +54,7 @@ router.put('/api/update/:id', (req, res)=>{
.then((brew)=>{ .then((brew)=>{
brew = _.merge(brew, req.body); brew = _.merge(brew, req.body);
brew.textBin = zlib.deflateRawSync(req.body.text); // Compress brew text to binary before saving brew.textBin = zlib.deflateRawSync(req.body.text); // Compress brew text to binary before saving
brew.text = ''; // Clear out the non-binary text field so its not saved twice brew.text = undefined; // Clear out the non-binary text field so its not saved twice
brew.updatedAt = new Date(); brew.updatedAt = new Date();
if(req.account) brew.authors = _.uniq(_.concat(brew.authors, req.account.username)); if(req.account) brew.authors = _.uniq(_.concat(brew.authors, req.account.username));

View File

@@ -53,7 +53,7 @@ HomebrewSchema.statics.get = function(query){
return new Promise((resolve, reject)=>{ return new Promise((resolve, reject)=>{
Homebrew.find(query, (err, brews)=>{ Homebrew.find(query, (err, brews)=>{
if(err || !brews.length) return reject('Can not find brew'); if(err || !brews.length) return reject('Can not find brew');
if(!_.isUndefined(brews[0].textBin)) { // Uncompress zipped text field if(!_.isNil(brews[0].textBin)) { // Uncompress zipped text field
unzipped = zlib.inflateRawSync(brews[0].textBin); unzipped = zlib.inflateRawSync(brews[0].textBin);
brews[0].text = unzipped.toString(); brews[0].text = unzipped.toString();
} }