aboutsummaryrefslogtreecommitdiffstats
path: root/app/Controllers/Http/RecipeController.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/Controllers/Http/RecipeController.js')
-rw-r--r--app/Controllers/Http/RecipeController.js226
1 files changed, 0 insertions, 226 deletions
diff --git a/app/Controllers/Http/RecipeController.js b/app/Controllers/Http/RecipeController.js
deleted file mode 100644
index cbdddaf..0000000
--- a/app/Controllers/Http/RecipeController.js
+++ /dev/null
@@ -1,226 +0,0 @@
1const Recipe = use('App/Models/Recipe');
2const Helpers = use('Helpers');
3const Drive = use('Drive');
4const {
5 validateAll,
6} = use('Validator');
7const Env = use('Env');
8
9const targz = require('targz');
10const path = require('path');
11const fs = require('fs-extra');
12const semver = require('semver');
13
14const compress = (src, dest) => new Promise((resolve, reject) => {
15 targz.compress({
16 src,
17 dest,
18 }, (err) => {
19 if (err) {
20 reject(err);
21 } else {
22 resolve(dest);
23 }
24 });
25});
26
27class RecipeController {
28 // List official and custom recipes
29 async list({
30 response,
31 }) {
32 const officialRecipes = fs.readJsonSync(path.join(Helpers.appRoot(), 'recipes', 'all.json'));
33 const customRecipesArray = (await Recipe.all()).rows;
34 const customRecipes = customRecipesArray.map((recipe) => ({
35 id: recipe.recipeId,
36 name: recipe.name,
37 ...typeof recipe.data === 'string' ? JSON.parse(recipe.data) : recipe.data,
38 }));
39
40 const recipes = [
41 ...officialRecipes,
42 ...customRecipes,
43 ];
44
45 return response.send(recipes);
46 }
47
48 // Create a new recipe using the new.html page
49 async create({
50 request,
51 response,
52 }) {
53 // Check if recipe creation is enabled
54 if (Env.get('IS_CREATION_ENABLED') == 'false') { // eslint-disable-line eqeqeq
55 return response.send('This server doesn\'t allow the creation of new recipes.');
56 }
57
58 // Validate user input
59 const validation = await validateAll(request.all(), {
60 name: 'required|string',
61 id: 'required|unique:recipes,recipeId',
62 author: 'required|accepted',
63 svg: 'required|url',
64 });
65 if (validation.fails()) {
66 return response.status(401).send({
67 message: 'Invalid POST arguments',
68 messages: validation.messages(),
69 status: 401,
70 });
71 }
72
73 const data = request.all();
74
75 if (!data.id) {
76 return response.send('Please provide an ID');
77 }
78
79 // Check for invalid characters
80 if (/\.{1,}/.test(data.id) || /\/{1,}/.test(data.id)) {
81 return response.send('Invalid recipe name. Your recipe name may not contain "." or "/"');
82 }
83
84 // Clear temporary recipe folder
85 await fs.emptyDir(Helpers.tmpPath('recipe'));
86
87 // Move uploaded files to temporary path
88 const files = request.file('files');
89 await files.moveAll(Helpers.tmpPath('recipe'));
90
91 // Compress files to .tar.gz file
92 const source = Helpers.tmpPath('recipe');
93 const destination = path.join(Helpers.appRoot(), `/recipes/archives/${data.id}.tar.gz`);
94
95 compress(
96 source,
97 destination,
98 );
99
100 // Create recipe in db
101 await Recipe.create({
102 name: data.name,
103 recipeId: data.id,
104 data: JSON.stringify({
105 author: data.author,
106 featured: false,
107 version: '1.0.0',
108 icons: {
109 svg: data.svg,
110 },
111 }),
112 });
113
114 return response.send('Created new recipe');
115 }
116
117 // Search official and custom recipes
118 async search({
119 request,
120 response,
121 }) {
122 // Validate user input
123 const validation = await validateAll(request.all(), {
124 needle: 'required',
125 });
126 if (validation.fails()) {
127 return response.status(401).send({
128 message: 'Please provide a needle',
129 messages: validation.messages(),
130 status: 401,
131 });
132 }
133
134 const needle = request.input('needle');
135
136 // Get results
137 let results;
138
139 if (needle === 'ferdium:custom') {
140 const dbResults = (await Recipe.all()).toJSON();
141 results = dbResults.map((recipe) => ({
142 id: recipe.recipeId,
143 name: recipe.name,
144 ...typeof recipe.data === 'string' ? JSON.parse(recipe.data) : recipe.data,
145 }));
146 } else {
147 const localResultsArray = (await Recipe.query().where('name', 'LIKE', `%${needle}%`).fetch()).toJSON();
148 results = localResultsArray.map((recipe) => ({
149 id: recipe.recipeId,
150 name: recipe.name,
151 ...typeof recipe.data === 'string' ? JSON.parse(recipe.data) : recipe.data,
152 }));
153 }
154
155 return response.send(results);
156 }
157
158 popularRecipes({
159 response,
160 }) {
161 return response.send(
162 fs
163 .readJsonSync(path.join(
164 Helpers.appRoot(), 'recipes', 'all.json',
165 ))
166 .filter((recipe) => recipe.featured),
167 );
168 }
169
170 update({ request, response }) {
171 const updates = [];
172 const recipes = request.all();
173 const allJson = fs.readJsonSync(path.join(
174 Helpers.appRoot(), 'recipes', 'all.json',
175 ));
176
177 for (const recipe of Object.keys(recipes)) {
178 const version = recipes[recipe];
179
180 // Find recipe in local recipe repository
181 const localRecipe = allJson.find(r => r.id === recipe);
182 if (localRecipe && semver.lt(version, localRecipe.version)) {
183 updates.push(recipe);
184 }
185 }
186
187 return response.send(updates);
188 }
189
190 // Download a recipe
191 async download({
192 response,
193 params,
194 }) {
195 // Validate user input
196 const validation = await validateAll(params, {
197 recipe: 'required|accepted',
198 });
199 if (validation.fails()) {
200 return response.status(401).send({
201 message: 'Please provide a recipe ID',
202 messages: validation.messages(),
203 status: 401,
204 });
205 }
206
207 const service = params.recipe;
208
209 // Check for invalid characters
210 if (/\.{1,}/.test(service) || /\/{1,}/.test(service)) {
211 return response.send('Invalid recipe name');
212 }
213
214 // Check if recipe exists in recipes folder
215 if (await Drive.exists(`${service}.tar.gz`)) {
216 return response.type('.tar.gz').send(await Drive.get(`${service}.tar.gz`));
217 }
218
219 return response.status(400).send({
220 message: 'Recipe not found',
221 code: 'recipe-not-found',
222 });
223 }
224}
225
226module.exports = RecipeController;