cloudrider 0.3.0 → 0.3.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +11 -1
- data/cloudrider.gemspec +1 -0
- data/generica/.gitignore +18 -0
- data/generica/Gemfile +8 -1
- data/generica/Gemfile.lock +3 -0
- data/generica/app/assets/javascripts/apiv1.js.ls +6 -1
- data/generica/app/assets/javascripts/components/offers-summary.js.em +2 -0
- data/generica/app/assets/javascripts/components/picture-chunk.js.em +17 -0
- data/generica/app/assets/javascripts/components/pictures-group.js.em +21 -0
- data/generica/app/assets/javascripts/components/search-and-filter.js.em +4 -0
- data/generica/app/assets/javascripts/components/site-nav.js.em +5 -1
- data/generica/app/assets/javascripts/components/taggable-field.js.em +28 -0
- data/generica/app/assets/javascripts/components/tree/taxon-li.js.em +6 -2
- data/generica/app/assets/javascripts/controllers/index_controller.js.em +19 -2
- data/generica/app/assets/javascripts/controllers/modals/login_controller.js.em +23 -9
- data/generica/app/assets/javascripts/controllers/modals/register_controller.js.em +24 -0
- data/generica/app/assets/javascripts/controllers/products/index_controller.js.em +23 -13
- data/generica/app/assets/javascripts/controllers/products/product/offers/new_controller.js.em +17 -0
- data/generica/app/assets/javascripts/controllers/users/offers/index_controller.js.em +10 -0
- data/generica/app/assets/javascripts/controllers/users/product/edit_controller.js.em +31 -0
- data/generica/app/assets/javascripts/controllers/users/products/index_controller.js.em +8 -0
- data/generica/app/assets/javascripts/controllers/users/products/new_controller.js.em +22 -0
- data/generica/app/assets/javascripts/controllers/users/products/slice_controller.js.em +4 -0
- data/generica/app/assets/javascripts/helpers/filte_previewer.js.ls +21 -0
- data/generica/app/assets/javascripts/helpers/listing_picture.js.em +17 -0
- data/generica/app/assets/javascripts/models/offer.js.em +9 -8
- data/generica/app/assets/javascripts/models/user.js.em +12 -0
- data/generica/app/assets/javascripts/models/users/product.js.em +12 -0
- data/generica/app/assets/javascripts/routes/application_route.js.em +10 -2
- data/generica/app/assets/javascripts/routes/products/index_route.js.em +23 -2
- data/generica/app/assets/javascripts/routes/products/product/offers/new_route.js.em +18 -0
- data/generica/app/assets/javascripts/routes/users/offers/index_route.js.em +1 -0
- data/generica/app/assets/javascripts/routes/users/product_route.js.em +3 -0
- data/generica/app/assets/javascripts/routes/users/products/index_route.js.em +3 -0
- data/generica/app/assets/javascripts/routes/users/products/new_route.js.em +3 -0
- data/generica/app/assets/javascripts/templates/admin/product/edit.emblem +2 -0
- data/generica/app/assets/javascripts/templates/admin/products/_form-core.emblem +44 -0
- data/generica/app/assets/javascripts/templates/admin/products/new.emblem +4 -42
- data/generica/app/assets/javascripts/templates/components/offers-summary.emblem +9 -0
- data/generica/app/assets/javascripts/templates/components/picture-chunk.emblem +9 -0
- data/generica/app/assets/javascripts/templates/components/pictures-group.emblem +6 -0
- data/generica/app/assets/javascripts/templates/components/search-and-filter.emblem +5 -1
- data/generica/app/assets/javascripts/templates/components/taggable-field.emblem +1 -0
- data/generica/app/assets/javascripts/templates/modals/register.emblem +57 -0
- data/generica/app/assets/javascripts/templates/products/product/offers/_anonymous-form.emblem +11 -0
- data/generica/app/assets/javascripts/templates/products/product/offers/_offer-form.emblem +55 -0
- data/generica/app/assets/javascripts/templates/products/product/offers/new.emblem +37 -0
- data/generica/app/assets/javascripts/templates/products/product/show.emblem +26 -1
- data/generica/app/assets/javascripts/templates/users.emblem +24 -0
- data/generica/app/assets/javascripts/templates/users/index.emblem +3 -0
- data/generica/app/assets/javascripts/templates/users/offers/index.emblem +25 -0
- data/generica/app/assets/javascripts/templates/users/offers/slice.emblem +31 -0
- data/generica/app/assets/javascripts/templates/users/product/edit.emblem +82 -0
- data/generica/app/assets/javascripts/templates/users/products/index.emblem +22 -0
- data/generica/app/assets/javascripts/templates/users/products/new.emblem +28 -0
- data/generica/app/assets/javascripts/templates/users/products/slice.emblem +27 -0
- data/generica/app/assets/stylesheets/apiv1/_application.css.scss +4 -0
- data/generica/app/assets/stylesheets/apiv1/components/_offers-summary.css.scss +20 -0
- data/generica/app/assets/stylesheets/apiv1/components/_pictures-group.css.scss +32 -0
- data/generica/app/assets/stylesheets/apiv1/components/_taggable-field.css.scss +32 -0
- data/generica/app/assets/stylesheets/apiv1/products/product/offers/_new.css.scss +8 -0
- data/generica/app/controllers/admin/base_controller.rb +1 -1
- data/generica/app/controllers/admin/sessions/destroy_controller.rb +16 -0
- data/generica/app/controllers/apiv1/offers/create_controller.rb +30 -0
- data/generica/app/controllers/apiv1/offers/index_controller.rb +22 -0
- data/generica/app/controllers/apiv1/offers/show_controller.rb +12 -0
- data/generica/app/controllers/apiv1/products/destroy_controller.rb +6 -0
- data/generica/app/controllers/apiv1/products/index_controller.rb +8 -2
- data/generica/app/controllers/apiv1/products/show_controller.rb +7 -3
- data/generica/app/controllers/apiv1/taxons/index_controller.rb +5 -1
- data/generica/app/controllers/apiv1/users/create_controller.rb +17 -0
- data/generica/app/controllers/apiv1/users/show_controller.rb +12 -0
- data/generica/app/controllers/apiv1/users_controller.rb +9 -0
- data/generica/app/controllers/application_controller.rb +3 -0
- data/generica/app/controllers/users/offers/create_controller.rb +26 -0
- data/generica/app/controllers/users/products/create_controller.rb +26 -0
- data/generica/app/controllers/users/products/update_controller.rb +35 -0
- data/generica/app/mailers/apiv1/aggregate_mailer.rb +13 -0
- data/generica/app/mailers/apiv1/aggregate_mailer/summary_context.rb +121 -0
- data/generica/app/mailers/apiv1/notifications_mailer.rb +19 -0
- data/generica/app/mailers/apiv1/notifications_mailer/new_offer_context.rb +53 -0
- data/generica/app/models/admin/user.rb +43 -2
- data/generica/app/models/apiv1/attachment.rb +2 -0
- data/generica/app/models/apiv1/email_object.rb +35 -0
- data/generica/app/models/apiv1/email_request.rb +107 -0
- data/generica/app/models/apiv1/offer_message.rb +53 -0
- data/generica/app/models/apiv1/offer_postboy.rb +33 -0
- data/generica/app/models/apiv1/picture.rb +2 -0
- data/generica/app/models/apiv1/product.rb +28 -6
- data/generica/app/models/apiv1/products/offer_message_factory.rb +13 -0
- data/generica/app/models/apiv1/products_machine.rb +8 -2
- data/generica/app/models/apiv1/taxon.rb +1 -1
- data/generica/app/models/apiv1/users/product_factory.rb +22 -0
- data/generica/app/models/apiv1/users/product_relationship.rb +19 -0
- data/generica/app/models/users/products/offer_factory.rb +40 -0
- data/generica/app/varissets/javascripts/templates/application.emblem.erb +2 -2
- data/generica/app/varissets/javascripts/templates/components/offers-overview.emblem.erb +1 -0
- data/generica/app/varissets/javascripts/templates/components/search-and-filter.emblem.erb +33 -0
- data/generica/app/varissets/javascripts/templates/components/site-nav.emblem.erb +8 -0
- data/generica/app/varissets/javascripts/templates/components/taggable-field.emblem.erb +11 -0
- data/generica/app/varissets/javascripts/templates/modals/login.emblem.erb +36 -0
- data/generica/app/varissets/javascripts/templates/products.emblem.erb +4 -0
- data/generica/app/varissets/javascripts/templates/products/index.emblem.erb +17 -0
- data/generica/app/varissets/javascripts/templates/products/product/offers/_anonymous-form.emblem.erb +11 -0
- data/generica/app/varissets/javascripts/templates/products/product/offers/_offer-form.emblem.erb +55 -0
- data/generica/app/varissets/javascripts/templates/products/product/offers/new.emblem.erb +37 -0
- data/generica/app/varissets/javascripts/templates/products/product/show.emblem.erb +108 -0
- data/generica/app/varissets/stylesheets/apiv1/components/_offers-overview.css.scss.erb +3 -0
- data/generica/app/varissets/stylesheets/apiv1/components/_offers_overview.css.scss.erb +3 -0
- data/generica/app/varissets/stylesheets/apiv1/components/_search-and-filter.css.scss.erb +15 -0
- data/generica/app/varissets/stylesheets/apiv1/components/_site-footer.css.scss.erb +23 -0
- data/generica/app/varissets/stylesheets/apiv1/components/_taggable-field.css.scss.erb +32 -0
- data/generica/app/views/apiv1/home/index.html.haml +3 -1
- data/generica/app/views/apiv1/layouts/application.html.haml +37 -2
- data/generica/config/{database.yml.erb → database.yml.str} +3 -3
- data/generica/config/email.yml +11 -0
- data/generica/config/email_slave.god +9 -0
- data/generica/config/initializers/premailer.rb +1 -0
- data/generica/config/initializers/squash.rb.erb +3 -0
- data/generica/config/nginx.conf.erb +4 -4
- data/generica/config/routes.rb +14 -0
- data/generica/db/migrate/20141114213427_add_user_rank_to_admin_users.rb +9 -0
- data/generica/db/migrate/20141114225019_create_apiv1_users_products.rb +9 -0
- data/generica/db/migrate/20141116053522_create_apiv1_offer_messages.rb +16 -0
- data/generica/db/migrate/20141116235011_add_deleted_at_to_apiv1_products.rb +5 -0
- data/generica/db/migrate/20141116235209_add_deleted_at_to_apiv1_offer_messages.rb +5 -0
- data/generica/db/migrate/20141116235651_add_deleted_at_to_apiv1_pictures.rb +5 -0
- data/generica/db/migrate/20141116235808_add_deleted_at_to_apiv1_attachments.rb +5 -0
- data/generica/db/migrate/20141127230304_create_apiv1_email_requests.rb +16 -0
- data/generica/db/migrate/20141127230455_create_apiv1_email_objects.rb +11 -0
- data/generica/lib/generica/assets_unretardifier.rb +32 -0
- data/generica/lib/generica/email_slave.rb +92 -0
- data/generica/lib/tasks/email_slave.rake +11 -0
- data/generica/lib/tasks/production.rake +1 -1
- data/generica/public/tests/bermese.jpg +0 -0
- data/generica/public/tests/chow.jpg +0 -0
- data/generica/public/tests/malamute.jpg +0 -0
- data/generica/public/tests/malamute2.JPG +0 -0
- data/generica/spec/controllers/apiv1/users/create_controller_spec.rb +17 -0
- data/generica/spec/controllers/users/products/create_controller_spec.rb +31 -0
- data/generica/spec/mailers/apiv1/aggregate_mailer_spec.rb +29 -0
- data/generica/spec/models/apiv1/email_request_spec.rb +4 -0
- data/generica/spec/models/apiv1/offer_postboy_spec.rb +22 -0
- data/generica/spec/models/apiv1/product_spec.rb +1 -0
- data/generica/spec/models/apiv1/products/offer_message_factory_spec.rb +37 -0
- data/generica/spec/models/apiv1/products_machine_spec.rb +77 -0
- data/generica/spec/models/apiv1/users/product_factory_spec.rb +47 -0
- data/generica/spec/models/users/products/offer_factory_spec.rb +38 -0
- data/generica/test/mailers/.keep +0 -0
- data/generica/test/mailers/previews/apiv1/aggregate_preview.rb +6 -0
- data/generica/test/mailers/previews/apiv1/notifications_preview.rb +5 -0
- data/lib/cloudrider.rb +1 -1
- data/lib/cloudrider/apiv1/base.rb +2 -2
- data/lib/cloudrider/apiv1/login_modal_emblem.rb +25 -0
- data/lib/cloudrider/apiv1/offers_anonymous_form_partial_emblem.rb +12 -0
- data/lib/cloudrider/apiv1/offers_new_emblem.rb +15 -0
- data/lib/cloudrider/apiv1/offers_overview_component.rb +8 -0
- data/lib/cloudrider/apiv1/offers_overview_sass.rb +8 -0
- data/lib/cloudrider/apiv1/product_show_emblem.rb +31 -0
- data/lib/cloudrider/apiv1/products_emblem.rb +11 -0
- data/lib/cloudrider/apiv1/products_index_emblem.rb +14 -0
- data/lib/cloudrider/apiv1/search_and_filter_component.rb +11 -0
- data/lib/cloudrider/apiv1/search_and_filter_sass.rb +11 -0
- data/lib/cloudrider/apiv1/site_footer_component.rb +7 -7
- data/lib/cloudrider/apiv1/site_footer_sass.rb +9 -0
- data/lib/cloudrider/application_commander.rb +46 -34
- data/lib/cloudrider/backend_commander.rb +15 -9
- data/lib/cloudrider/protofile.rb +18 -2
- data/lib/cloudrider/protosite.example.json +26 -0
- data/lib/cloudrider/protosite.rb +66 -0
- data/lib/cloudrider/serverside/base.rb +2 -2
- data/lib/cloudrider/serverside/database_yaml.rb +9 -4
- data/lib/cloudrider/serverside/nginx_conf.rb +7 -2
- data/lib/cloudrider/serverside/squash_ruby.rb +14 -0
- data/lib/cloudrider/serverside/unicorn_conf_ruby.rb +2 -1
- data/lib/cloudrider/version.rb +1 -1
- data/lib/cloudrider/web_firm.rb +16 -0
- data/lib/cloudrider/web_firm/component_architect.rb +23 -0
- data/lib/cloudrider/web_firm/page_designer.rb +13 -0
- data/lib/cloudrider/web_firm/project_lead.rb +30 -0
- data/lib/cloudrider/web_firm/scumbag_engineer.rb +40 -0
- data/lib/cloudrider/web_firm/support_intern.rb +113 -0
- data/lib/generators/cloudrider/server/server_generator.rb +4 -8
- data/lib/generators/cloudrider/website/website_generator.rb +25 -0
- data/spec/cloudrider/protosite_spec.rb +63 -0
- data/vanilla/.bowerrc +4 -0
- data/vanilla/.editorconfig +33 -0
- data/vanilla/.ember-cli +9 -0
- data/vanilla/.gitignore +17 -0
- data/vanilla/.jshintrc +32 -0
- data/vanilla/.travis.yml +16 -0
- data/vanilla/Brocfile.js +20 -0
- data/vanilla/README.md +51 -0
- data/vanilla/app/app.js +16 -0
- data/vanilla/app/components/.gitkeep +0 -0
- data/vanilla/app/controllers/.gitkeep +0 -0
- data/vanilla/app/controllers/admin.coffee +5 -0
- data/vanilla/app/helpers/.gitkeep +0 -0
- data/vanilla/app/index.html +21 -0
- data/vanilla/app/models/.gitkeep +0 -0
- data/vanilla/app/router.js +11 -0
- data/vanilla/app/routes/.gitkeep +0 -0
- data/vanilla/app/styles/.gitkeep +0 -0
- data/vanilla/app/styles/app.css +3 -0
- data/vanilla/app/templates/.gitkeep +0 -0
- data/vanilla/app/templates/application.hbs +3 -0
- data/vanilla/app/templates/components/.gitkeep +0 -0
- data/vanilla/app/views/.gitkeep +0 -0
- data/vanilla/bower.json +17 -0
- data/vanilla/config/environment.js +47 -0
- data/vanilla/package.json +39 -0
- data/vanilla/public/.gitkeep +0 -0
- data/vanilla/public/crossdomain.xml +15 -0
- data/vanilla/public/robots.txt +3 -0
- data/vanilla/testem.json +11 -0
- data/vanilla/tests/.jshintrc +74 -0
- data/vanilla/tests/helpers/resolver.js +11 -0
- data/vanilla/tests/helpers/start-app.js +25 -0
- data/vanilla/tests/index.html +45 -0
- data/vanilla/tests/test-helper.js +12 -0
- data/vanilla/tests/unit/.gitkeep +0 -0
- data/vanilla/tests/unit/controllers/admin-test.coffee +12 -0
- data/vanilla/vendor/.gitkeep +0 -0
- metadata +189 -5
- data/generica/app/views/layouts/application.html.erb +0 -14
- data/lib/cloudrider/master_context.rb +0 -105
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
.taggable-field {
|
|
2
|
+
@include display-flex;
|
|
3
|
+
@include flex-direction(row);
|
|
4
|
+
@include flex-wrap(nowrap);
|
|
5
|
+
@include justify-content(flex-start);
|
|
6
|
+
overflow-x: hidden;
|
|
7
|
+
.taggable-textfield {
|
|
8
|
+
margin-bottom: 0px;
|
|
9
|
+
width: 100%;
|
|
10
|
+
height: 40px;
|
|
11
|
+
}
|
|
12
|
+
.taggable-field-tag {
|
|
13
|
+
@include display-flex;
|
|
14
|
+
@include flex-direction(row);
|
|
15
|
+
@include justify-content(center);
|
|
16
|
+
@include align-items(center);
|
|
17
|
+
border: 1px solid #ddd;
|
|
18
|
+
padding-left: 10px;
|
|
19
|
+
padding-right: 15px;
|
|
20
|
+
min-width: 50px;
|
|
21
|
+
height: 40px;
|
|
22
|
+
background: {
|
|
23
|
+
color: #f2f2f2;
|
|
24
|
+
}
|
|
25
|
+
color: #358753;
|
|
26
|
+
}
|
|
27
|
+
.centered-fully {
|
|
28
|
+
@include display-flex;
|
|
29
|
+
@include flex-wrap(nowrap);
|
|
30
|
+
@include flex-direction(row);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -2,7 +2,7 @@ class Admin::BaseController < ApplicationController
|
|
|
2
2
|
before_filter :_respond_with_unauthorized_json
|
|
3
3
|
private
|
|
4
4
|
def _respond_with_unauthorized_json
|
|
5
|
-
unless logged_in?
|
|
5
|
+
unless logged_in? && current_user.admin?
|
|
6
6
|
render json: { message: "login required" }, status: 401
|
|
7
7
|
end
|
|
8
8
|
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class Admin::Sessions::DestroyController < Apiv1::UsersController
|
|
2
|
+
before_filter :_ensure_correct_sessionism
|
|
3
|
+
def destroy
|
|
4
|
+
logout
|
|
5
|
+
render json: nil
|
|
6
|
+
end
|
|
7
|
+
private
|
|
8
|
+
def _ensure_correct_sessionism
|
|
9
|
+
unless current_user == _user
|
|
10
|
+
render json: { message: "you can't log someone else out" }, status: 401
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
def _user
|
|
14
|
+
@user ||= Admin::User.find params[:id]
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
class Apiv1::Offers::CreateController < Apiv1::HomeController
|
|
2
|
+
def create
|
|
3
|
+
if _offer_creation_success?
|
|
4
|
+
_offer_factory.save!
|
|
5
|
+
_offer_postboy.request_work!
|
|
6
|
+
render json: _offer_hash
|
|
7
|
+
else
|
|
8
|
+
render json: _error_hash, status: :expectation_failed
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
private
|
|
12
|
+
def _offer_postboy
|
|
13
|
+
@offer_postboy ||= Apiv1::OfferPostboy.new _offer_factory.offer
|
|
14
|
+
end
|
|
15
|
+
def _offer_creation_success?
|
|
16
|
+
_offer_factory.satisfy_specifications?
|
|
17
|
+
end
|
|
18
|
+
def _offer_hash
|
|
19
|
+
_offer_factory.offer_hash
|
|
20
|
+
end
|
|
21
|
+
def _error_hash
|
|
22
|
+
_offer_factory.error_hash
|
|
23
|
+
end
|
|
24
|
+
def _offer_factory
|
|
25
|
+
@offer_factory ||= Apiv1::Products::OfferMessageFactory.new(_offer_params)
|
|
26
|
+
end
|
|
27
|
+
def _offer_params
|
|
28
|
+
params.require(:offer)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
class Apiv1::Offers::IndexController < Apiv1::UsersController
|
|
2
|
+
def index
|
|
3
|
+
render json: { offers: _offers.map(&:to_ember_hash), meta: _meta_hash }
|
|
4
|
+
end
|
|
5
|
+
private
|
|
6
|
+
def _meta_hash
|
|
7
|
+
{
|
|
8
|
+
page: _page,
|
|
9
|
+
per: _per,
|
|
10
|
+
count: current_user.offers.count
|
|
11
|
+
}
|
|
12
|
+
end
|
|
13
|
+
def _offers
|
|
14
|
+
@offers ||= current_user.offers.page(_page).per(_per)
|
|
15
|
+
end
|
|
16
|
+
def _page
|
|
17
|
+
params[:page] || 1
|
|
18
|
+
end
|
|
19
|
+
def _per
|
|
20
|
+
params[:per] || 15
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
class Apiv1::Products::DestroyController < Admin::BaseController
|
|
2
|
+
before_filter :_ensure_product_ownership
|
|
2
3
|
def destroy
|
|
3
4
|
render json: { product: _product.destroy }
|
|
4
5
|
end
|
|
5
6
|
private
|
|
7
|
+
def _ensure_product_ownership
|
|
8
|
+
unless current_user.admin? || current_user.owns?(_product)
|
|
9
|
+
render json: { message: "This isn't your listing" }, status: 401
|
|
10
|
+
end
|
|
11
|
+
end
|
|
6
12
|
def _product
|
|
7
13
|
@product ||= Apiv1::Product.find params[:id]
|
|
8
14
|
end
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
class Apiv1::Products::IndexController < Apiv1::HomeController
|
|
2
2
|
def index
|
|
3
|
-
render json: { products: _products_hash, meta: _meta_hash }
|
|
3
|
+
render json: { products: _products_hash, meta: _meta_hash, pictures: _pictures_hash, taxons: _taxons_hash }
|
|
4
4
|
end
|
|
5
5
|
private
|
|
6
|
+
def _pictures_hash
|
|
7
|
+
_products.map(&:pictures).flatten.map(&:to_ember_hash)
|
|
8
|
+
end
|
|
9
|
+
def _taxons_hash
|
|
10
|
+
_products.map(&:taxons).flatten.map(&:to_ember_hash)
|
|
11
|
+
end
|
|
6
12
|
def _products_hash
|
|
7
13
|
_products.map &:to_ember_hash
|
|
8
14
|
end
|
|
@@ -16,6 +22,6 @@ class Apiv1::Products::IndexController < Apiv1::HomeController
|
|
|
16
22
|
@products_machine ||= Apiv1::ProductsMachine.new _query_params
|
|
17
23
|
end
|
|
18
24
|
def _query_params
|
|
19
|
-
params.permit(:page, :per, :query, :order
|
|
25
|
+
params.permit(:page, :per, :query, :order, :user_id, :taxons, taxons: [])
|
|
20
26
|
end
|
|
21
27
|
end
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
class Apiv1::Products::ShowController < Apiv1::HomeController
|
|
2
2
|
def show
|
|
3
|
-
render json:
|
|
3
|
+
render json: _output_hash
|
|
4
4
|
end
|
|
5
5
|
private
|
|
6
|
-
def
|
|
7
|
-
|
|
6
|
+
def _output_hash
|
|
7
|
+
{
|
|
8
|
+
product: _product.to_ember_hash,
|
|
9
|
+
pictures: _product.pictures.map(&:to_ember_hash),
|
|
10
|
+
offers: _product.offers.map(&:to_ember_hash)
|
|
11
|
+
}
|
|
8
12
|
end
|
|
9
13
|
def _product
|
|
10
14
|
@product ||= Apiv1::Product.find_by_permalink_or_id! params[:id]
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
class Apiv1::Taxons::IndexController < Apiv1::HomeController
|
|
2
2
|
def index
|
|
3
|
-
render json: { taxons:
|
|
3
|
+
render json: { taxons: _taxons_hash }
|
|
4
4
|
end
|
|
5
5
|
private
|
|
6
|
+
def _taxons_hash
|
|
7
|
+
_taxons.map(&:to_ember_hash)
|
|
8
|
+
end
|
|
6
9
|
def _taxons
|
|
7
10
|
Apiv1::Taxon.pipeline -> (t) { t.by_root_genus(params[:root_genus]) if params[:root_genus].present? },
|
|
8
11
|
-> (t) { t.children_of_parent(params[:parent_id]) if params[:parent_id].present? },
|
|
9
12
|
-> (t) { t.root_generation if params.has_key?(:parent_id) && params[:parent_id].blank? },
|
|
13
|
+
-> (t) { t.where id: params[:ids].to_a if params[:ids].present? },
|
|
10
14
|
-> (t) { t.all }
|
|
11
15
|
end
|
|
12
16
|
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
class Apiv1::Users::CreateController < Apiv1::HomeController
|
|
2
|
+
def create
|
|
3
|
+
if _user.valid?
|
|
4
|
+
_user.save! && auto_login(_user)
|
|
5
|
+
render json: { user: _user.to_ember_hash }
|
|
6
|
+
else
|
|
7
|
+
render json: _user.errors.to_h, status: :expectation_failed
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
private
|
|
11
|
+
def _user
|
|
12
|
+
@user ||= Admin::User.new _user_params
|
|
13
|
+
end
|
|
14
|
+
def _user_params
|
|
15
|
+
params.require(:user).permit :email, :company_name, :phone_number, :password, :password_confirmation, :address
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -2,4 +2,7 @@ class ApplicationController < ActionController::Base
|
|
|
2
2
|
# Prevent CSRF attacks by raising an exception.
|
|
3
3
|
# For APIs, you may want to use :null_session instead.
|
|
4
4
|
protect_from_forgery with: :exception
|
|
5
|
+
|
|
6
|
+
include Squash::Ruby::ControllerMethods
|
|
7
|
+
enable_squash_client
|
|
5
8
|
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
class Users::Offers::CreateController < Apiv1::UsersController
|
|
2
|
+
def create
|
|
3
|
+
if _offer_creation_success?
|
|
4
|
+
_offer_factory.save!
|
|
5
|
+
render json: _offer_hash
|
|
6
|
+
else
|
|
7
|
+
render json: _error_hash, status: :expectation_failed
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
private
|
|
11
|
+
def _offer_creation_success?
|
|
12
|
+
_offer_factory.satisfy_specifications?
|
|
13
|
+
end
|
|
14
|
+
def _offer_hash
|
|
15
|
+
_offer_factory.offer_hash
|
|
16
|
+
end
|
|
17
|
+
def _error_hash
|
|
18
|
+
_offer_factory.error_hash
|
|
19
|
+
end
|
|
20
|
+
def _offer_factory
|
|
21
|
+
@offer_factory ||= Users::Products::OfferFactory.new(current_user, _offer_params)
|
|
22
|
+
end
|
|
23
|
+
def _offer_params
|
|
24
|
+
params.require(:users_offer)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
class Users::Products::CreateController < Apiv1::UsersController
|
|
2
|
+
def create
|
|
3
|
+
if _product_creation_success?
|
|
4
|
+
_product_factory.save!
|
|
5
|
+
render json: _product_hash
|
|
6
|
+
else
|
|
7
|
+
render json: _error_hash, status: :expectation_failed
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
private
|
|
11
|
+
def _product_creation_success?
|
|
12
|
+
_product_factory.satisfy_specifications?
|
|
13
|
+
end
|
|
14
|
+
def _product_hash
|
|
15
|
+
_product_factory.product_hash
|
|
16
|
+
end
|
|
17
|
+
def _error_hash
|
|
18
|
+
_product_factory.error_hash
|
|
19
|
+
end
|
|
20
|
+
def _product_factory
|
|
21
|
+
@product_factory ||= Apiv1::Users::ProductFactory.new(current_user, _product_params)
|
|
22
|
+
end
|
|
23
|
+
def _product_params
|
|
24
|
+
params.require(:users_product)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
class Users::Products::UpdateController < Apiv1::UsersController
|
|
2
|
+
before_filter :_ensure_product_ownership
|
|
3
|
+
def update
|
|
4
|
+
if _product_modification_success?
|
|
5
|
+
_product_modifier.update!
|
|
6
|
+
render json: { product: _product_hash }
|
|
7
|
+
else
|
|
8
|
+
render json: _error_hash, status: :expectation_failed
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
private
|
|
12
|
+
def _ensure_product_ownership
|
|
13
|
+
unless current_user.owns? _product
|
|
14
|
+
render json: { message: "This isn't your listing" }, status: 401
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
def _product_modification_success?
|
|
18
|
+
_product_modifier.satisfy_specifications?
|
|
19
|
+
end
|
|
20
|
+
def _product_hash
|
|
21
|
+
_product_modifier.product_hash
|
|
22
|
+
end
|
|
23
|
+
def _error_hash
|
|
24
|
+
_product_modifier.error_hash
|
|
25
|
+
end
|
|
26
|
+
def _product_modifier
|
|
27
|
+
@product_modifier ||= Admin::ProductModifier.new _product, _product_params
|
|
28
|
+
end
|
|
29
|
+
def _product
|
|
30
|
+
@product ||= Apiv1::Product.find params[:id]
|
|
31
|
+
end
|
|
32
|
+
def _product_params
|
|
33
|
+
params.require(:users_product)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class Apiv1::AggregateMailer < ActionMailer::Base
|
|
2
|
+
default from: "from@example.com"
|
|
3
|
+
layout "apiv1/layouts/email"
|
|
4
|
+
def summary(emails)
|
|
5
|
+
@ctx = Apiv1::AggregateMailer::SummaryContext.new emails
|
|
6
|
+
|
|
7
|
+
mail to: @ctx.to,
|
|
8
|
+
from: @ctx.from,
|
|
9
|
+
cc: @ctx.cc,
|
|
10
|
+
bcc: @ctx.bcc,
|
|
11
|
+
subject: @ctx.subject
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
class Apiv1::AggregateMailer::SummaryContext
|
|
2
|
+
class NoEmailsToAggregate < StandardError; end
|
|
3
|
+
delegate :to,
|
|
4
|
+
:from,
|
|
5
|
+
:cc,
|
|
6
|
+
:bcc,
|
|
7
|
+
to: :_first_email
|
|
8
|
+
def initialize(emails)
|
|
9
|
+
@emails = emails
|
|
10
|
+
raise NoEmailsToAggregate, "no emails to aggregate" if @emails.blank?
|
|
11
|
+
end
|
|
12
|
+
def subject
|
|
13
|
+
[_preamble, _email_type_and_counts.join(", ")].join(" ").strip
|
|
14
|
+
end
|
|
15
|
+
def html_bodies
|
|
16
|
+
@emails.map do |email|
|
|
17
|
+
CoreHtmlFinder.html_body_gist email
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
def plain_bodies
|
|
21
|
+
@emails.map do |email|
|
|
22
|
+
CorePlainFinder.plain_body_gist email
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
def whoever_this_is_sent_to
|
|
26
|
+
FormalTitleFinder.formal_title _first_email
|
|
27
|
+
end
|
|
28
|
+
private
|
|
29
|
+
def _preamble
|
|
30
|
+
"Update:"
|
|
31
|
+
end
|
|
32
|
+
def _email_type_and_counts
|
|
33
|
+
_email_groups.map do |type_name, emails|
|
|
34
|
+
_that_pluralize_thing noun: type_name, count: emails.count
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
def _that_pluralize_thing(noun: noun, count: count)
|
|
38
|
+
if count > 1 || count == 0
|
|
39
|
+
"#{count} #{noun.pluralize}"
|
|
40
|
+
else
|
|
41
|
+
"#{count} #{noun.singularize}"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
def _first_email
|
|
45
|
+
@emails.first
|
|
46
|
+
end
|
|
47
|
+
def _email_groups
|
|
48
|
+
@emails.reduce({}) do |hash, email|
|
|
49
|
+
s = _simplify_subject email.subject
|
|
50
|
+
hash[s] ||= []
|
|
51
|
+
hash[s].push email
|
|
52
|
+
hash
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
def _simplify_subject(subject)
|
|
56
|
+
subject.split("-").first.to_s.strip
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
class Apiv1::AggregateMailer::SummaryContext::CoreHtmlFinder
|
|
61
|
+
class << self
|
|
62
|
+
def html_body_gist(mail)
|
|
63
|
+
_process.call mail
|
|
64
|
+
end
|
|
65
|
+
private
|
|
66
|
+
def _process
|
|
67
|
+
_get_html_part >> _parse_by_nokogiri >> _find_via_css >> _return_html
|
|
68
|
+
end
|
|
69
|
+
def _get_html_part
|
|
70
|
+
-> (mail) { mail.html_part.to_s }
|
|
71
|
+
end
|
|
72
|
+
def _parse_by_nokogiri
|
|
73
|
+
-> (string) { Nokogiri::HTML(string) }
|
|
74
|
+
end
|
|
75
|
+
def _find_via_css
|
|
76
|
+
-> (nokodoc) { nokodoc.css "table.the-gist" }
|
|
77
|
+
end
|
|
78
|
+
def _return_html
|
|
79
|
+
-> (nokoel) { nokoel.map(&:to_s).join("\n") }
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
class Apiv1::AggregateMailer::SummaryContext::FormalTitleFinder
|
|
85
|
+
class << self
|
|
86
|
+
def formal_title(mail)
|
|
87
|
+
_process.call mail
|
|
88
|
+
end
|
|
89
|
+
private
|
|
90
|
+
def _process
|
|
91
|
+
_get_html_part >> _parse_by_nokogiri >> _find_via_css >> _return_html
|
|
92
|
+
end
|
|
93
|
+
def _get_html_part
|
|
94
|
+
-> (mail) { mail.html_part.to_s }
|
|
95
|
+
end
|
|
96
|
+
def _parse_by_nokogiri
|
|
97
|
+
-> (string) { Nokogiri::HTML(string) }
|
|
98
|
+
end
|
|
99
|
+
def _find_via_css
|
|
100
|
+
-> (nokodoc) { nokodoc.css "span.product-owner" }
|
|
101
|
+
end
|
|
102
|
+
def _return_html
|
|
103
|
+
-> (nokoel) { nokoel.first.text }
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
class Apiv1::AggregateMailer::SummaryContext::CorePlainFinder
|
|
109
|
+
class << self
|
|
110
|
+
def plain_body_gist(mail)
|
|
111
|
+
_process.call mail
|
|
112
|
+
end
|
|
113
|
+
private
|
|
114
|
+
def _process
|
|
115
|
+
_get_plain_part
|
|
116
|
+
end
|
|
117
|
+
def _get_plain_part
|
|
118
|
+
-> (mail) { mail.text_part.to_s }
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|