diff --git a/.db.py.swp b/.db.py.swp deleted file mode 100644 index 3434ac2..0000000 Binary files a/.db.py.swp and /dev/null differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eb9e3ff --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +*.swp +package-lock.json +yarn.lock + +.DS_Store +node_modules/ +/cuizin/dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln diff --git a/build/build.js b/build/build.js new file mode 100644 index 0000000..8f2ad8a --- /dev/null +++ b/build/build.js @@ -0,0 +1,41 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const rm = require('rimraf') +const path = require('path') +const chalk = require('chalk') +const webpack = require('webpack') +const config = require('../config') +const webpackConfig = require('./webpack.prod.conf') + +const spinner = ora('building for production...') +spinner.start() + +rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { + if (err) throw err + webpack(webpackConfig, (err, stats) => { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) + }) +}) diff --git a/build/check-versions.js b/build/check-versions.js new file mode 100644 index 0000000..3ef972a --- /dev/null +++ b/build/check-versions.js @@ -0,0 +1,54 @@ +'use strict' +const chalk = require('chalk') +const semver = require('semver') +const packageConfig = require('../package.json') +const shell = require('shelljs') + +function exec (cmd) { + return require('child_process').execSync(cmd).toString().trim() +} + +const versionRequirements = [ + { + name: 'node', + currentVersion: semver.clean(process.version), + versionRequirement: packageConfig.engines.node + } +] + +if (shell.which('npm')) { + versionRequirements.push({ + name: 'npm', + currentVersion: exec('npm --version'), + versionRequirement: packageConfig.engines.npm + }) +} + +module.exports = function () { + const warnings = [] + + for (let i = 0; i < versionRequirements.length; i++) { + const mod = versionRequirements[i] + + if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { + warnings.push(mod.name + ': ' + + chalk.red(mod.currentVersion) + ' should be ' + + chalk.green(mod.versionRequirement) + ) + } + } + + if (warnings.length) { + console.log('') + console.log(chalk.yellow('To use this template, you must update following to modules:')) + console.log() + + for (let i = 0; i < warnings.length; i++) { + const warning = warnings[i] + console.log(' ' + warning) + } + + console.log() + process.exit(1) + } +} diff --git a/build/logo.png b/build/logo.png new file mode 100644 index 0000000..f3d2503 Binary files /dev/null and b/build/logo.png differ diff --git a/build/utils.js b/build/utils.js new file mode 100644 index 0000000..e534fb0 --- /dev/null +++ b/build/utils.js @@ -0,0 +1,101 @@ +'use strict' +const path = require('path') +const config = require('../config') +const ExtractTextPlugin = require('extract-text-webpack-plugin') +const packageConfig = require('../package.json') + +exports.assetsPath = function (_path) { + const assetsSubDirectory = process.env.NODE_ENV === 'production' + ? config.build.assetsSubDirectory + : config.dev.assetsSubDirectory + + return path.posix.join(assetsSubDirectory, _path) +} + +exports.cssLoaders = function (options) { + options = options || {} + + const cssLoader = { + loader: 'css-loader', + options: { + sourceMap: options.sourceMap + } + } + + const postcssLoader = { + loader: 'postcss-loader', + options: { + sourceMap: options.sourceMap + } + } + + // generate loader string to be used with extract text plugin + function generateLoaders (loader, loaderOptions) { + const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader] + + if (loader) { + loaders.push({ + loader: loader + '-loader', + options: Object.assign({}, loaderOptions, { + sourceMap: options.sourceMap + }) + }) + } + + // Extract CSS when that option is specified + // (which is the case during production build) + if (options.extract) { + return ExtractTextPlugin.extract({ + use: loaders, + fallback: 'vue-style-loader' + }) + } else { + return ['vue-style-loader'].concat(loaders) + } + } + + // https://vue-loader.vuejs.org/en/configurations/extract-css.html + return { + css: generateLoaders(), + postcss: generateLoaders(), + less: generateLoaders('less'), + sass: generateLoaders('sass', { indentedSyntax: true }), + scss: generateLoaders('sass'), + stylus: generateLoaders('stylus'), + styl: generateLoaders('stylus') + } +} + +// Generate loaders for standalone style files (outside of .vue) +exports.styleLoaders = function (options) { + const output = [] + const loaders = exports.cssLoaders(options) + + for (const extension in loaders) { + const loader = loaders[extension] + output.push({ + test: new RegExp('\\.' + extension + '$'), + use: loader + }) + } + + return output +} + +exports.createNotifierCallback = () => { + const notifier = require('node-notifier') + + return (severity, errors) => { + if (severity !== 'error') return + + const error = errors[0] + const filename = error.file && error.file.split('!').pop() + + notifier.notify({ + title: packageConfig.name, + message: severity + ': ' + error.name, + subtitle: filename || '', + icon: path.join(__dirname, 'logo.png') + }) + } +} diff --git a/build/vue-loader.conf.js b/build/vue-loader.conf.js new file mode 100644 index 0000000..33ed58b --- /dev/null +++ b/build/vue-loader.conf.js @@ -0,0 +1,22 @@ +'use strict' +const utils = require('./utils') +const config = require('../config') +const isProduction = process.env.NODE_ENV === 'production' +const sourceMapEnabled = isProduction + ? config.build.productionSourceMap + : config.dev.cssSourceMap + +module.exports = { + loaders: utils.cssLoaders({ + sourceMap: sourceMapEnabled, + extract: isProduction + }), + cssSourceMap: sourceMapEnabled, + cacheBusting: config.dev.cacheBusting, + transformToRequire: { + video: ['src', 'poster'], + source: 'src', + img: 'src', + image: 'xlink:href' + } +} diff --git a/build/webpack.base.conf.js b/build/webpack.base.conf.js new file mode 100644 index 0000000..9ed8095 --- /dev/null +++ b/build/webpack.base.conf.js @@ -0,0 +1,92 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const config = require('../config') +const vueLoaderConfig = require('./vue-loader.conf') + +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + +const createLintingRule = () => ({ + test: /\.(js|vue)$/, + loader: 'eslint-loader', + enforce: 'pre', + include: [resolve('src'), resolve('test')], + options: { + formatter: require('eslint-friendly-formatter'), + emitWarning: !config.dev.showEslintErrorsInOverlay + } +}) + +module.exports = { + context: path.resolve(__dirname, '../cuizin'), + entry: { + app: './src/main.js' + }, + output: { + path: config.build.assetsRoot, + filename: '[name].js', + publicPath: process.env.NODE_ENV === 'production' + ? config.build.assetsPublicPath + : config.dev.assetsPublicPath + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src'), + } + }, + module: { + rules: [ + ...(config.dev.useEslint ? [createLintingRule()] : []), + { + test: /\.vue$/, + loader: 'vue-loader', + options: vueLoaderConfig + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + } + ] + }, + node: { + // prevent webpack from injecting useless setImmediate polyfill because Vue + // source contains it (although only uses it if it's native). + setImmediate: false, + // prevent webpack from injecting mocks to Node native modules + // that does not make sense for the client + dgram: 'empty', + fs: 'empty', + net: 'empty', + tls: 'empty', + child_process: 'empty' + } +} diff --git a/build/webpack.dev.conf.js b/build/webpack.dev.conf.js new file mode 100755 index 0000000..250e55c --- /dev/null +++ b/build/webpack.dev.conf.js @@ -0,0 +1,95 @@ +'use strict' +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const path = require('path') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') +const portfinder = require('portfinder') + +const HOST = process.env.HOST +const PORT = process.env.PORT && Number(process.env.PORT) + +const devWebpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) + }, + // cheap-module-eval-source-map is faster for development + devtool: config.dev.devtool, + + // these devServer options should be customized in /config/index.js + devServer: { + clientLogLevel: 'warning', + historyApiFallback: { + rewrites: [ + { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, + ], + }, + hot: true, + contentBase: false, // since we use CopyWebpackPlugin. + compress: true, + host: HOST || config.dev.host, + port: PORT || config.dev.port, + open: config.dev.autoOpenBrowser, + overlay: config.dev.errorOverlay + ? { warnings: false, errors: true } + : false, + publicPath: config.dev.assetsPublicPath, + proxy: config.dev.proxyTable, + quiet: true, // necessary for FriendlyErrorsPlugin + watchOptions: { + poll: config.dev.poll, + } + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env': require('../config/dev.env') + }), + new webpack.HotModuleReplacementPlugin(), + new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. + new webpack.NoEmitOnErrorsPlugin(), + // https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: 'index.html', + template: 'index.html', + inject: true + }), + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../cuizin/static'), + to: config.dev.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +module.exports = new Promise((resolve, reject) => { + portfinder.basePort = process.env.PORT || config.dev.port + portfinder.getPort((err, port) => { + if (err) { + reject(err) + } else { + // publish the new Port, necessary for e2e tests + process.env.PORT = port + // add port to devServer config + devWebpackConfig.devServer.port = port + + // Add FriendlyErrorsPlugin + devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ + compilationSuccessInfo: { + messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], + }, + onErrors: config.dev.notifyOnErrors + ? utils.createNotifierCallback() + : undefined + })) + + resolve(devWebpackConfig) + } + }) +}) diff --git a/build/webpack.prod.conf.js b/build/webpack.prod.conf.js new file mode 100644 index 0000000..fcf7bc5 --- /dev/null +++ b/build/webpack.prod.conf.js @@ -0,0 +1,145 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const ExtractTextPlugin = require('extract-text-webpack-plugin') +const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') +const UglifyJsPlugin = require('uglifyjs-webpack-plugin') + +const env = require('../config/prod.env') + +const webpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ + sourceMap: config.build.productionSourceMap, + extract: true, + usePostCSS: true + }) + }, + devtool: config.build.productionSourceMap ? config.build.devtool : false, + output: { + path: config.build.assetsRoot, + filename: utils.assetsPath('js/[name].[chunkhash].js'), + chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') + }, + plugins: [ + // http://vuejs.github.io/vue-loader/en/workflow/production.html + new webpack.DefinePlugin({ + 'process.env': env + }), + new UglifyJsPlugin({ + uglifyOptions: { + compress: { + warnings: false + } + }, + sourceMap: config.build.productionSourceMap, + parallel: true + }), + // extract css into its own file + new ExtractTextPlugin({ + filename: utils.assetsPath('css/[name].[contenthash].css'), + // Setting the following option to `false` will not extract CSS from codesplit chunks. + // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. + // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, + // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 + allChunks: true, + }), + // Compress extracted CSS. We are using this plugin so that possible + // duplicated CSS from different components can be deduped. + new OptimizeCSSPlugin({ + cssProcessorOptions: config.build.productionSourceMap + ? { safe: true, map: { inline: false } } + : { safe: true } + }), + // generate dist index.html with correct asset hash for caching. + // you can customize output by editing /index.html + // see https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: config.build.index, + template: 'index.html', + inject: true, + minify: { + removeComments: true, + collapseWhitespace: true, + removeAttributeQuotes: true + // more options: + // https://github.com/kangax/html-minifier#options-quick-reference + }, + // necessary to consistently work with multiple chunks via CommonsChunkPlugin + chunksSortMode: 'dependency' + }), + // keep module.id stable when vendor modules does not change + new webpack.HashedModuleIdsPlugin(), + // enable scope hoisting + new webpack.optimize.ModuleConcatenationPlugin(), + // split vendor js into its own file + new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor', + minChunks (module) { + // any required modules inside node_modules are extracted to vendor + return ( + module.resource && + /\.js$/.test(module.resource) && + module.resource.indexOf( + path.join(__dirname, '../node_modules') + ) === 0 + ) + } + }), + // extract webpack runtime and module manifest to its own file in order to + // prevent vendor hash from being updated whenever app bundle is updated + new webpack.optimize.CommonsChunkPlugin({ + name: 'manifest', + minChunks: Infinity + }), + // This instance extracts shared chunks from code splitted chunks and bundles them + // in a separate chunk, similar to the vendor chunk + // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk + new webpack.optimize.CommonsChunkPlugin({ + name: 'app', + async: 'vendor-async', + children: true, + minChunks: 3 + }), + + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../cuizin/static'), + to: config.build.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +if (config.build.productionGzip) { + const CompressionWebpackPlugin = require('compression-webpack-plugin') + + webpackConfig.plugins.push( + new CompressionWebpackPlugin({ + asset: '[path].gz[query]', + algorithm: 'gzip', + test: new RegExp( + '\\.(' + + config.build.productionGzipExtensions.join('|') + + ')$' + ), + threshold: 10240, + minRatio: 0.8 + }) + ) +} + +if (config.build.bundleAnalyzerReport) { + const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin + webpackConfig.plugins.push(new BundleAnalyzerPlugin()) +} + +module.exports = webpackConfig diff --git a/config/dev.env.js b/config/dev.env.js new file mode 100644 index 0000000..1e22973 --- /dev/null +++ b/config/dev.env.js @@ -0,0 +1,7 @@ +'use strict' +const merge = require('webpack-merge') +const prodEnv = require('./prod.env') + +module.exports = merge(prodEnv, { + NODE_ENV: '"development"' +}) diff --git a/config/index.js b/config/index.js new file mode 100644 index 0000000..394257e --- /dev/null +++ b/config/index.js @@ -0,0 +1,76 @@ +'use strict' +// Template version: 1.2.8 +// see http://vuejs-templates.github.io/webpack for documentation. + +const path = require('path') + +module.exports = { + dev: { + + // Paths + assetsSubDirectory: path.resolve(__dirname, '../cuizin/static'), + assetsPublicPath: '/', + proxyTable: {}, + + // Various Dev Server settings + host: 'localhost', // can be overwritten by process.env.HOST + port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined + autoOpenBrowser: false, + errorOverlay: true, + notifyOnErrors: true, + poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- + + // Use Eslint Loader? + // If true, your code will be linted during bundling and + // linting errors and warnings will be shown in the console. + useEslint: true, + // If true, eslint errors and warnings will also be shown in the error overlay + // in the browser. + showEslintErrorsInOverlay: false, + + /** + * Source Maps + */ + + // https://webpack.js.org/configuration/devtool/#development + devtool: 'cheap-module-eval-source-map', + + // If you have problems debugging vue-files in devtools, + // set this to false - it *may* help + // https://vue-loader.vuejs.org/en/options.html#cachebusting + cacheBusting: true, + + cssSourceMap: true, + }, + + build: { + // Template for index.html + index: path.resolve(__dirname, '../cuizin/dist/index.html'), + + // Paths + assetsRoot: path.resolve(__dirname, '../cuizin/dist'), + assetsSubDirectory: 'static', + assetsPublicPath: '/', + + /** + * Source Maps + */ + + productionSourceMap: true, + // https://webpack.js.org/configuration/devtool/#production + devtool: '#source-map', + + // Gzip off by default as many popular static hosts such as + // Surge or Netlify already gzip all static assets for you. + // Before setting to `true`, make sure to: + // npm install --save-dev compression-webpack-plugin + productionGzip: false, + productionGzipExtensions: ['js', 'css'], + + // Run the build command with an extra argument to + // View the bundle analyzer report after build finishes: + // `npm run build --report` + // Set to `true` or `false` to always turn it on or off + bundleAnalyzerReport: process.env.npm_config_report + } +} diff --git a/config/prod.env.js b/config/prod.env.js new file mode 100644 index 0000000..a6f9976 --- /dev/null +++ b/config/prod.env.js @@ -0,0 +1,4 @@ +'use strict' +module.exports = { + NODE_ENV: '"production"' +} diff --git a/main.py b/cuizin/__init__.py similarity index 75% rename from main.py rename to cuizin/__init__.py index adb7c35..819da74 100644 --- a/main.py +++ b/cuizin/__init__.py @@ -5,10 +5,15 @@ import sys from weboob.core.ouiboube import WebNip from weboob.tools.json import WeboobEncoder +from cuizin import db + BACKENDS = ['750g', 'allrecipes', 'cuisineaz', 'marmiton', 'supertoinette'] -def __main__(url, modules_path=None): +def add_recipe(url, modules_path=None): + db.database.connect() + db.database.create_tables([db.Recipe]) + webnip = WebNip(modules_path=modules_path) backends = [ @@ -24,10 +29,5 @@ def __main__(url, modules_path=None): browser = backend.browser if url.startswith(browser.BASEURL): browser.location(url) - recipe = browser.page.get_recipe() - print(json.dumps(recipe, cls=WeboobEncoder)) + db.Recipe.from_weboob(browser.page.get_recipe()).save() break - - -if __name__ == "__main__": - __main__(sys.argv[1]) diff --git a/cuizin/__main__.py b/cuizin/__main__.py new file mode 100644 index 0000000..f19e359 --- /dev/null +++ b/cuizin/__main__.py @@ -0,0 +1,12 @@ +import os + +from cuizin import web + + +app = application = web.app + +if __name__ == '__main__': + HOST = os.environ.get('CUIZIN_HOST', 'localhost') + PORT = os.environ.get('CUIZIN_PORT', '8080') + DEBUG = os.environ.get('CUIZIN_DEBUG', False) + app.run(host=HOST, port=PORT, debug=DEBUG) diff --git a/cuizin/__pycache__/__init__.cpython-36.pyc b/cuizin/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000..99af6d0 Binary files /dev/null and b/cuizin/__pycache__/__init__.cpython-36.pyc differ diff --git a/cuizin/__pycache__/__main__.cpython-36.pyc b/cuizin/__pycache__/__main__.cpython-36.pyc new file mode 100644 index 0000000..ad3accf Binary files /dev/null and b/cuizin/__pycache__/__main__.cpython-36.pyc differ diff --git a/cuizin/__pycache__/db.cpython-36.pyc b/cuizin/__pycache__/db.cpython-36.pyc new file mode 100644 index 0000000..7858d23 Binary files /dev/null and b/cuizin/__pycache__/db.cpython-36.pyc differ diff --git a/cuizin/db.py b/cuizin/db.py new file mode 100644 index 0000000..6cfd5b2 --- /dev/null +++ b/cuizin/db.py @@ -0,0 +1,45 @@ +import base64 + +import requests +from peewee import ( + Model, SqliteDatabase, + BlobField, CharField, IntegerField, TextField +) +from playhouse.shortcuts import model_to_dict + + +database = SqliteDatabase('recipes.db') + + +class Recipe(Model): + title = CharField() + author = CharField(null=True) + picture = BlobField(null=True) + short_description = TextField(null=True) + nb_person = None # TODO + preparation_time = IntegerField(null=True) # In minutes + cooking_time = IntegerField(null=True) # In minutes + ingredients = None # TODO + instructions = TextField() + comments = None # TODO + + class Meta: + database = database + + @staticmethod + def from_weboob(obj): + recipe = Recipe() + for field in ['title', 'author', 'picture_url', 'short_description', + 'preparation_time', 'cooking_time', 'instructions']: + value = getattr(obj, field) + if value: + setattr(recipe, field, value) + recipe.picture = requests.get(obj.picture_url).content + return recipe + + def to_dict(self): + serialized = model_to_dict(self) + serialized['picture'] = base64.b64encode( + serialized['picture'] + ).decode('utf-8') + return serialized diff --git a/cuizin/js_src/.gitrepo b/cuizin/js_src/.gitrepo new file mode 100644 index 0000000..8ba7ed8 --- /dev/null +++ b/cuizin/js_src/.gitrepo @@ -0,0 +1,12 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = https://github.com/vuetifyjs/templates-common.git + branch = subrepo/webpack-src + commit = 090741fa8ba4da0c6f85db64eff64550704123e1 + parent = e05204fc0583a8c99f1963ce873eba1266838215 + method = merge + cmdver = 0.4.0 diff --git a/cuizin/js_src/App.vue b/cuizin/js_src/App.vue new file mode 100644 index 0000000..397f89a --- /dev/null +++ b/cuizin/js_src/App.vue @@ -0,0 +1,91 @@ + + + diff --git a/cuizin/js_src/assets/logo.png b/cuizin/js_src/assets/logo.png new file mode 100755 index 0000000..a2ce235 Binary files /dev/null and b/cuizin/js_src/assets/logo.png differ diff --git a/cuizin/js_src/components/HelloWorld.vue b/cuizin/js_src/components/HelloWorld.vue new file mode 100644 index 0000000..6bbe5cd --- /dev/null +++ b/cuizin/js_src/components/HelloWorld.vue @@ -0,0 +1,35 @@ + + + + diff --git a/cuizin/js_src/main.js b/cuizin/js_src/main.js new file mode 100644 index 0000000..6ac070d --- /dev/null +++ b/cuizin/js_src/main.js @@ -0,0 +1,20 @@ +// The Vue build version to load with the `import` command +// (runtime-only or standalone) has been set in webpack.base.conf with an alias. +import Vue from 'vue'; +import Vuetify from 'vuetify'; +import 'vuetify/dist/vuetify.min.css'; + +import App from './App'; +import router from './router'; + +Vue.use(Vuetify); + +Vue.config.productionTip = false; + +/* eslint-disable no-new */ +new Vue({ + el: '#app', + router, + components: { App }, + template: '', +}); diff --git a/cuizin/js_src/router/index.js b/cuizin/js_src/router/index.js new file mode 100644 index 0000000..50d7d36 --- /dev/null +++ b/cuizin/js_src/router/index.js @@ -0,0 +1,15 @@ +import Vue from 'vue'; +import Router from 'vue-router'; +import HelloWorld from '@/components/HelloWorld'; + +Vue.use(Router); + +export default new Router({ + routes: [ + { + path: '/', + name: 'HelloWorld', + component: HelloWorld, + }, + ], +}); diff --git a/cuizin/static/.babelrc b/cuizin/static/.babelrc new file mode 100644 index 0000000..3a280ba --- /dev/null +++ b/cuizin/static/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + ["env", { + "modules": false, + "targets": { + "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] + } + }], + "stage-2" + ], + "plugins": ["transform-vue-jsx", "transform-runtime"] +} diff --git a/cuizin/static/.editorconfig b/cuizin/static/.editorconfig new file mode 100644 index 0000000..9d08a1a --- /dev/null +++ b/cuizin/static/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/cuizin/static/.eslintignore b/cuizin/static/.eslintignore new file mode 100644 index 0000000..e1fcc9c --- /dev/null +++ b/cuizin/static/.eslintignore @@ -0,0 +1,4 @@ +/build/ +/config/ +/dist/ +/*.js diff --git a/cuizin/static/.eslintrc.js b/cuizin/static/.eslintrc.js new file mode 100644 index 0000000..e319040 --- /dev/null +++ b/cuizin/static/.eslintrc.js @@ -0,0 +1,49 @@ +// https://eslint.org/docs/user-guide/configuring + +module.exports = { + root: true, + parser: 'babel-eslint', + parserOptions: { + sourceType: 'module' + }, + env: { + browser: true, + }, + extends: 'airbnb-base', + // required to lint *.vue files + plugins: [ + 'html' + ], + // check if imports actually resolve + settings: { + 'import/resolver': { + webpack: { + config: 'build/webpack.base.conf.js' + } + } + }, + // add your custom rules here + rules: { + // don't require .vue extension when importing + 'import/extensions': ['error', 'always', { + js: 'never', + vue: 'never' + }], + // disallow reassignment of function parameters + // disallow parameter object manipulation except for specific exclusions + 'no-param-reassign': ['error', { + props: true, + ignorePropertyModificationsFor: [ + 'state', // for vuex state + 'acc', // for reduce accumulators + 'e' // for e.returnvalue + ] + }], + // allow optionalDependencies + 'import/no-extraneous-dependencies': ['error', { + optionalDependencies: ['test/unit/index.js'] + }], + // allow debugger during development + 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' + } +} diff --git a/cuizin/static/.postcssrc.js b/cuizin/static/.postcssrc.js new file mode 100644 index 0000000..eee3e92 --- /dev/null +++ b/cuizin/static/.postcssrc.js @@ -0,0 +1,10 @@ +// https://github.com/michael-ciniawsky/postcss-load-config + +module.exports = { + "plugins": { + "postcss-import": {}, + "postcss-url": {}, + // to edit target browsers: use "browserslist" field in package.json + "autoprefixer": {} + } +} diff --git a/cuizin/static/index.html b/cuizin/static/index.html new file mode 100644 index 0000000..b8d6a02 --- /dev/null +++ b/cuizin/static/index.html @@ -0,0 +1,13 @@ + + + + + + cuizin + + + +
+ + + diff --git a/cuizin/web.py b/cuizin/web.py new file mode 100644 index 0000000..06c67cb --- /dev/null +++ b/cuizin/web.py @@ -0,0 +1,39 @@ +import bottle + +from cuizin import db + + +bottle.Bottle() + + +@app.get('/api/v1') +def api_v1_index(): + return { + 'recipes': '/api/v1/recipes' + } + + +@app.get('/api/v1/recipes') +def api_v1_recipes(): + return { + 'recipes': [ + recipe.to_dict() for recipe in db.Recipe.select() + ] + } + + +@app.get('/api/v1/recipe/:id') +def api_v1_recipe(id): + return { + 'recipes': [ + recipe.to_dict() for recipe in db.Recipe.select().where( + db.Recipe.id == id + ) + ] + } + + +@app.get('/static/') +def get_static_files(filename): + """Get Static files""" + return bottle.static_file(filename, root=) diff --git a/db.py b/db.py deleted file mode 100644 index ccc17a5..0000000 --- a/db.py +++ /dev/null @@ -1,12 +0,0 @@ -from peewee import * - -db = SqliteDatabase('people.db') - - -class Person(Model): - name = CharField() - birthday = DateField() - is_relative = BooleanField() - - class Meta: - database = db diff --git a/package.json b/package.json new file mode 100644 index 0000000..89098e7 --- /dev/null +++ b/package.json @@ -0,0 +1,72 @@ +{ + "name": "cuizin", + "version": "1.0.0", + "description": "Store your recipes!", + "author": "Phyks (Lucas Verney) ", + "private": true, + "scripts": { + "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", + "start": "npm run dev", + "lint": "eslint --ext .js,.vue src", + "build": "node build/build.js" + }, + "dependencies": { + "vue": "^2.5.2", + "vue-router": "^3.0.1", + "vuetify": "^1.0.0" + }, + "devDependencies": { + "autoprefixer": "^7.1.2", + "babel-core": "^6.22.1", + "babel-eslint": "^7.1.1", + "babel-helper-vue-jsx-merge-props": "^2.0.3", + "babel-loader": "^7.1.1", + "babel-plugin-syntax-jsx": "^6.18.0", + "babel-plugin-transform-runtime": "^6.22.0", + "babel-plugin-transform-vue-jsx": "^3.5.0", + "babel-preset-env": "^1.3.2", + "babel-preset-stage-2": "^6.22.0", + "chalk": "^2.0.1", + "copy-webpack-plugin": "^4.0.1", + "css-loader": "^0.28.0", + "eslint": "^3.19.0", + "eslint-config-airbnb-base": "^11.3.0", + "eslint-friendly-formatter": "^3.0.0", + "eslint-import-resolver-webpack": "^0.8.3", + "eslint-loader": "^1.7.1", + "eslint-plugin-html": "^3.0.0", + "eslint-plugin-import": "^2.7.0", + "extract-text-webpack-plugin": "^3.0.0", + "file-loader": "^1.1.4", + "friendly-errors-webpack-plugin": "^1.6.1", + "html-webpack-plugin": "^2.30.1", + "node-notifier": "^5.1.2", + "optimize-css-assets-webpack-plugin": "^3.2.0", + "ora": "^1.2.0", + "portfinder": "^1.0.13", + "postcss-import": "^11.0.0", + "postcss-loader": "^2.0.8", + "postcss-url": "^7.2.1", + "rimraf": "^2.6.0", + "semver": "^5.3.0", + "shelljs": "^0.7.6", + "uglifyjs-webpack-plugin": "^1.1.1", + "url-loader": "^0.5.8", + "vue-loader": "^13.3.0", + "vue-style-loader": "^3.0.1", + "vue-template-compiler": "^2.5.2", + "webpack": "^3.6.0", + "webpack-bundle-analyzer": "^2.9.0", + "webpack-dev-server": "^2.9.1", + "webpack-merge": "^4.1.0" + }, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not ie <= 8" + ] +} diff --git a/recipes.db b/recipes.db new file mode 100644 index 0000000..6b4f580 Binary files /dev/null and b/recipes.db differ diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..819aa8f --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +bottle +peewee +requests +https://git.weboob.org/weboob/devel/repository/archive.zip?ref=master +https://git.weboob.org/weboob/modules/repository/archive.zip?ref=master