Merge branch 'develop' of github.com:looching/dsite into develop
This commit is contained in:
commit
cc0c22c68b
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@ -9,5 +9,7 @@
|
|||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
"editor.rulers": [
|
"editor.rulers": [
|
||||||
120
|
120
|
||||||
]
|
],
|
||||||
|
"editor.bracketPairColorization.enabled": true,
|
||||||
|
"editor.guides.bracketPairs": "active"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,3 +31,4 @@ user-agents==2.2.0
|
|||||||
wcwidth==0.2.5
|
wcwidth==0.2.5
|
||||||
zipp==3.5.0
|
zipp==3.5.0
|
||||||
redis==4.1.0
|
redis==4.1.0
|
||||||
|
black
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-row justify="left">
|
<el-row justify="left" gutter="10">
|
||||||
<el-col>
|
<el-col>
|
||||||
<el-form :rules="rules" ref="form" :model="form" label-position="left">
|
<el-form :rules="rules" ref="form" :model="form" label-position="left">
|
||||||
<el-form-item label="名字" prop="name">
|
<el-form-item label="名字" prop="name">
|
||||||
@ -54,13 +54,33 @@
|
|||||||
<el-input type="textarea" v-model="form.note"></el-input>
|
<el-input type="textarea" v-model="form.note"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button
|
<el-col :span="12" v-if="recipe_id">
|
||||||
type="primary"
|
<el-button
|
||||||
plain
|
type="primary"
|
||||||
class="summit-recipe"
|
plain
|
||||||
@click="onSubmit(recipe_id)"
|
class="summit-recipe"
|
||||||
>提交</el-button
|
@click="onSubmit(recipe_id)"
|
||||||
>
|
>提交</el-button
|
||||||
|
>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="24" v-else>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
class="summit-recipe"
|
||||||
|
@click="onSubmit(recipe_id)"
|
||||||
|
>提交</el-button
|
||||||
|
>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12" v-if="recipe_id">
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
plain
|
||||||
|
class="summit-recipe"
|
||||||
|
@click="onSubmitDelete(recipe_id)"
|
||||||
|
>删除</el-button
|
||||||
|
>
|
||||||
|
</el-col>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-col>
|
</el-col>
|
||||||
@ -69,6 +89,8 @@
|
|||||||
<script>
|
<script>
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import config from '@/config/index';
|
import config from '@/config/index';
|
||||||
|
import { ElMessage } from 'element-plus';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ['recipe_'],
|
props: ['recipe_'],
|
||||||
watch: {
|
watch: {
|
||||||
@ -77,7 +99,7 @@ export default {
|
|||||||
this.recipe_id = val.id;
|
this.recipe_id = val.id;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data: function() {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
form: {
|
form: {
|
||||||
name: null,
|
name: null,
|
||||||
@ -104,23 +126,41 @@ export default {
|
|||||||
if (!recipe_id) {
|
if (!recipe_id) {
|
||||||
axios
|
axios
|
||||||
.post(config.publicPath + '/recipe/recipe/', data)
|
.post(config.publicPath + '/recipe/recipe/', data)
|
||||||
.then(function() {
|
.then(function () {
|
||||||
|
ElMessage({
|
||||||
|
message: '创建成功.',
|
||||||
|
type: 'success',
|
||||||
|
});
|
||||||
location.reload();
|
location.reload();
|
||||||
})
|
})
|
||||||
.catch(function(error) {
|
.catch(function (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
axios
|
axios
|
||||||
.put(config.publicPath + '/recipe/recipe/' + recipe_id, data)
|
.put(config.publicPath + '/recipe/recipe/' + recipe_id, data)
|
||||||
.then(function() {
|
.then(function () {
|
||||||
location.reload();
|
ElMessage({
|
||||||
|
message: '修改成功.',
|
||||||
|
type: 'success',
|
||||||
|
});
|
||||||
})
|
})
|
||||||
.catch(function(error) {
|
.catch(function (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onSubmitDelete(recipe_id) {
|
||||||
|
axios
|
||||||
|
.delete(config.publicPath + '/recipe/recipe/' + recipe_id)
|
||||||
|
.then(function () {
|
||||||
|
ElMessage.error('删除成功.');
|
||||||
|
location.reload();
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
@ -128,5 +168,6 @@ export default {
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
.summit-recipe {
|
.summit-recipe {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -43,23 +43,64 @@
|
|||||||
/>
|
/>
|
||||||
</van-cell-group>
|
</van-cell-group>
|
||||||
<div class="recipe-create">
|
<div class="recipe-create">
|
||||||
<van-button
|
<van-row gutter="20">
|
||||||
round
|
<van-col span="12" v-if="recipe_id">
|
||||||
type="primary"
|
<van-button
|
||||||
block
|
class="submit-button"
|
||||||
plain
|
round
|
||||||
hairline
|
type="primary"
|
||||||
:disabled="disable_submit"
|
plain
|
||||||
@click="onSubmit(recipe_id)"
|
hairline
|
||||||
:loading="loading"
|
:disabled="disable_submit"
|
||||||
>提交</van-button
|
@click="onSubmit(recipe_id)"
|
||||||
>
|
:loading="loading"
|
||||||
|
>提交</van-button
|
||||||
|
>
|
||||||
|
</van-col>
|
||||||
|
<van-col span="24" v-else>
|
||||||
|
<van-button
|
||||||
|
class="submit-button"
|
||||||
|
round
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
hairline
|
||||||
|
:disabled="disable_submit"
|
||||||
|
@click="onSubmit(recipe_id)"
|
||||||
|
:loading="loading"
|
||||||
|
>提交</van-button
|
||||||
|
>
|
||||||
|
</van-col>
|
||||||
|
<van-col span="12" v-if="recipe_id">
|
||||||
|
<van-button
|
||||||
|
class="submit-button"
|
||||||
|
round
|
||||||
|
type="danger"
|
||||||
|
plain
|
||||||
|
hairline
|
||||||
|
:disabled="disable_submit"
|
||||||
|
@click="onSubmitDelete(recipe_id)"
|
||||||
|
:loading="loading"
|
||||||
|
>删除</van-button
|
||||||
|
>
|
||||||
|
</van-col>
|
||||||
|
</van-row>
|
||||||
</div>
|
</div>
|
||||||
</van-form>
|
</van-form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { Form, Field, CellGroup, Radio, RadioGroup, Rate, Button } from 'vant';
|
import {
|
||||||
|
Form,
|
||||||
|
Field,
|
||||||
|
CellGroup,
|
||||||
|
Radio,
|
||||||
|
RadioGroup,
|
||||||
|
Rate,
|
||||||
|
Button,
|
||||||
|
Toast,
|
||||||
|
Col,
|
||||||
|
Row,
|
||||||
|
} from 'vant';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import config from '@/config/index';
|
import config from '@/config/index';
|
||||||
import router from '@/router/index';
|
import router from '@/router/index';
|
||||||
@ -81,6 +122,8 @@ export default {
|
|||||||
[RadioGroup.name]: RadioGroup,
|
[RadioGroup.name]: RadioGroup,
|
||||||
[Rate.name]: Rate,
|
[Rate.name]: Rate,
|
||||||
[Button.name]: Button,
|
[Button.name]: Button,
|
||||||
|
[Col.name]: Col,
|
||||||
|
[Row.name]: Row,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -118,11 +161,30 @@ export default {
|
|||||||
(response) => (response, router.push({ name: 'RecipeMobileHome' }))
|
(response) => (response, router.push({ name: 'RecipeMobileHome' }))
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
axios
|
axios.put(config.publicPath + '/recipe/recipe/' + recipe_id, data).then(
|
||||||
.put(config.publicPath + '/recipe/recipe/' + recipe_id, data)
|
(Toast.success({
|
||||||
.then((this.loading = false));
|
message: '修改成功',
|
||||||
|
forbidClick: true,
|
||||||
|
duration: 500,
|
||||||
|
}),
|
||||||
|
(this.loading = false))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onSubmitDelete(recipe_id) {
|
||||||
|
if (!this.form.name) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.loading = true;
|
||||||
|
axios.delete(config.publicPath + '/recipe/recipe/' + recipe_id).then(
|
||||||
|
(Toast.success({
|
||||||
|
message: '删除成功',
|
||||||
|
forbidClick: true,
|
||||||
|
duration: 500,
|
||||||
|
}),
|
||||||
|
(this.loading = false))
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
@ -130,4 +192,7 @@ export default {
|
|||||||
.recipe-create {
|
.recipe-create {
|
||||||
margin: 20px 16px;
|
margin: 20px 16px;
|
||||||
}
|
}
|
||||||
|
.submit-button {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
18
recipe/migrations/0003_recipe_status.py
Normal file
18
recipe/migrations/0003_recipe_status.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.2.6 on 2022-02-04 16:13
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('recipe', '0002_auto_20211002_1926'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='recipe',
|
||||||
|
name='status',
|
||||||
|
field=models.CharField(default='active', max_length=32),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -9,6 +9,7 @@ import utils
|
|||||||
class Recipe(models.Model):
|
class Recipe(models.Model):
|
||||||
name = models.CharField(max_length=128)
|
name = models.CharField(max_length=128)
|
||||||
recipe_type = models.CharField(max_length=32, default=const.RECIPE_TYPE_MEAT)
|
recipe_type = models.CharField(max_length=32, default=const.RECIPE_TYPE_MEAT)
|
||||||
|
status = models.CharField(max_length=32, default=const.RECIPE_STATUS_ACTIVE)
|
||||||
note = models.TextField(null=True)
|
note = models.TextField(null=True)
|
||||||
rate = models.IntegerField(default=0)
|
rate = models.IntegerField(default=0)
|
||||||
difficulty = models.IntegerField(default=0)
|
difficulty = models.IntegerField(default=0)
|
||||||
@ -54,7 +55,9 @@ class Recipe(models.Model):
|
|||||||
difficulty = 0
|
difficulty = 0
|
||||||
else:
|
else:
|
||||||
difficulty = 0
|
difficulty = 0
|
||||||
recipe = cls.objects.create(name=name, recipe_type=recipe_type, rate=rate, difficulty=difficulty)
|
recipe = cls.objects.create(
|
||||||
|
name=name, recipe_type=recipe_type, rate=rate, difficulty=difficulty, status=const.RECIPE_STATUS_ACTIVE
|
||||||
|
)
|
||||||
return recipe
|
return recipe
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -125,7 +128,12 @@ class DailyRecipe(models.Model):
|
|||||||
# meat
|
# meat
|
||||||
for x in range(0, 2):
|
for x in range(0, 2):
|
||||||
while True:
|
while True:
|
||||||
recipe = Recipe.objects.filter(recipe_type=const.RECIPE_TYPE_MEAT).order_by('?').first()
|
recipe = (
|
||||||
|
Recipe.objects.filter(recipe_type=const.RECIPE_TYPE_MEAT)
|
||||||
|
.exclude(status=const.RECIPE_STATUS_DELETED)
|
||||||
|
.order_by('?')
|
||||||
|
.first()
|
||||||
|
)
|
||||||
if recipe and recipe.id not in recipes and recipe.id not in prev_recipes:
|
if recipe and recipe.id not in recipes and recipe.id not in prev_recipes:
|
||||||
recipes.append(recipe.id)
|
recipes.append(recipe.id)
|
||||||
break
|
break
|
||||||
@ -138,7 +146,12 @@ class DailyRecipe(models.Model):
|
|||||||
# vegetable
|
# vegetable
|
||||||
for x in range(0, 1):
|
for x in range(0, 1):
|
||||||
while True:
|
while True:
|
||||||
recipe = Recipe.objects.filter(recipe_type=const.RECIPE_TYPE_VEGETABLE).order_by('?').first()
|
recipe = (
|
||||||
|
Recipe.objects.filter(recipe_type=const.RECIPE_TYPE_VEGETABLE)
|
||||||
|
.exclude(status=const.RECIPE_STATUS_DELETED)
|
||||||
|
.order_by('?')
|
||||||
|
.first()
|
||||||
|
)
|
||||||
if recipe and recipe.id not in recipes and recipe.id not in prev_recipes:
|
if recipe and recipe.id not in recipes and recipe.id not in prev_recipes:
|
||||||
recipes.append(recipe.id)
|
recipes.append(recipe.id)
|
||||||
break
|
break
|
||||||
@ -150,7 +163,12 @@ class DailyRecipe(models.Model):
|
|||||||
|
|
||||||
# soup
|
# soup
|
||||||
if random.randint(0, 2):
|
if random.randint(0, 2):
|
||||||
recipe = Recipe.objects.filter(recipe_type=const.RECIPE_TYPE_SOUP).order_by('?').first()
|
recipe = (
|
||||||
|
Recipe.objects.filter(recipe_type=const.RECIPE_TYPE_SOUP)
|
||||||
|
.exclude(status=const.RECIPE_STATUS_DELETED)
|
||||||
|
.order_by('?')
|
||||||
|
.first()
|
||||||
|
)
|
||||||
# if recipe not in recipes and recipe not in prev_recipes:
|
# if recipe not in recipes and recipe not in prev_recipes:
|
||||||
if recipe:
|
if recipe:
|
||||||
recipes.append(recipe.id)
|
recipes.append(recipe.id)
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import recipe.serializers
|
|||||||
from utils import const
|
from utils import const
|
||||||
|
|
||||||
|
|
||||||
class RecipeAPI(rest_framework.generics.RetrieveUpdateAPIView):
|
class RecipeAPI(rest_framework.generics.RetrieveUpdateDestroyAPIView):
|
||||||
|
|
||||||
# authentication_classes = (authentication.TokenAuthentication,
|
# authentication_classes = (authentication.TokenAuthentication,
|
||||||
# authentication.SessionAuthentication,
|
# authentication.SessionAuthentication,
|
||||||
@ -21,6 +21,10 @@ class RecipeAPI(rest_framework.generics.RetrieveUpdateAPIView):
|
|||||||
queryset = recipe.models.Recipe.objects.all()
|
queryset = recipe.models.Recipe.objects.all()
|
||||||
serializer_class = recipe.serializers.RecipeSerializer
|
serializer_class = recipe.serializers.RecipeSerializer
|
||||||
|
|
||||||
|
def perform_destroy(self, instance):
|
||||||
|
instance.status = const.RECIPE_STATUS_DELETED
|
||||||
|
instance.save(update_fields=['status'])
|
||||||
|
|
||||||
|
|
||||||
class RecipeListAPI(rest_framework.generics.ListAPIView, rest_framework.generics.CreateAPIView):
|
class RecipeListAPI(rest_framework.generics.ListAPIView, rest_framework.generics.CreateAPIView):
|
||||||
|
|
||||||
@ -28,7 +32,7 @@ class RecipeListAPI(rest_framework.generics.ListAPIView, rest_framework.generics
|
|||||||
# authentication.SessionAuthentication,
|
# authentication.SessionAuthentication,
|
||||||
# authentication.BasicAuthentication)
|
# authentication.BasicAuthentication)
|
||||||
# permission_classes = (permissions.IsAuthenticated,)
|
# permission_classes = (permissions.IsAuthenticated,)
|
||||||
queryset = recipe.models.Recipe.objects.all()
|
queryset = recipe.models.Recipe.objects.exclude(status=const.RECIPE_STATUS_DELETED)
|
||||||
serializer_class = recipe.serializers.RecipeSerializer
|
serializer_class = recipe.serializers.RecipeSerializer
|
||||||
filterset_fields = {
|
filterset_fields = {
|
||||||
'recipe_type': const.FILTER_EXACT,
|
'recipe_type': const.FILTER_EXACT,
|
||||||
|
|||||||
83
scripts/bitwarden_backup.py
Normal file
83
scripts/bitwarden_backup.py
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
# coding: utf-8
|
||||||
|
from datetime import datetime
|
||||||
|
from dateutil import tz
|
||||||
|
from email import encoders
|
||||||
|
from email.header import Header
|
||||||
|
from email.mime.base import MIMEBase
|
||||||
|
from email.mime.multipart import MIMEMultipart
|
||||||
|
from email.mime.text import MIMEText
|
||||||
|
from email.utils import parseaddr, formataddr
|
||||||
|
import os, tarfile
|
||||||
|
import smtplib
|
||||||
|
|
||||||
|
|
||||||
|
to_zone = tz.gettz('Asia/Shanghai')
|
||||||
|
localtime = datetime.now(tz=to_zone)
|
||||||
|
|
||||||
|
|
||||||
|
def make_targz(output_filename, source_dir):
|
||||||
|
"""
|
||||||
|
一次性打包目录为tar.gz
|
||||||
|
:param output_filename: 压缩文件名
|
||||||
|
:param source_dir: 需要打包的目录
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
with tarfile.open(output_filename, "w:gz") as tar:
|
||||||
|
tar.add(source_dir, arcname=os.path.basename(source_dir))
|
||||||
|
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def send_email(file_name):
|
||||||
|
def _format_addr(s):
|
||||||
|
name, addr = parseaddr(s)
|
||||||
|
return formataddr((Header(name, 'utf-8').encode(), addr))
|
||||||
|
|
||||||
|
smtp_server = 'smtp.gmail.com'
|
||||||
|
smtp_port = 587
|
||||||
|
server = smtplib.SMTP(smtp_server, smtp_port)
|
||||||
|
server.starttls()
|
||||||
|
# 剩下的代码和前面的一模一样:
|
||||||
|
# server.set_debuglevel(1)
|
||||||
|
|
||||||
|
from_addr = ''
|
||||||
|
to_addr = ''
|
||||||
|
to_zone = tz.gettz('Asia/Shanghai')
|
||||||
|
localtime = datetime.now(tz=to_zone)
|
||||||
|
|
||||||
|
msg = MIMEMultipart()
|
||||||
|
msg['From'] = _format_addr('Vaultwarden <%s>' % from_addr)
|
||||||
|
msg['To'] = _format_addr('<%s>' % to_addr)
|
||||||
|
msg['Subject'] = Header('bitwarden 备份 %s' % localtime.strftime('%Y-%m-%d'), 'utf-8').encode()
|
||||||
|
|
||||||
|
# 邮件正文是MIMEText:
|
||||||
|
msg.attach(MIMEText('backup file attached', 'plain', 'utf-8'))
|
||||||
|
|
||||||
|
# 添加附件就是加上一个MIMEBase,从本地读取一个图片:
|
||||||
|
with open(file_name, 'rb') as f:
|
||||||
|
# 设置附件的MIME和文件名
|
||||||
|
mime = MIMEBase('tar.gz', 'tar.gz', filename=file_name)
|
||||||
|
# 加上必要的头信息:
|
||||||
|
mime.add_header('Content-Disposition', 'attachment', filename=file_name)
|
||||||
|
mime.add_header('Content-ID', '<0>')
|
||||||
|
mime.add_header('X-Attachment-Id', '0')
|
||||||
|
# 把附件的内容读进来:
|
||||||
|
mime.set_payload(f.read())
|
||||||
|
# 用Base64编码:
|
||||||
|
encoders.encode_base64(mime)
|
||||||
|
# 添加到MIMEMultipart:
|
||||||
|
msg.attach(mime)
|
||||||
|
|
||||||
|
server.login(from_email, password)
|
||||||
|
server.sendmail(from_addr, [to_addr], msg.as_string())
|
||||||
|
server.quit()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
file_name = '/root/develop/vaultwarden/backup/bitwarden-%s.tar.gz' % localtime.strftime('%Y-%m-%d')
|
||||||
|
if make_targz(file_name, '/root/develop/vaultwarden/vw-data'):
|
||||||
|
send_email(file_name)
|
||||||
@ -224,6 +224,11 @@ class RequestHandler(BaseHTTPRequestHandler):
|
|||||||
subprocess.call("/root/deploy/dsite_prepare.sh")
|
subprocess.call("/root/deploy/dsite_prepare.sh")
|
||||||
subprocess.run(["supervisorctl", "restart", "dsite"])
|
subprocess.run(["supervisorctl", "restart", "dsite"])
|
||||||
self.msg_compoment(access_token, open_id, '🎉 %s 部署成功 🎉' % site_)
|
self.msg_compoment(access_token, open_id, '🎉 %s 部署成功 🎉' % site_)
|
||||||
|
elif site_ == 'dodo':
|
||||||
|
self.msg_compoment(access_token, open_id, '🚧 %s 开始部署 🚧' % site_)
|
||||||
|
subprocess.run(["git", "pull"])
|
||||||
|
self.msg_compoment(access_token, open_id, '🎉 %s 部署成功 🎉' % site_)
|
||||||
|
subprocess.run(["supervisorctl", "restart", "dodo"])
|
||||||
else:
|
else:
|
||||||
self.msg_compoment(access_token, open_id, '⚠️ %s 不存在 ⚠️' % site_)
|
self.msg_compoment(access_token, open_id, '⚠️ %s 不存在 ⚠️' % site_)
|
||||||
elif orig_text.startswith('/菜谱 '):
|
elif orig_text.startswith('/菜谱 '):
|
||||||
|
|||||||
5
scripts/dsite_prepare.sh
Normal file
5
scripts/dsite_prepare.sh
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
/root/.pyenv/versions/py37/bin/pip install -r /root/deploy/dsite/develop_requirements.txt
|
||||||
|
/root/.pyenv/versions/py37/bin/python /root/deploy/dsite/manage.py collectstatic --noinput
|
||||||
|
/root/.pyenv/versions/py37/bin/python /root/deploy/dsite/manage.py migrate
|
||||||
5
scripts/restart_dodo.sh
Normal file
5
scripts/restart_dodo.sh
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
supervisorctl restart dodo && \
|
||||||
|
curl -X POST -H "Content-Type: application/json" \
|
||||||
|
-d '{"msg_type":"text","content":{"text":"🎉 dodo 部署成功 🎉"}}' \
|
||||||
|
https://open.feishu.cn/open-apis/bot/v2/hook/57cfa603-6154-4055-a739-210028171d10
|
||||||
@ -11,6 +11,9 @@ RECIPE_TYPE_MEAT = 'meat'
|
|||||||
RECIPE_TYPE_VEGETABLE = 'vegetable'
|
RECIPE_TYPE_VEGETABLE = 'vegetable'
|
||||||
RECIPE_TYPE_SOUP = 'soup'
|
RECIPE_TYPE_SOUP = 'soup'
|
||||||
|
|
||||||
|
RECIPE_STATUS_ACTIVE = 'active'
|
||||||
|
RECIPE_STATUS_DELETED = 'deleted'
|
||||||
|
|
||||||
RECIPE_TYPE_CHOICE = [RECIPE_TYPE_MEAT, RECIPE_TYPE_VEGETABLE, RECIPE_TYPE_SOUP]
|
RECIPE_TYPE_CHOICE = [RECIPE_TYPE_MEAT, RECIPE_TYPE_VEGETABLE, RECIPE_TYPE_SOUP]
|
||||||
|
|
||||||
FILTER_EXACT = ['exact']
|
FILTER_EXACT = ['exact']
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user