initial commit
This commit is contained in:
0
whatforlunch.com/app/assets/images/.keep
Normal file
0
whatforlunch.com/app/assets/images/.keep
Normal file
17
whatforlunch.com/app/assets/javascripts/application.js
Normal file
17
whatforlunch.com/app/assets/javascripts/application.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
||||
// listed below.
|
||||
//
|
||||
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
||||
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
||||
//
|
||||
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
||||
// compiled file.
|
||||
//
|
||||
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
|
||||
// about supported directives.
|
||||
//
|
||||
//= require jquery
|
||||
//= require jquery_ujs
|
||||
//= require turbolinks
|
||||
//= require_tree .
|
||||
//= require bootstrap
|
||||
15
whatforlunch.com/app/assets/stylesheets/application.scss
Normal file
15
whatforlunch.com/app/assets/stylesheets/application.scss
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
||||
* listed below.
|
||||
*
|
||||
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
||||
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
||||
*
|
||||
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
||||
* compiled file, but it's generally better to create a new file per style scope.
|
||||
*
|
||||
*= require_self
|
||||
*= require_tree .
|
||||
*/
|
||||
@import "bootstrap";
|
||||
@import "bootstrap/theme"
|
||||
12
whatforlunch.com/app/assets/stylesheets/recipes.css.scss
Normal file
12
whatforlunch.com/app/assets/stylesheets/recipes.css.scss
Normal file
@@ -0,0 +1,12 @@
|
||||
// Place all the styles related to the Recipes controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||
|
||||
body {
|
||||
padding-top: 60px;
|
||||
}
|
||||
@media (max-width: 979px) {
|
||||
body {
|
||||
padding-top: 0px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class ApplicationController < ActionController::Base
|
||||
# Prevent CSRF attacks by raising an exception.
|
||||
# For APIs, you may want to use :null_session instead.
|
||||
protect_from_forgery with: :exception
|
||||
end
|
||||
0
whatforlunch.com/app/controllers/concerns/.keep
Normal file
0
whatforlunch.com/app/controllers/concerns/.keep
Normal file
71
whatforlunch.com/app/controllers/recipes_controller.rb
Normal file
71
whatforlunch.com/app/controllers/recipes_controller.rb
Normal file
@@ -0,0 +1,71 @@
|
||||
class RecipesController < ApplicationController
|
||||
before_action :set_recipe, only: [:show, :edit, :update, :destroy]
|
||||
|
||||
# GET /recipes
|
||||
# GET /recipes.json
|
||||
def index
|
||||
@recipes = Recipe.all
|
||||
end
|
||||
|
||||
# GET /recipes/1
|
||||
# GET /recipes/1.json
|
||||
def show
|
||||
end
|
||||
|
||||
# GET /recipes/new
|
||||
def new
|
||||
@recipe = Recipe.new
|
||||
end
|
||||
|
||||
# GET /recipes/1/edit
|
||||
def edit
|
||||
@samplepis
|
||||
end
|
||||
|
||||
# POST /recipes
|
||||
def create
|
||||
@recipe = Recipe.new(recipe_params)
|
||||
@recipe.scrape!
|
||||
|
||||
respond_to do |format|
|
||||
if @recipe.save
|
||||
format.html { redirect_to edit_recipe_path(@recipe), notice: 'Recipe was successfully created.' }
|
||||
else
|
||||
format.html { render action: 'new' }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# PATCH/PUT /recipes/1
|
||||
# PATCH/PUT /recipes/1.json
|
||||
def update
|
||||
respond_to do |format|
|
||||
if @recipe.update(recipe_params)
|
||||
format.html { render action: 'edit', notice: 'Recipe was successfully updated.' }
|
||||
format.json { head :no_content }
|
||||
format.html { render action: 'edit' }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /recipes/1
|
||||
# DELETE /recipes/1.json
|
||||
def destroy
|
||||
@recipe.destroy
|
||||
respond_to do |format|
|
||||
format.html { redirect_to recipes_url }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
# Use callbacks to share common setup or constraints between actions.
|
||||
def set_recipe
|
||||
@recipe = Recipe.find(params[:id])
|
||||
end
|
||||
|
||||
# Never trust parameters from the scary internet, only allow the white list through.
|
||||
def recipe_params
|
||||
params.require(:recipe).permit(:name, :duration, :ingredients, :process, :picture_url, :original_url)
|
||||
end
|
||||
end
|
||||
2
whatforlunch.com/app/helpers/application_helper.rb
Normal file
2
whatforlunch.com/app/helpers/application_helper.rb
Normal file
@@ -0,0 +1,2 @@
|
||||
module ApplicationHelper
|
||||
end
|
||||
2
whatforlunch.com/app/helpers/recipes_helper.rb
Normal file
2
whatforlunch.com/app/helpers/recipes_helper.rb
Normal file
@@ -0,0 +1,2 @@
|
||||
module RecipesHelper
|
||||
end
|
||||
0
whatforlunch.com/app/mailers/.keep
Normal file
0
whatforlunch.com/app/mailers/.keep
Normal file
0
whatforlunch.com/app/models/.keep
Normal file
0
whatforlunch.com/app/models/.keep
Normal file
0
whatforlunch.com/app/models/concerns/.keep
Normal file
0
whatforlunch.com/app/models/concerns/.keep
Normal file
72
whatforlunch.com/app/models/recipe.rb
Normal file
72
whatforlunch.com/app/models/recipe.rb
Normal file
@@ -0,0 +1,72 @@
|
||||
# encoding: utf-8
|
||||
|
||||
class Recipe < ActiveRecord::Base
|
||||
before_create :setup_ordinal
|
||||
|
||||
def scrape!
|
||||
scrape_document Nokogiri::HTML(open(self.original_url))
|
||||
end
|
||||
|
||||
def scrape_document(doc)
|
||||
r = self
|
||||
r.name = doc.css('h1')[0].text.to_s.strip
|
||||
r.duration = doc.xpath('//*[@id="recipe_preparation"]/div[1]/dl/dd[1]/text()').text.to_s.strip
|
||||
r.process = doc.css(".recipe_step_description").map { |el| el.text.to_s.strip }.join("\n")
|
||||
|
||||
r.ingredients = doc.xpath('//*[@id="recipe_ingredients"]/ul/li').map { |x|
|
||||
if x.css('span').length == 2
|
||||
x.css('span')[0].text.strip + " | " + x.css('span')[1].text.strip
|
||||
else
|
||||
nil
|
||||
end
|
||||
|
||||
}.compact.join("\n")
|
||||
end
|
||||
|
||||
def search_url
|
||||
name = URI::escape(self.name)
|
||||
return "https://www.google.com/search?q=#{name}&source=lnms&tbm=isch&sa=X"
|
||||
end
|
||||
|
||||
def ingredients_fit?
|
||||
ing = self.ingredients.to_s.split("\n")
|
||||
return false if ing.length < 1
|
||||
return false if ing.length > 20
|
||||
return false unless ing.select { |x| x.length > 22 }.empty?
|
||||
true
|
||||
end
|
||||
|
||||
def process_fits?
|
||||
pro = self.process.to_s
|
||||
return false if pro.length < 1
|
||||
return false if pro.length > 15 * 44
|
||||
true
|
||||
end
|
||||
|
||||
def picture_ok?
|
||||
!picture_url.to_s.include?("coolinarika") and picture_url.to_s.length > 0
|
||||
end
|
||||
|
||||
def is_it_valid?
|
||||
ingredients_fit? and process_fits? and name.to_s.length <= 14 and duration.to_s.length <= 10 and picture_ok?
|
||||
end
|
||||
|
||||
def ordinal_date
|
||||
Date.ordinal(2014,self.ordinal)
|
||||
end
|
||||
|
||||
def ingredients_safe
|
||||
unless self.ingredients.nil?
|
||||
ingred = self.ingredients.gsub("\r\n", "/").gsub("|"," ").gsub("/", "\n")
|
||||
return ingred
|
||||
end
|
||||
|
||||
""
|
||||
end
|
||||
|
||||
private
|
||||
def setup_ordinal
|
||||
self.ordinal = Recipe.all.length + 1
|
||||
end
|
||||
|
||||
end
|
||||
53
whatforlunch.com/app/views/layouts/application.html.erb
Normal file
53
whatforlunch.com/app/views/layouts/application.html.erb
Normal file
@@ -0,0 +1,53 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="bs_BA">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<title>Theme Template for Bootstrap</title>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js" type="text/javascript"></script>
|
||||
<![endif]-->
|
||||
<%= stylesheet_link_tag "application", media: "all" %>
|
||||
<%= javascript_include_tag "application" %>
|
||||
<%= csrf_meta_tags %>
|
||||
</head>
|
||||
|
||||
<body role="document">
|
||||
|
||||
<!-- Fixed navbar -->
|
||||
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" target="_blank" href="http://www.coolinarika.com">Šta za ručak?</a>
|
||||
</div>
|
||||
<div class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Recepti<b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="<%= recipes_path %>">Lista</a></li>
|
||||
<li><a href="<%= new_recipe_path %>">Novi recept</a></li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div><!--/.nav-collapse -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container" role="main">
|
||||
<%= yield %>
|
||||
</div> <!-- /container -->
|
||||
|
||||
</body>
|
||||
</html>
|
||||
41
whatforlunch.com/app/views/recipes/_form.html.erb
Normal file
41
whatforlunch.com/app/views/recipes/_form.html.erb
Normal file
@@ -0,0 +1,41 @@
|
||||
<%= form_for(@recipe) do |f| %>
|
||||
<% if @recipe.errors.any? %>
|
||||
<div id="error_explanation">
|
||||
<h2><%= pluralize(@recipe.errors.count, "error") %> prohibited this recipe from being saved:</h2>
|
||||
|
||||
<ul>
|
||||
<% @recipe.errors.full_messages.each do |msg| %>
|
||||
<li><%= msg %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="field">
|
||||
<%= f.label :name %><br>
|
||||
<%= f.text_field :name %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :duration %><br>
|
||||
<%= f.text_field :duration %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :ingredients %><br>
|
||||
<%= f.text_field :ingredients %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :process %><br>
|
||||
<%= f.text_field :process %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :picture_url %><br>
|
||||
<%= f.text_field :picture_url %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :original_url %><br>
|
||||
<%= f.text_field :original_url %>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<%= f.submit %>
|
||||
</div>
|
||||
<% end %>
|
||||
98
whatforlunch.com/app/views/recipes/edit.html.erb
Normal file
98
whatforlunch.com/app/views/recipes/edit.html.erb
Normal file
@@ -0,0 +1,98 @@
|
||||
<h1>Promjena recepta</h1>
|
||||
|
||||
<%= form_for(@recipe, html: {role: "form"}) do |f| %>
|
||||
|
||||
<div class="form_group row">
|
||||
<%= f.label :name, class: "col-md-1 control-label" %>
|
||||
<div class="col-md-4">
|
||||
<%= f.text_field :name, class: "form-control" %>
|
||||
</div>
|
||||
<% if @recipe.name.to_s.length > 14 %>
|
||||
<div id="name" class="col-md-4 danger" >
|
||||
|
||||
Ime je predugo - skrati do 14 slova!
|
||||
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="form_group row">
|
||||
<%= f.label :duration, class: "col-md-1 control-label" %>
|
||||
<div class="col-md-4">
|
||||
<%= f.text_field :duration, class: "form-control" %>
|
||||
</div>
|
||||
<% if @recipe.duration.to_s.length > 10 %>
|
||||
<div id="duration" class="col-md-4 danger">
|
||||
|
||||
Dužina je prevelika - skrati do 10 slova!
|
||||
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="form_group row">
|
||||
<%= f.label :ingredients, class: "col-md-1 control-label" %>
|
||||
<div class="col-md-4">
|
||||
<%= f.text_area :ingredients, class: "form-control", rows: "10" %>
|
||||
</div>
|
||||
<% unless @recipe.ingredients_fit? %>
|
||||
<div id="ingredients" class="col-md-4 danger">
|
||||
Ne smije biti više od 20 sastojaka i svaki sastojak ne smije imati više od 22 znaka (slova, broja, praznine itd.).
|
||||
Skrati ili izbaci neke sastojke.
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form_group row">
|
||||
<%= f.label :process, class: "col-md-1 control-label" %>
|
||||
<div class="col-md-4">
|
||||
<%= f.text_area :process , class: "form-control" , rows: "15" %>
|
||||
|
||||
</div>
|
||||
<% unless @recipe.process_fits? %>
|
||||
<div id="process" class="col-md-4 danger">
|
||||
Priprema mora imati najvise 15 redova a ni jedan red ne smije biti duzi od 44 slova.
|
||||
Skrati malo.
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="form_group row ">
|
||||
<div class="col-md-1">
|
||||
Slika
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<%= link_to(@recipe.picture_url, class: "thumbnail") do %>
|
||||
<%= image_tag(@recipe.picture_url) %>
|
||||
<% end %>
|
||||
<%= link_to(" Nađi drugu sliku", @recipe.search_url, target: "_blank" ) %>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="form_group row">
|
||||
|
||||
<%= f.label :picture_url, class: "col-md-1 control-label" %>
|
||||
<div class="col-md-4">
|
||||
<%= f.text_field :picture_url, class: "form-control" %>
|
||||
</div>
|
||||
<% unless @recipe.picture_ok? %>
|
||||
<div id="picture" class="col-md-4 danger">
|
||||
Slika mora biti izabrana!
|
||||
Slika ne smije biti sa stranice coolinarika. Nadji drugu.
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form_group row">
|
||||
<%= f.submit class: "btn btn-success" %>
|
||||
</div>
|
||||
|
||||
<% end %>
|
||||
|
||||
|
||||
34
whatforlunch.com/app/views/recipes/index.html.erb
Normal file
34
whatforlunch.com/app/views/recipes/index.html.erb
Normal file
@@ -0,0 +1,34 @@
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-8">
|
||||
|
||||
<h1>Recepti</h1>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Ime</th>
|
||||
<th>Datum</th>
|
||||
<th>Ispravan?</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<% @recipes.each do |recipe| %>
|
||||
<tr>
|
||||
<td><%= recipe.name %></td>
|
||||
<td><%= recipe.ordinal_date %></td>
|
||||
<td><%= (recipe.is_it_valid?) ? "DA" : "NE" %></td>
|
||||
<td><%= link_to 'Popravi recept', edit_recipe_path(recipe) %></td>
|
||||
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<br>
|
||||
|
||||
<%= link_to 'Napravi novi recept', new_recipe_path %>
|
||||
</div>
|
||||
</div>
|
||||
4
whatforlunch.com/app/views/recipes/index.json.jbuilder
Normal file
4
whatforlunch.com/app/views/recipes/index.json.jbuilder
Normal file
@@ -0,0 +1,4 @@
|
||||
json.array!(@recipes) do |recipe|
|
||||
json.extract! recipe, :id, :name, :duration, :ingredients, :process, :picture_url, :original_url
|
||||
json.url recipe_url(recipe, format: :json)
|
||||
end
|
||||
16
whatforlunch.com/app/views/recipes/new.html.erb
Normal file
16
whatforlunch.com/app/views/recipes/new.html.erb
Normal file
@@ -0,0 +1,16 @@
|
||||
<h1>Pravljenje Novog Recepta</h1>
|
||||
|
||||
<%= form_for(@recipe, html: {role: "form"}) do |f| %>
|
||||
|
||||
<div class="form_group row">
|
||||
|
||||
<%= f.label :original_url, class: "col-md-1 control-label" %>
|
||||
<div class="col-md-6">
|
||||
<%= f.url_field :original_url, class: "form-control" %>
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<%= f.submit class: "btn btn-success" %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
34
whatforlunch.com/app/views/recipes/show.html.erb
Normal file
34
whatforlunch.com/app/views/recipes/show.html.erb
Normal file
@@ -0,0 +1,34 @@
|
||||
<p id="notice"><%= notice %></p>
|
||||
|
||||
<p>
|
||||
<strong>Name:</strong>
|
||||
<%= @recipe.name %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Duration:</strong>
|
||||
<%= @recipe.duration %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Ingredients:</strong>
|
||||
<%= @recipe.ingredients %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Process:</strong>
|
||||
<%= @recipe.process %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Picture url:</strong>
|
||||
<%= @recipe.picture_url %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Original url:</strong>
|
||||
<%= @recipe.original_url %>
|
||||
</p>
|
||||
|
||||
<%= link_to 'Edit', edit_recipe_path(@recipe) %> |
|
||||
<%= link_to 'Back', recipes_path %>
|
||||
1
whatforlunch.com/app/views/recipes/show.json.jbuilder
Normal file
1
whatforlunch.com/app/views/recipes/show.json.jbuilder
Normal file
@@ -0,0 +1 @@
|
||||
json.extract! @recipe, :id, :name, :duration, :ingredients, :process, :picture_url, :original_url, :created_at, :updated_at
|
||||
Reference in New Issue
Block a user