diff --git a/.gitignore b/.gitignore index 553281cad4c6e899d7a643d1f49f4ae9943be0ce..33866f7712a5cf4c53f305b90bfac5db7ebbbcd2 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,8 @@ Gemfile.lock /public/assets /config/orientdb.yml /config/dspace.yml +# ignore server scripts +puma.sh +start_puma.sh +stop_puma.sh +portalmec.service diff --git a/app/assets/images/fnde.png b/app/assets/images/fnde.png new file mode 100644 index 0000000000000000000000000000000000000000..19bf5082710dffa1fef3b06252932f090a6c6bce Binary files /dev/null and b/app/assets/images/fnde.png differ diff --git "a/app/assets/images/icons/Copiar_Sele\303\247\303\243o.png" "b/app/assets/images/icons/Copiar_Sele\303\247\303\243o.png" new file mode 100644 index 0000000000000000000000000000000000000000..85d33052a55cdd834c30b1c632172bf7ccaab8d3 Binary files /dev/null and "b/app/assets/images/icons/Copiar_Sele\303\247\303\243o.png" differ diff --git a/app/assets/images/icons/Download_01.png b/app/assets/images/icons/Download_01.png new file mode 100644 index 0000000000000000000000000000000000000000..367358d049e9c2c6b5f841e459923a4f7b26b6e2 Binary files /dev/null and b/app/assets/images/icons/Download_01.png differ diff --git "a/app/assets/images/icons/Mover_Sele\303\247\303\243o.png" "b/app/assets/images/icons/Mover_Sele\303\247\303\243o.png" new file mode 100644 index 0000000000000000000000000000000000000000..27feb4a46143bcede48aaa0b9a45e0283ce78015 Binary files /dev/null and "b/app/assets/images/icons/Mover_Sele\303\247\303\243o.png" differ diff --git "a/app/assets/images/icons/Remover_da_Cole\303\247\303\243o_Sele\303\247\303\243o.png" "b/app/assets/images/icons/Remover_da_Cole\303\247\303\243o_Sele\303\247\303\243o.png" new file mode 100644 index 0000000000000000000000000000000000000000..bda86e5ce3e7cfc86c866645bd26aa0e633b2ca3 Binary files /dev/null and "b/app/assets/images/icons/Remover_da_Cole\303\247\303\243o_Sele\303\247\303\243o.png" differ diff --git a/app/assets/images/icons/downloadred.png b/app/assets/images/icons/downloadred.png new file mode 100644 index 0000000000000000000000000000000000000000..d67b8a025b6b5b7e51bdb91a221dd8a726b05f89 Binary files /dev/null and b/app/assets/images/icons/downloadred.png differ diff --git a/app/assets/images/icons/foldergreen.png b/app/assets/images/icons/foldergreen.png new file mode 100644 index 0000000000000000000000000000000000000000..0c4da5a1501d915c3f7d746378b10872ddc318e5 Binary files /dev/null and b/app/assets/images/icons/foldergreen.png differ diff --git a/app/assets/images/icons/signup.png b/app/assets/images/icons/signup.png new file mode 100644 index 0000000000000000000000000000000000000000..083ccb7ad3cb5f5a4cda6f4efa515d0199754d5a Binary files /dev/null and b/app/assets/images/icons/signup.png differ diff --git a/app/assets/images/logo_brasil.png b/app/assets/images/logo_brasil.png index 9d7e5d51f0fdbd92f94f2ab0d53e3aca23ed54fe..46dd6a59d8b6477d66c96c657b1213f99a47a09e 100644 Binary files a/app/assets/images/logo_brasil.png and b/app/assets/images/logo_brasil.png differ diff --git a/app/assets/images/logo_ministerio.png b/app/assets/images/logo_ministerio.png new file mode 100644 index 0000000000000000000000000000000000000000..f1da0b032991ee57ec2ed728c28c0721d4a5b84f Binary files /dev/null and b/app/assets/images/logo_ministerio.png differ diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 61019549c1b48e0a360ce2358c670e461c41f568..02a2779b288f6148210a37f5848c4817de283f55 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -14,6 +14,8 @@ //= require jquery_ujs //= require bootstrap-sprockets //= require select2 +//= require select2_locale_pt-BR +//= require bootstrap-tagsinput //= require jquery.turbolinks //= require turbolinks //= require_tree ./application diff --git a/app/assets/javascripts/application/accessibility.js b/app/assets/javascripts/application/accessibility.js index 9383da590ec29253b1a029b825306704bae5f021..c121b221fc896c27fc80bd1036b28644ef89f29f 100644 --- a/app/assets/javascripts/application/accessibility.js +++ b/app/assets/javascripts/application/accessibility.js @@ -58,6 +58,8 @@ var contrast = function() { $(contrast_elements).removeClass('contraste'); $('.search-bar').css('border-top','none'); $('#menu-bar').removeClass('menu-bar-contrast'); + $('.navbar-header').removeClass('set-Colecao'); + $('.caret').css('border-top',' 7px solid black'); var select = $('.select-tag-container').select2() .on("select2:open", function() { @@ -75,8 +77,10 @@ var contrast = function() { $(contrast_elements).addClass('contraste'); $('.search-bar').css('border-top','2px solid white'); $('#menu-bar').addClass('menu-bar-contrast'); + $('.navbar-header').addClass('set-Colecao'); + $('.caret').css('border-top',' 7px solid white'); - //contraste select2(menu esquerda) + //contraste select2(menu esquerda) var select = $('.select-tag-container').select2() .on("select2:open", function() { // TODO: find a way to only apply contrast first time only @@ -86,6 +90,7 @@ var contrast = function() { $(this).data('select2').$dropdown.addClass("words"); $(this).data('select2').$results.addClass("fundo"); }); + $('.select2-search-choice:not(.my-custom-css)', this).addClass('my-custom-css'); } }); } diff --git a/app/assets/javascripts/application/search.js b/app/assets/javascripts/application/search.js index a6425bb889ce8022071e30e20a5f94eb82417074..4e7bfdf1e63cc9b03acf68ef9101e07da26a89ab 100644 --- a/app/assets/javascripts/application/search.js +++ b/app/assets/javascripts/application/search.js @@ -1,4 +1,5 @@ ////// SEARCH +var watch = {}; var search = function() { //// SEARCH FETCH // get results from params @@ -53,10 +54,15 @@ var search = function() { var has_init = false; function init() { - // check url and set inputs with params + // watch params to change inputs + watchParams(); + + // check url and set params checkUrl(); + // watch inputs to change params watchSearchInput(); + watchFilterPanel(); watchOrder(); watchFilters(); } @@ -74,7 +80,7 @@ var search = function() { for(var i = 0; i < length; i++) { element = values[i].split('='); - params.add(element[0], element[1]); + params.add(decodeURIComponent(element[0]), decodeURIComponent(element[1])); } // replace history state with new parameters @@ -84,8 +90,68 @@ var search = function() { searchFetch(); } + function watchParams() { + $(watch).on('params', function (e, action, type, value) { + // filter panel + var text = type + ': ' + value; + var object = {'type': type, 'value': value, 'text': text }; + switch(action) { + case 'add': + // remove previous element if type is a single value only + var single_params = ['query', 'order']; + var index = single_params.indexOf(type); + if (index > -1) { + $.each($('.filter-panel').tagsinput('items'), function (i, v) { + if (v.type === single_params[index]) { + $('.filter-panel').tagsinput('remove', { 'type': type, 'value': v.value }, {'ignore': true}); + } + }); + } + // add object + $('.filter-panel').tagsinput('add', object); + break; + case 'remove': + // remove object + $('.filter-panel').tagsinput('remove', object); + break; + } + + // sidebar + switch(type) { + // search input + case 'query': + if ($('.search-input form input[name="query"]').val() !== params.get('query')) { + $('.search-input form input[name="query"]').val(params.get('query')); + } + break; + // order + case 'order': + if ($('select[name="order"]').val() !== params.get('order')) { + $('select[name="order"]').val(params.get('order')); + } + break; + // subject + case 'subject': + var subjects = params.get('subject'); + $('.filter-subject').each(function() { + if (this.value !== subjects) { + $(this).val(subjects).trigger('change'); + } + }); + break; + // type + case 'type': + watchCheckbox('type', 'filter-type', true); + break; + // schoolyear + case 'school_year': + watchCheckbox('school_year', 'filter-school-year', true); + break; + } + }); + } + function watchSearchInput() { - $('.search-input form input[name="query"]').val(params.get('query')); $('.search-input form').on('submit', function (event) { event.preventDefault(); params.reset(); @@ -94,10 +160,21 @@ var search = function() { }); } + function watchFilterPanel() { + $('.filter-panel').on('beforeItemRemove', function(event) { + if (event.options === undefined) { + event.options = {'ignore': false}; + } + if (event.options.ignore === false) { + params.remove(event.item.type, event.item.value); + filtersFetchInterval(); + } + }); + } + function watchOrder() { - $('select[name="order"]').val(params.get('order')); $('select[name="order"]').on('change', function (event) { - params.add('order', $(this).val()); + params.add('order', this.value); searchFetch(); }); } @@ -108,61 +185,59 @@ var search = function() { watchCheckbox('school_year', 'filter-school-year'); } - // control ajax requisitions (fetch) of filters - function filtersFetchInterval() { - // cancel previous function call - clearInterval(intervalId); - intervalId = setInterval(function () { - searchFetch(); - // cancel to not loop (interval) - clearInterval(intervalId); - }, 800); - } - function watchFilterSubject() { - // add values from url - var subjects = params.get('subject'); - $('.filter-subject').each(function() { - $(this).val(subjects).trigger('change'); - }); - // watch for changes - $('.filter-subject').on('change', function () { - var subject_filters = []; - $('.filter-subject').each(function() { - //add only non-null values - if($(this).val()) - subject_filters.push($(this).val()); - }); - //flatten the array - subject_filters = [].concat.apply([], subject_filters); + $('.filter-subject').on('select2:select', function (e) { + params.add('subject', e.params.data.id); - params.add('subject', subject_filters, true); + filtersFetchInterval(); + }); + $('.filter-subject').on('select2:unselect', function (e) { + params.remove('subject', e.params.data.id); filtersFetchInterval(); }); } - function watchCheckbox(type, name) { - // add values from url - var elements = params.get(type); - if (elements !== undefined) { - $('input[name="' + name + '"]').each(function() { - if (~elements.indexOf($(this).val())) { - $(this).attr('checked', true); - } - }); + function watchCheckbox(type, name, set) { + if (set === undefined) { set = false; } + if (set) { + var elements = params.get(type); + if (elements !== undefined) { + $('input[name="' + name + '"]').each(function() { + if (elements.indexOf(this.value) > -1) { + $(this).attr('checked', true); + } + else { + $(this).attr('checked', false); + } + }); + } } + else { + // watch for changes + $('input[name="' + name + '"]').on('click', function () { + if (this.checked) { + params.add(type, this.value); + } + else { + params.remove(type, this.value); + } - // watch for changes - $('input[name="' + name + '"]').on('change', function () { - params.reset(type); - $('input[name="' + name + '"]:checked').each(function(){ - params.add(type, $(this).val()); + filtersFetchInterval(); }); + } + } - filtersFetchInterval(); - }); + // control ajax requisitions (fetch) of filters + function filtersFetchInterval() { + // cancel previous function call + clearInterval(intervalId); + intervalId = setInterval(function () { + searchFetch(); + // cancel to not loop (interval) + clearInterval(intervalId); + }, 800); } return { @@ -227,28 +302,39 @@ var searchParameters = function() { return { reload: function(params_new) { params = params_new; + $(watch).trigger("params", ['reload', 'all']); }, add: function(type, value, replace) { - if (replace === undefined) { - replace = false; - } if (validate_type(type)) { + if (replace === undefined) { + replace = false; + } // if string type or replace if ((typeof params[type] === "string") || (typeof params[type] === "number") || replace) { - params[type] = value; + if (params[type] !== value) { + params[type] = value; + $(watch).trigger("params", ['add', type, value]); + } } // if object, append else { - params[type].push(value); + if (params[type].indexOf(value) === -1) { + params[type].push(value); + $(watch).trigger("params", ['add', type, value]); + } } } }, remove: function(type, value) { if (validate_type(type)) { + // value = encodeURIComponent(value); // if string type if ((typeof params[type] === "string") || (typeof params[type] === "number")){ // remove element - params[type] = ""; + if (params[type] !== ""){ + params[type] = ""; + $(watch).trigger("params", ['remove', type, value]); + } } // if object else { @@ -257,6 +343,7 @@ var searchParameters = function() { var index = params[type].indexOf(value); if (~index) { params[type].splice(index,1); + $(watch).trigger("params", ['remove', type, value]); } } } @@ -291,7 +378,7 @@ var searchParameters = function() { else { var object_length = params[keys[i]].length for (var j = 0; j < object_length; ++j) { - url += "&" + keys[i] + "=" + params[keys[i]][j]; + url += "&" + encodeURIComponent(keys[i]) + "=" + encodeURIComponent(params[keys[i]][j]); } } } @@ -302,10 +389,12 @@ var searchParameters = function() { if (type === undefined) { // reset params params = JSON.parse(JSON.stringify(default_params)); + // $(watch).trigger("params", ['all']); } else { // reset params.type params[type] = JSON.parse(JSON.stringify(default_params[type])); + // $(watch).trigger("params", [type, value]); } } }; diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index f92deb8281927af3585f07f99e4119354a5ec63c..42a0c5a2d2771ccbec3af0fada5056cbc83c1013 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -17,6 +17,7 @@ @import "bootstrap"; @import "select2"; @import "select2-bootstrap"; +@import "bootstrap-tagsinput"; $header-blue: #1676bc; $link-grey: #343D3E; @@ -304,10 +305,10 @@ footer { min-height: 256px; } - .footerbar { - padding: 16px; - background-color: #080808; - } + .footerbar{ + padding: 16px; + background-color: #AAB1AD; + } } .starRating:not(old) { @@ -458,3 +459,73 @@ table.tipo1 p { .fundo { background: black; } +.right-edge { + padding: 0px 45px; + margin-bottom: 25px; +} + +.left-edge { + position:absolute; +} + +.set-align { + position: relative; + margin: 5px; + padding: 0px 35px; + } + +.right-button { padding: 0px 60px; } + +.logo-footer{ + float: left; + margin-right: 1%; + margin-left: 1%; + width: 18%; + +} +.grey-panel{ + background-color: #EEEEEE; + width: 100; + padding: 40px; + text-align:center; + margin: 25px; +} + +.but { + display: inline-block; + background-color: #1676bc; + color: #fff; + padding: 8px 26px; + text-decoration: none; + box-sizing: border-box; + font-family: Helvetica; + font-weight: bold; + font-size: 16px; + border: 0px; +} + +.but-shadow { + box-shadow: 1px 1px 1px #999; +} + +.but-rc { + border-radius: 4px; +} + +.center_data{ + text-align:center; +} + +.thumb{ + width:250px; + margin-left: 50px; + border: solid 1px #ccc; +} +input.chk { + margin-top:5px; + margin-left:5px; +} + +.white-input input{ + border:none; +} diff --git a/app/assets/stylesheets/application/learning_objects.scss b/app/assets/stylesheets/application/learning_objects.scss index 485a0a462d51f601bc75e6822dbc3e7f4576dae9..3bd1088cb20b2c238acaa5a5fa7f382891d3eb69 100644 --- a/app/assets/stylesheets/application/learning_objects.scss +++ b/app/assets/stylesheets/application/learning_objects.scss @@ -81,7 +81,7 @@ $background-grey: #e7e7e8; font-weight: 400; } .rightbar { - margin-top: 230px; + margin-top: 100px; .media-heading { white-space: nowrap; diff --git a/app/assets/stylesheets/application/search.scss b/app/assets/stylesheets/application/search.scss index 0c741c551992ee34c1e76a6252a1798d8fb10e0a..4b51005dc0048aa21dd4805299d942a7fb6bda60 100644 --- a/app/assets/stylesheets/application/search.scss +++ b/app/assets/stylesheets/application/search.scss @@ -1,8 +1,26 @@ +#s2id_myelement > .select2-choice{ + background-color:green; +} .search-sidebar { margin-top: 40px; display: none; + .bootstrap-tagsinput { + border: 0; + box-shadow: 0px 0px 0px; + input { + display: none; + } + + .label { + font-size: 16px; + font-weight: 300; + display: inline-block; + margin-bottom: 6px; + } + } + .dropdown-element { width: 95%; margin-left: 3%; diff --git a/app/builders/learning_object_builder.rb b/app/builders/learning_object_builder.rb index a29135153805f759005bb5acf0e30b91e7f62566..d7e5cf5701e3f2208b3e6cf5850ce8323782e9cb 100644 --- a/app/builders/learning_object_builder.rb +++ b/app/builders/learning_object_builder.rb @@ -32,11 +32,10 @@ class LearningObjectBuilder id_dspace: args['id_dspace'], type: args['type'], bitstreams: args['bitstreams'], - metadata: args['metadata'], - last_modified: args['last_modified'] + last_modified: args['last_modified'], + metadata: JSON.parse(args['metadata']) ) end - lo.likes = args.key?('in_Likes') ? args['in_Likes'].size : 0 lo.views = args.key?('in_Views') ? args['in_Views'].size : 0 end diff --git a/app/controllers/collections_controller.rb b/app/controllers/collections_controller.rb index ab65c750c3f2c1cc8ec7abfe91213be8971501d9..bb580dcf20f3910660c90c8924e6c04a2c10ff4a 100644 --- a/app/controllers/collections_controller.rb +++ b/app/controllers/collections_controller.rb @@ -1,10 +1,11 @@ class CollectionsController < ApplicationController before_action :set_collection, only: [:show, :update, :destroy, :like] + before_action :authenticate_user!, except: [:index, :show] # GET /collections # GET /collections.json def index - @collections = collection_repository.all + @collections = collection_repository.all current_user end # GET /collections/1 @@ -22,6 +23,7 @@ class CollectionsController < ApplicationController # POST /collections.json def create @collection = Collection.new(collection_params) + @collection.owner = current_user respond_to do |format| if collection_repository.create @collection @@ -65,7 +67,4 @@ class CollectionsController < ApplicationController params.require(:collection).permit(:name, :description, learning_objects: []) end - def collection - end - end diff --git a/app/controllers/learning_objects_controller.rb b/app/controllers/learning_objects_controller.rb index 2217721f1267bdf39b40d4fa1b13f9977c47667d..af0edaa22a858eb0d18e65100145a74a8f982b46 100644 --- a/app/controllers/learning_objects_controller.rb +++ b/app/controllers/learning_objects_controller.rb @@ -1,7 +1,7 @@ class LearningObjectsController < ApplicationController include Reportable - before_action :set_learning_object, only: [:show, :edit, :update, :destroy, :like] + before_action :set_learning_object, only: [:show, :edit, :update, :destroy, :like, :bookmark] after_action :increment_learning_object_views, only: [:show] before_action :authenticate_user!, except: [:index, :show, :like] @@ -86,7 +86,14 @@ class LearningObjectsController < ApplicationController learning_object_repository.report current_user, @learning_object, message, description end - def bookmark + def bookmarks + bookmarks = current_user.bookmarks + bookmarks.add @learning_object + collection_repository.save bookmarks + + if request.xhr? + render json: {id: params[:id]} + end end private diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 7ba640079c6e661adddb6fc044de222bf98efb89..8798aceb0962910811d7ac70343c7f2ea9729280 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -38,26 +38,11 @@ class SearchController < ApplicationController # end end - # build objects from one page only - @objects = build_page_result(objectsFound, page, @pagination_limit) - @result = Kaminari.paginate_array(objectsFound).page(page).per(@pagination_limit) - render partial: 'search/fetch' - end - - private - - def build_page_result(objects, page, limit) - start = (page * limit) - limit - offset = page * limit - 1 - # build only objects from page - LearningObjectBuilder.build(objects[start..offset]) - end + # build objects from one page only + @objects = LearningObjectBuilder.build(@result) - def order_author(items) - # items = items.order_by{|item| [ item['author'].to_s.downcase ]} - # items.each{ |item| item['author'] = order_author(item['author']) if (item['author'].nil? ? [] : item['author']).size > 0 } - items + render partial: 'search/fetch' end end diff --git a/app/models/bookmarks.rb b/app/models/bookmarks.rb index 72fc563b1188c0204ef436e92f48a41847204454..da16e2d62eed65afb4858820e62bd1409f2bb849 100644 --- a/app/models/bookmarks.rb +++ b/app/models/bookmarks.rb @@ -8,4 +8,8 @@ class Bookmarks < Collection raise 'Bookmarks can`t change the name.' end + def valid? + @owner.is_a? User + end + end diff --git a/app/models/collection.rb b/app/models/collection.rb index d5a481f21750cc780eec290c1f1ec3319047972b..7b259a766fbf0489efb3dd33cdd471ee6b625eee 100644 --- a/app/models/collection.rb +++ b/app/models/collection.rb @@ -2,20 +2,47 @@ class Collection include ActiveModel::Model attr_accessor :id, :created_at, :last_modified, :name, :description, :privacy, :owner, :learning_objects - validates_presence_of :name, :created_at, :owner, :learning_objects - validates_with Validators::CollectionOwnerValidator - def initialize(params={}) - super(params.merge(defaults)) + def initialize(params = {}) + super(defaults.merge(params)) + end + + ## + # Add +learning_object+ to collection + # + # After adding some learning object to collection, you must use CollectionRepository to persist + # the changes. + # + # Example: + # @test_collection = Collection.new(name: 'test', description: 'test', owner: current_user) + # @test_collection.add @learning_object + # + # @test_collection.learning_objects # [@learning_object] + # collection_repository.save @test_collection + def add(learning_object) + learning_objects.append learning_object + end + + ## + # Remove +learning_object+ from collection + # + # After remove some learning object to collection, you must use CollectionRepository to persist + # the changes. + def remove(learning_object) + learning_objects.delete learning_object + end + + def valid? + !@name.blank? end private def defaults { - created_at: DateTime.new, - last_modified: DateTime.new, + created_at: DateTime.now.strftime("%Y-%m-%d %H:%M:%S"), + last_modified: DateTime.now.strftime("%Y-%m-%d %H:%M:%S"), owner: User.new, learning_objects: [], privacy: 'private' diff --git a/app/models/duplicated_user_index_error.rb b/app/models/duplicated_user_index_error.rb new file mode 100644 index 0000000000000000000000000000000000000000..1356e37c37b4b85f197f64f42071e9fc702438d0 --- /dev/null +++ b/app/models/duplicated_user_index_error.rb @@ -0,0 +1,2 @@ +class DuplicatedUserIndexError < Orientdb4r::ServerError +end \ No newline at end of file diff --git a/app/models/learning_object.rb b/app/models/learning_object.rb index bdc001228f505550b9a41c2742c353c3fbd17a2f..ade9205a8a48d81b0663b0d150320e36df8eb372 100644 --- a/app/models/learning_object.rb +++ b/app/models/learning_object.rb @@ -82,7 +82,7 @@ class LearningObject likes: 0, views: 0, downloads: 0, - created_at: DateTime.new + created_at: DateTime.now.strftime("%Y-%m-%d %H:%M:%S") } end diff --git a/app/models/user.rb b/app/models/user.rb index 2b6fdd7ff8a447267b13fcd8117ff5aed621ce43..8d183743fcd9df34be35424c6db0668ca4a57a5f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -29,7 +29,6 @@ class User < ActiveRecord::Base after_create SyncUserRepositoryService.new after_destroy SyncUserRepositoryService.new - after_create CreateUserBookmarksService.new after_destroy CreateUserBookmarksService.new has_attached_file :avatar, styles: {medium: "300x300>", thumb: "60x60>"}, default_url: lambda { |image| ActionController::Base.helpers.asset_path('user-anon.png') } diff --git a/app/repositories/orient_db/base.rb b/app/repositories/orient_db/base.rb index 13dee488917719753e60c2ad14f7ec85cc27f7d7..2058b678bf332956363e7622eb9a92a94ecd5574 100644 --- a/app/repositories/orient_db/base.rb +++ b/app/repositories/orient_db/base.rb @@ -1,5 +1,5 @@ class OrientDb::Base - include OrientDb::Methods::GenericMethods + include OrientDb::Methods::FinderMethods def initialize(orientdb_connection) @connection = orientdb_connection @@ -46,12 +46,12 @@ class OrientDb::Base end def build_hash(object) - hash = {} - hash["@class"] = odb_class + hash = {'@class' => odb_class} object.instance_variables.each do |var| var_name = sanitize_orientdb_vars(var) - hash[var_name] = object.instance_variable_get(var) + hash[var_name] = sanitize_orientdb_values(object.instance_variable_get(var)) end + hash.delete('id') hash end @@ -59,6 +59,10 @@ class OrientDb::Base var.to_s.gsub(/\A@/, "") end + def sanitize_orientdb_values(val) + val + end + def build_object(args={}) raise NoMethodError, "You must implement this method" end diff --git a/app/repositories/orient_db/collection_repository.rb b/app/repositories/orient_db/collection_repository.rb index e884f1c1145b07c7a3359d15756cdce7672116d6..39f8ed020c806e281fba8c59fc294a7fa4fac9f2 100644 --- a/app/repositories/orient_db/collection_repository.rb +++ b/app/repositories/orient_db/collection_repository.rb @@ -4,15 +4,13 @@ module OrientDb include OrientDb::Methods::GenericMethods def build_object(args={}) - Collection.new(args.merge(id: args['@rid'], - name: args['name'])) + Collection.new(map_object_hash(args)) end - def create_bookmarks_collection(user) - bookmarks = Bookmarks.new(owner: user) - - if !has_bookmarks?(user) - create bookmarks + def save(collection = Collection.new) + collection.learning_objects.each do |learning_object| + query = sprintf("update %s add learning_objects = %s", collection.id, learning_object.id) + connection.command query end end @@ -21,10 +19,14 @@ module OrientDb result end - def destroy_bookmarks_collection(user) + def create_bookmarks_collection(user) bookmarks = Bookmarks.new(owner: user) + create bookmarks + end - if has_bookmarks?(user) + def destroy_bookmarks_collection(user) + bookmarks = user.bookmarks + if has_bookmarks? user destroy bookmarks end end @@ -32,6 +34,7 @@ module OrientDb def create(object) super(object) create_edge "BelongsTo", object.id, object.owner.rid + object end def destroy(object) @@ -40,28 +43,46 @@ module OrientDb end def all(user) - build_objects(connection.query(sprintf("select expand(in('BelongsTo')) from %s", user.rid))) + query = sprintf("select * from (select expand(in('BelongsTo')) from %s) where name<>'Bookmarks'", user.rid) + objects = build_objects connection.query(query) end def bookmarks(user) - result = connection.query(sprintf("select expand(in('BelongsTo')) from %s where name = '%s'", user.rid, 'Bookmarks')) - build_object(result.first) + query = sprintf("select * from (select expand(in('BelongsTo')) from %s) where name='Bookmarks'", user.rid) + result = build_objects(connection.query(query)) + if !result.empty? + return result.first + end + create_bookmarks_collection(user) end def has_bookmarks?(user) - edge_exists? 'BelongsTo', user.bookmarks.id, user.rid + if !user.bookmarks.id.nil? && !user.rid.nil? + edge_exists? 'BelongsTo', user.bookmarks.id, user.rid + end end def build_hash(object) hash = super(object) - hash.delete("owner") - hash + hash.delete("owner") # delete owner, because it represents an edge in schema + hash.merge('name' => object.name) # forces name property for bookmarks end private + def map_object_hash(hash={}) + { + created_at: hash['created_at'], + last_modified: hash['last_modified'], + learning_objects: hash['created_at'], + privacy: hash['privacy'], + name: hash['name'], + id: hash['@rid'] + } + end + def odb_class - "Collection" + 'Collection' end end diff --git a/app/repositories/orient_db/learning_object_repository.rb b/app/repositories/orient_db/learning_object_repository.rb index 2b4e1d959e79ebb4edad086c5ccd0f17a868ce27..04d4f95b75659150e351bf9d488c4cdb8a16ed3c 100644 --- a/app/repositories/orient_db/learning_object_repository.rb +++ b/app/repositories/orient_db/learning_object_repository.rb @@ -34,7 +34,7 @@ module OrientDb def like(user, learning_object) like_edge_class = 'Likes' - if !liked? + if !liked? user, learning_object create_edge like_edge_class, user.rid, learning_object.id learning_object.likes = learning_object.likes + 1 end @@ -145,33 +145,48 @@ module OrientDb # FULLTEXT ENGINE LUCENE # METADATA {"analyzer":"org.apache.lucene.analysis.br.BrazilianAnalyzer"} def search(params) - # TODO: fix search metadata from dspace - order = params[:order] - qry = params[:query] - unless order.nil? - order = case order - when "author" - "author" - when "publicationasc" - "created_at" - when "publicationdesc" - "created_at DESC" - when "title" - "name ASC" + # mount cache_key with params + valid_params = %w(query order subject type school_year year) + cache_key = "search_result/" + valid_params.each do |param| + if params[param].class == Array + cache_key += params[param].join('-') else - nil + cache_key += params[param].to_s end + cache_key += '/' unless (param == valid_params.last) end - query = "SELECT EXPAND(rid) FROM index:learningobject_search WHERE key LUCENE '#{qry}'" - query = "SELECT * FROM (" + query + ") WHERE " + fetch_types(params[:type]) unless params[:type].blank? - query = "SELECT * FROM (" + query + ") ORDER BY #{order}" unless order.nil? - query = "SELECT @rid.asString(), last_modified FROM (" + query + ")" - learning_objects_hash = connection.query query, limit: 10000 + # get results in cache or search + Rails.cache.fetch(cache_key, expires_in: 10.minutes) do + qry = params[:query] + + order = params[:order] + unless order.nil? + order = case order + when "author" + "author" + when "publicationasc" + "created_at" + when "publicationdesc" + "created_at DESC" + when "title" + "name ASC" + else + nil + end + end + + query = "SELECT EXPAND(rid) FROM index:learningobject_search WHERE key LUCENE '#{qry}'" + query = "SELECT * FROM (" + query + ") WHERE " + fetch_types(params[:type]) unless params[:type].blank? + query = "SELECT * FROM (" + query + ") ORDER BY #{order}" unless order.nil? + query = "SELECT @rid.asString(), last_modified FROM (" + query + ")" + learning_objects_hash = connection.query query, limit: 10000 - # return only rids with their modification time - learning_objects_hash.map do |e| - {'@rid' => e['rid'], 'last_modified' => e['last_modified']} + # return only rids with their modification time + learning_objects_hash.map do |e| + {'@rid': e['rid'], 'last_modified': e['last_modified']} + end end end diff --git a/app/repositories/orient_db/user_repository.rb b/app/repositories/orient_db/user_repository.rb index 924b97b49c6be129504efe4db37938506dd04468..7a904ba1cb44a3d9391054b95662d31878103d9a 100644 --- a/app/repositories/orient_db/user_repository.rb +++ b/app/repositories/orient_db/user_repository.rb @@ -3,9 +3,15 @@ module OrientDb include RepositoriesProxy def create_graph_node(user) - if user.persisted? - connection.command sprintf("create vertex User set p_id = %d", user.id) - return true + begin + if user.persisted? + connection.command sprintf("create vertex User set p_id = %d", user.id) + return true + end + rescue Orientdb4r::ServerError => e + if e.message =~ /ORecordDuplicatedException/ + raise DuplicatedUserIndexError, 'The OrientDB index p_id of User class cannot be duplicated.' + end end raise NotPersistedRecordError, 'The user wasn`t persisted yet.' diff --git a/app/views/collections/_collection.html.erb b/app/views/collections/_collection.html.erb index be3a0dae7c9617a75e98e03de4f44f0d8e8c3ebd..6f630a4d6b09cd86cb89fd0f77df41c6361ae320 100644 --- a/app/views/collections/_collection.html.erb +++ b/app/views/collections/_collection.html.erb @@ -1,4 +1,4 @@ -<%= link_to collection, do %> +<%= link_to collection do %> <%= image_tag 'icons/collection', width: 24 %> <%= collection.name %> <% end %> \ No newline at end of file diff --git a/app/views/collections/_form.html.erb b/app/views/collections/_form.html.erb index 42bd3cfb3ef58e538d9c7f67b19ba50478382d6c..87e3d99acbde775bfe2c39e472ad8dd3d23cbaa1 100644 --- a/app/views/collections/_form.html.erb +++ b/app/views/collections/_form.html.erb @@ -1,7 +1,5 @@ <%= form_for collection do |f| %> - <%= f.label :name %> <%= f.text_field :name, required: true, style: 'width: 250px;' %> - <%= f.submit %> <% end %> diff --git a/app/views/collections/index.html.erb b/app/views/collections/index.html.erb index 17a6fc78e9ac25830ddafd57c38714d7c5ad5f93..0cefac7b39280e69cc5b8f02284e4408ac4902f2 100644 --- a/app/views/collections/index.html.erb +++ b/app/views/collections/index.html.erb @@ -242,4 +242,4 @@ </div> </div> </div> -<% end %> \ No newline at end of file +<% end %> diff --git a/app/views/devise/registrations/edit.html.erb b/app/views/devise/registrations/edit.html.erb index 97a0c18003ea6daedf31190ec395244a701cf5bd..c2c488bf17bb0e0724da814366a44b4d7b51368b 100644 --- a/app/views/devise/registrations/edit.html.erb +++ b/app/views/devise/registrations/edit.html.erb @@ -1,49 +1,63 @@ -<h2>Editar <%= resource_name.to_s.humanize %></h2> - <%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: {method: :put, multipart: true}) do |f| %> <%= devise_error_messages! %> - - <div class="field"> - <%= f.label :name %><br/> - <%= f.text_field :name, autofocus: true, required: true %> - </div> - - <div class="field"> - <%= f.label :email %><br/> - <%= f.email_field :email, autofocus: true %> - </div> - - <div class="field"> - <%= f.label :avatar %><br/> - <%= f.file_field :avatar %> - </div> - - <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %> - <div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div> - <% end %> - - <div class="field"> - <%= f.label :password, "Nova senha" %> <i>(deixe em branco caso não queira mudar a senha)</i><br/> - <%= f.password_field :password, autocomplete: "off" %> - </div> - - <div class="field"> - <%= f.label :password_confirmation %><br/> - <%= f.password_field :password_confirmation, autocomplete: "off" %> - </div> - - <div class="field"> - <%= f.label :current_password %> <i>(precisamos da sua senha atual para confirmar suas mudanças)</i><br/> - <%= f.password_field :current_password, autocomplete: "off" %> - </div> - - <div class="actions"> - <%= f.submit "Salvar" %> +<div class="container"> + <div class="row"> + <div class="col-md-12"> + <div class="grey-panel"> + <div class="container-fluid"> + <div class="col-md-8"> + + <div class="row"> + <div class="white-input"> + <div class="col-md-2"> + <%= image_tag image_path('user-anon.png'), class: "logo" %> + <br/> + <%= link_to 'editar foto', search_path,style:'color: #1676bc;' %><br/><%= f.file_field :avatar %> + </div> + <div class="col-md-10"> + <div style="text-align:left"> + <%= f.text_field :name, autofocus: true, required: true, style:"width:515px; height:60px;font-size:18pt;font-weight:bold; margin-bottom: 5px;" %> + <input type="text" size="55" placeholder="Nome instituição"> + </div> + <span class="pull-right"><input type="checkbox"> Conta de instituição</span><br/><br/> + <div style="text-align:left"> + Email: + <%= f.email_field :email, autofocus: true, style:"width:445px;" %> + <br/><br/> + <b>Alterar senha</b><br/> + + <table style="margin: 20px auto;"> + <tr> + <td>Senha atual:</td><td> <%= f.password_field :current_password, autocomplete: "off" ,style:"width:370px;" %></td> + </tr> + <tr> + <td colspan="2"><span class="pull-right"><div style="margin-bottom: 5px"><%= link_to 'Esqueci a senha', search_path, style:'color: #1676bc;'%></div></span></td> + </tr> + <tr> + <td> <div style="margin-bottom: 15px"> Nova senha:</div></td><td> <%= f.password_field :password, autocomplete: "off",style:"width:370px;" %></td> + </tr> + <tr> + <td> Confirmar senha:</td><td> <%= f.password_field :password_confirmation, autocomplete: "off" ,style:"width:370px;"%></td> + </tr> + </table> + <b>Conta</b><br/> + <div style="margin: 5px 5px;"> + <%= link_to 'Deletar conta', search_path, style:'color: #FF3300;'%> + <!-- <%= button_to "Deletar conta", registration_path(resource_name), data: {confirm: "Are you sure?"}, method: :delete, style:'color: #FF3300;' %> + --></div> + + </div> + </div> + </div> + </div> + </div> + <div class="col-md-4"> + <%= link_to 'Cancelar',:back, class: "btn", style: 'height: 35px; width: 130px; color:white; background-color: #FF3300;' %> + <%= f.submit "Salvar",class: "btn", style: 'height: 35px; width: 130px; color:white; background-color: #1676bc;' %> + </div> + </div> + </div> </div> + </div> +</div> <% end %> - -<h3>Excluir minha conta</h3> - -<p><%= button_to "Excluir", registration_path(resource_name), data: {confirm: "Você tem certeza?"}, method: :delete %></p> - -<%= link_to "Voltar", :back %> diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb index 3f55ecb667ef8357a39facdc431cf24750abb4b6..fe3d444de41b7cc9b1e52de9de517ada33b80035 100644 --- a/app/views/devise/sessions/new.html.erb +++ b/app/views/devise/sessions/new.html.erb @@ -1,26 +1,62 @@ -<h2>Entrar</h2> - <%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %> - <div class="field"> - <%= f.label :email %><br /> - <%= f.email_field :email, autofocus: true %> - </div> +<div class="container"> + <div class="row"> + <div class=" col-md-12"> + <div class="white-input"> + <div class="grey-panel"> + <h2>Entrar</h2> + <br/> + <%= image_tag image_path('user-anon.png'), class: "logo" %><br/><br/> - <div class="field"> - <%= f.label :password %><br /> - <%= f.password_field :password, autocomplete: "off" %> - </div> + <form action="" method=""> + <table style="margin: 20px auto;"> + <tr> + <td>Email:</td><td> </td> + <td style=" padding: 10px;"> + <%= f.email_field :email, autofocus: true , style:"width:375px;"%> + </td> + </tr> - <% if devise_mapping.rememberable? -%> - <div class="field"> - <%= f.check_box :remember_me %> - <%= f.label :remember_me %> + <tr> + <td>Senha:</td><td> </td> + <td><%= f.password_field :password, autocomplete: "off", style:"width:375px;" %></td> + </tr> + <tr> + <td></td><td></td> + <td> + <span class="pull-right"> + <% if devise_mapping.rememberable? -%> + <div class="field"> + <%= f.check_box :remember_me %> + <%= f.label :remember_me %> + </div> + <% end -%> + <%= link_to "Esqueceu sua senha?", new_password_path(resource_name) , style:'color: #FF3300;' %> + </span></td> + </tr> + </table> + </form> + <br/> + <br/> + <div class="container-fluid"> + <div class="col-md-offset-3 col-md-4"> + <div class="col-md-7"> + <span class="pull-right">Não possui conta?</span><br/> + <span class="pull-right"> + <%= link_to "Cadastre-se", new_registration_path(resource_name),style:'color: #1676bc;' %> + </span> + </div> + <div class=" col-md-3"> + <span class="pull-left"> + <%= f.submit "Entrar", class: "btn", style: ' width: 230px; color:white; background-color: #1676bc;' %> + </span> + <br/> + </div> + </div> + </div> + </div> + </div> </div> - <% end -%> - - <div class="actions"> - <%= f.submit "Entrar" %> </div> +</div> <% end %> - -<%= render "devise/shared/links" %> diff --git a/app/views/learning_objects/show.html.erb b/app/views/learning_objects/show.html.erb index 5f87f10d8fd61f54426dd947166baa18912327ed..a21298c24756b9fa37a395e002cabd8699ac915d 100644 --- a/app/views/learning_objects/show.html.erb +++ b/app/views/learning_objects/show.html.erb @@ -26,10 +26,11 @@ <div class="row learning-object"> <div class="col-md-7"> <%= learning_object_thumbnail @learning_object, "large" %> - <div class="stats"> + <div class="pull-right" style="padding-right:122px"> <span class="glyphicon glyphicon-eye-open"><%= @learning_object.views %> </span> <span class="glyphicon glyphicon-star"><%= @learning_object.likes %> </span> </div> + <br/><br/> <h2 class="title"><%= @learning_object.name %></h2> <% unless @learning_object.description.nil? %> <p class="description"><%= @learning_object.description %></p> @@ -89,29 +90,14 @@ </div> </div> -<!-- <div class="container-fluid"> + <div class="container-fluid"> <div class="container-fluid"> - <div class="row"> + <!-- <div class="row"> <div class="col-sm-6"> - <a href=""> - <img alt="<%=@learning_object.name %>" class="img-responsive" height="550" src="<%= @learning_object.thumbnail %>" width="600"> - </a> - <p> - <h1><%= @learning_object.name %></h1> - </p> + </div> <div class="col-sm-6"> - <div class="col-sm-12"> - <div class="row"> - <div class="col-md-12">Adicionado por: - <h1> - <img class="img-circle" src="images/user.jpg"> - <a href="autor.php"><%= @learning_object.get_metadata_value_of("dc.contributor.author") %></a> - </h1> - </div> - </div><br/> - <%= @learning_object.get_metadata_value_of("dc.description") %> - </div> + <div class="col-sm-12"> <br/> <table class="table"> @@ -134,15 +120,13 @@ </tr> </table><br/> <!--div class="pull-right"--> - <!-- <div style="text-align: center;"> - <a class="btn btn-primary" href="#">Download</a> - </div> +<!-- </div> </div> - </div> - <br/><br/> + </div>--> + <br/> <div class="row"> - <div class="col-sm-8"> + <div class="col-sm-7"> <ul> <li> <b>Autor: @@ -178,8 +162,8 @@ like_learning_object_path(@learning_object.id_dspace), method: :post, remote: true %> <% end %> - <br/> --> - <!-- <div class="row"> + <br/> + <div class="row"> <div class="col-md-12"> <h1>Comentários</h1> </div> @@ -244,14 +228,15 @@ </div> <br/> - </div> --> + </div> <!--arquivos relacionados--> - <!-- <div class="col-sm-4"> + <div class="col-sm-5"> <div class="row"> - <div class="col-md-12"> + <div class="col-md-12" style ="text-align:center"> <h1> - Arquivos relacionados + Arquivos similares </h1> + <br/><br/> </div> </div> <%# @related_objects.each do |o| %> @@ -277,10 +262,10 @@ </div> </div><hr> <%# end %> - </div> --> -<!-- </div> + </div> +</div> <br/> </div> <!-- container fluid --> -<!-- </div> --> + </div> <!-- /container --> diff --git a/app/views/search/index.html.erb b/app/views/search/index.html.erb index dc085d56cc8ee17e0fb0926b5abfe5c57fa9dd44..796b7fa4d399d3d2ee7a984344d3aafec7500f15 100644 --- a/app/views/search/index.html.erb +++ b/app/views/search/index.html.erb @@ -8,11 +8,11 @@ </div> <div class="media-body"> <h3 class="media-heading">Filtros</h3> - Nenhum selecionado + <select class="filter-panel" multiple="multiple"></select> </div> </div> - <div class="nestedAccordion search-link"> + <div class="nestedAccordion"> <h3 class="dropdown open">Matérias<span class="caret caret-align-right"/></h3> <div class="dropdown-element"> @@ -30,9 +30,9 @@ <div> <select class="select-tag-container filter-subject" multiple="multiple"> <option value="">Todos</option> - <option value="Plantas">Plantas</option> - <option value="">...</option> - <option value="">...</option> + <option value="Plantas">Plantas</option> + <option value="">...</option> + <option value="">...</option> </select> </div> <h4 class="dropdown">História<span class="caret caret-align-right"/></h4> @@ -285,7 +285,21 @@ </div> <script type="text/javascript"> + $('.filter-panel').tagsinput({ + itemValue: 'value', + tagClass: function(item) { + switch (item.type) { + case 'query' : return 'label label-primary'; + case 'order' : return 'label label-danger label-important'; + case 'subject': return 'label label-success'; + case 'type' : return 'label label-default'; + case 'school_year' : return 'label label-warning'; + } + }, + freeInput: false + }); $(".select-tag-container").select2(); + runDropdown($('.nestedAccordion .dropdown')); $('.nestedAccordion .dropdown').click(function () { runDropdown(this); diff --git a/app/views/shared/application/_footer.html.erb b/app/views/shared/application/_footer.html.erb index e4e96daded60b0425116993001ddcdc52d5cb7c0..f4a0e006f9c86fa03d51a58800c8cb4faa021331 100644 --- a/app/views/shared/application/_footer.html.erb +++ b/app/views/shared/application/_footer.html.erb @@ -1,31 +1,42 @@ <footer> - <div class="main"> + <div class="main" style="background-color: #E6E6E6;"> <div class="container" style="min-height: 200px;"> - <div class="col-md-3"> - <%= image_tag 'logo.png', height: '120' %> - </div> - <div class="col-md-9" style="padding-top: 20px"> + <div class="col-md-12" style="padding-top: 50px"> + <div class="logo-footer"> <%= link_to 'http://www.brasil.gov.br/' do %> - <%= image_tag 'logo_brasil.png', style: 'margin-left: 20px' %> + <%= image_tag 'logo_brasil.png', style: 'width: auto; height: 70px;' %> + <% end %> + </div> + <div class="logo-footer"> + <%= link_to 'http://www.fnde.gov.br/' do %> + <%= image_tag 'logo_ministerio.png', height: '70', style: 'width: auto; height: 70px; margin-left: 18%;' %> <% end %> + </div> + <div class="logo-footer"> <%= link_to 'http://www.fnde.gov.br/' do %> - <%= image_tag 'logo_fnde.jpg', height: '70', style: 'margin-left: 20px' %> + <%= image_tag 'fnde.png', height: '70', style: 'width: auto; height: 100px; margin-top: -8%;' %> <% end %> + </div> + <div class="logo-footer"> <%= link_to 'http://www.ufpr.br/portalufpr/' do %> - <%= image_tag 'logo_ufpr.jpg', height: '100', style: 'margin-left: 20px'%> + <%= image_tag 'logo_ufpr.jpg', height: '100', style: 'width: auto; height: 70px;'%> <% end %> - + </div> + <div class="logo-footer"> <%= link_to 'http://www.c3sl.ufpr.br/' do %> - <%= image_tag 'logo_c3.png', style: 'margin-left: 20px'%> + <%= image_tag 'logo_c3.png', style: 'width: auto; height: 70px;'%> <% end %> </div> + </div> </div> <div class="footerbar"> <div class="container"> + <div style="text-align:center"> <%= image_tag 'cc.png' %> Creative Commons Attribution 4.0 International Licence </div> + </div> </div> </div> </footer> diff --git a/app/views/shared/application/_links.html.erb b/app/views/shared/application/_links.html.erb index ed72aa842c8e323df4b9f33e150ffcc93d188b8e..afb8fcb9ca9dea64d3fb95f2f3e95b570f56b4c6 100644 --- a/app/views/shared/application/_links.html.erb +++ b/app/views/shared/application/_links.html.erb @@ -2,15 +2,13 @@ <div class="col-md-8"> <h4><b>Portais nacionais e internacionais</b></h4> <div class="row inner-column"> - <ul class="list-unstyled col-md-6"> + <ul class="list-bullet col-md-12"> <li><a href="">Portais Educacionais</a></li> <li><a href="">Museus</a></li> <li><a href="">Bibliotecas</a></li> <li><a href="">Revistas</a></li> <li><a href="">Projetos Inovadores</a></li> <li><a href="">Jornais</a></li> - </ul> - <ul class="list-unstyled col-md-6"> <li><a href="">Projeto de escolas</a></li> <li><a href="">Um computador por aluno</a></li> <li><a href="">Geoprocessamento</a></li> @@ -22,7 +20,7 @@ <div class="col-md-4"> <h4><b>Visite também</b></h4> <div class="row inner-column"> - <ul class="list-unstyled col-md-12"> + <ul class="list-bullet col-md-12"> <li><a href="">DomÃnio Público</a></li> <li><a href="">E-ProInfo</a></li> <li><a href="">Objetos Educacionais</a></li> diff --git a/app/views/welcome/add_file.html.erb b/app/views/welcome/add_file.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..d7b64b59b66aa378834aa9d0555f34cd7b97b13e --- /dev/null +++ b/app/views/welcome/add_file.html.erb @@ -0,0 +1,77 @@ + + + +<div class="container"> + <div class="row"> + <div class="col-md-12"> + <div class="container-fluid" style="margin-left:10px;"> + <%= image_tag image_path('icons/upload.png'), class: "logo",style:"width:50px;" %> + <span class="pull-left"><h3 style="position:absolute; margin-left:60px;">Adicionando x arquivos</h3> + </div> + </div><br/> + <div class="grey-panel"> + <div class="container-fluid"> + <div class="row"> + <div class="white-input"> + + <div class="col-md-3"> + <%= image_tag image_path('icons/square.png'), style:"width:250px; height:150px;" %><br/> + <%= link_to 'editar foto', search_path,style:'color: #1676bc;' %> + </div> + <div class="col-md-9"> + + <table style="margin-left:0px;"> + <tr> + <td colspan="2"> + <input type="text" size="70px" style="height:30px;font-size:14pt; margin-bottom: 10px;" placeholder="TÃtulo do arquivo"> + </td> + </tr> + <tr> + <td colspan="2"> + <input type="text" size="70px" style="height:65px;font-size:14pt; margin-bottom: 10px;" placeholder="Descrição"> + <br/> + </td> + </tr> + <tr> + <td colspan="2"> <input type="text" size="70px" style="height:30px;font-size:14pt; margin-bottom: 10px;" placeholder="Assunto"></td> + </tr> + <tr> + <td> + <select style="width: 345px; margin-left:8px"> + <option value="">NÃvel</option> + <option value="">..</option> + </select> + + </td> + <td> + <select style="width: 345px;"> + <option value="">Adicionar à coleção</option> + <option value="">..</option> + </select> + </td> + </tr> + <tr> + <td colspan="2"> + <div class=" pull-right"> <%= button_to "Remover", new_user_registration_path,class: "btn btn-danger", style: 'margin-top: 15px; width: 130px; background-color: #FF2134;'%></div> + </td> + </tr> + </table> + + </div> + </div> + </div> + </div> + </div> + <div class="col-md-12"> + <div class="container-fluid" > + <div class="pull-right"> + <input type="checkbox" > Li e concordo com os <%= link_to 'termos e condições', search_path, style:'color: #1676bc;' %> de upload e copyright<br/><br/> + <div class="pull-left"><div style= 'margin-left:130px;'><%= link_to 'Cancelar', search_path %></div></div> + <div class="pull-right"><%= button_to "Salvar", search_path,class: "btn pull-right", style: 'margin-top: -10px; width: 230px; color:white; background-color: #1676bc;'%></div> + + </div> + </div> + </div> + </div> + </div> +</div> diff --git a/app/views/welcome/collection.html.erb b/app/views/welcome/collection.html.erb index 28fa4d131c98121a73c425ea9a2bbe64bb95f463..c8d1afb594127908b3cd8312488fa5bb4113aab2 100644 --- a/app/views/welcome/collection.html.erb +++ b/app/views/welcome/collection.html.erb @@ -2,6 +2,11 @@ <nav class="navigation navbar-default "><br/> <div class="container-fluid"> + <div class="navbar-right"> + <%= link_to 'http://www.fnde.gov.br/' do %> + <%= image_tag 'icons/collection-download.png', style: 'width: auto; height: 40px; margin-right: 20px;' %><span style="margin-right: 30px;"><button class="but but-shadow but-rc">Editar Coleção</button></span> + <% end %> + </div> <div class="navbar-header"> <%= image_tag image_path("icons/collection.png"), class: "logo-image",size: "90x66" %> <ul class="nav navbar-nav navbar-right"><h1> <b>Coleção 1</b></h1> <br/> @@ -11,12 +16,12 @@ <br/></nav> <nav class="navigation navbar-inverse "> <div class="container-fluid"> - <a class="navbar-brand" href="#">x arquivo(s) selecionado(s)</a> + <a class="navbar-brand" href="#"><font color="FFFFFF">x arquivo(s) selecionado(s)</font></a> <ul class="nav navbar-nav navbar-right"> - <li><a href="#"><%= image_tag image_path("icons/collection1.png"), class: "logo-image",size: "35x28" %> Salvar no computador</a></li> - <li><a href="#"><%= image_tag image_path("icons/collection1.png"), class: "logo-image",size: "35x28" %> Copiar para</a></li> - <li><a href="#"><%= image_tag image_path("icons/collection1.png"), class: "logo-image",size: "35x28" %> Mover para</a></li> - <li><a href="#"><%= image_tag image_path("icons/collection1.png"), class: "logo-image",size: "35x28" %> Remover da coleção</a></li> + <li class="set-align"><a href="#"><span class="left-edge"><%= image_tag image_path("icons/Download_01.png"), class: "logo-image",size: "35x35" %></span><font color="FFFFFF"> Salvar no <br>computador</font></br></a></li> + <li class="set-align"><a href="#"><span class="left-edge"><%= image_tag image_path("icons/Copiar_Seleção.png"), class: "logo-image",size: "35x35" %></span><font color="FFFFFF"> Copiar <br>para</font></br></a></li> + <li class="set-align"><a href="#"><span class="left-edge"><%= image_tag image_path("icons/Mover_Seleção.png"), class: "logo-image",size: "35x35" %></span><font color="FFFFFF"> Mover <br>para</font></br></a></li> + <li class="set-align"><a href="#"><span class="left-edge"><%= image_tag image_path("icons/Remover_da_Coleção_Seleção.png"), class: "logo-image",size: "35x35" %></span><font color="FFFFFF"> Remover da <br>coleção</font></br></a></li> </ul> </div> </nav> @@ -24,18 +29,45 @@ <div class="row mainpage-subjects"> <br/> <div class="col-md-4"> - Obj 1<br/> - Obj 4<br/> - Obj 7 + <div class="thumb"> + <input type="checkbox" class="chk " checked="checked" name="" value="0" /> + <%= image_tag image_path('learning-object-preview.png'), class: "logo" %>Obj1 + </div><br/> + <div class="thumb"> + <input type="checkbox" class="chk " checked="checked" name="" value="0" /> + <%= image_tag image_path('learning-object-preview.png'), class: "logo" %>Obj4 + </div><br/> + <div class="thumb"> + <input type="checkbox" class="chk " checked="checked" name="" value="0" /> + <%= image_tag image_path('learning-object-preview.png'), class: "logo" %>Obj7 + </div> </div> <div class="col-md-4"> - Obj 2<br/> - Obj 5<br/> - Obj 8 + <div class="thumb"> + <input type="checkbox" class="chk " checked="checked" name="" value="0" /> + <%= image_tag image_path('learning-object-preview.png'), class: "logo" %>Obj2 + </div><br/> + <div class="thumb"> + <input type="checkbox" class="chk " checked="checked" name="" value="0" /> + <%= image_tag image_path('learning-object-preview.png'), class: "logo" %>Obj5 + </div><br/> + <div class="thumb"> + <input type="checkbox" class="chk " checked="checked" name="" value="0" /> + <%= image_tag image_path('learning-object-preview.png'), class: "logo" %>Obj8 + </div> </div> <div class="col-md-4"> - Obj 3<br/> - Obj 6<br/> - Obj 9 + <div class="thumb"> + <input type="checkbox" class="chk " checked="checked" name="" value="0" /> + <%= image_tag image_path('learning-object-preview.png'), class: "logo" %>Obj3 + </div><br/> + <div class="thumb"> + <input type="checkbox" class="chk " checked="checked" name="" value="0" /> + <%= image_tag image_path('learning-object-preview.png'), class: "logo" %>Obj6 + </div><br/> + <div class="thumb"> + <input type="checkbox" class="chk " checked="checked" name="" value="0" /> + <%= image_tag image_path('learning-object-preview.png'), class: "logo" %>Obj9 + </div> </div> </div> diff --git a/app/views/welcome/follow_collection.html.erb b/app/views/welcome/follow_collection.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..d3b53cc71c656202108697f32b0b3a42fa934d1a --- /dev/null +++ b/app/views/welcome/follow_collection.html.erb @@ -0,0 +1,64 @@ +<!--Page the user can follow a collection --> + +<nav class="navigation navbar-default "><br/> + <div class="container-fluid"> + <div class="navbar-right"> + <%= link_to 'http://www.fnde.gov.br/' do %> + <%= image_tag 'icons/collection-download.png', style: 'width: auto; height: 40px; margin-right: 20px;' %> + <span style="margin-right: 30px;"><button class="but but-shadow but-rc">Seguir Coleção</button></span> + <% end %> + </div> + <div class="navbar-header"> + <%= image_tag image_path("icons/collection.png"), class: "logo-image",size: "90x66" %> + <ul class="nav navbar-nav navbar-right"><h1> <b>Coleção 1</b></h1> <br/> + <%= image_tag image_path("user-anon.png"), class: "logo-image",size: "30x30" %> por Usuário + <%= image_tag image_path("icons/square.png"), class: "logo-image",size: "20x20" %> 200 itens</ul> + </div> + </div> +</nav> + +<div class="row mainpage-subjects"> + <br/> + <div class="col-md-4"> + <div class="thumb"> + <input type="checkbox" class="chk " checked="checked" name="" value="0" /> + <%= image_tag image_path('learning-object-preview.png'), class: "logo" %>Obj1 + </div><br/> + <div class="thumb"> + <input type="checkbox" class="chk " checked="checked" name="" value="0" /> + <%= image_tag image_path('learning-object-preview.png'), class: "logo" %>Obj4 + </div><br/> + <div class="thumb"> + <input type="checkbox" class="chk " checked="checked" name="" value="0" /> + <%= image_tag image_path('learning-object-preview.png'), class: "logo" %>Obj7 + </div> + </div> + <div class="col-md-4"> + <div class="thumb"> + <input type="checkbox" class="chk " checked="checked" name="" value="0" /> + <%= image_tag image_path('learning-object-preview.png'), class: "logo" %>Obj2 + </div><br/> + <div class="thumb"> + <input type="checkbox" class="chk " checked="checked" name="" value="0" /> + <%= image_tag image_path('learning-object-preview.png'), class: "logo" %>Obj5 + </div><br/> + <div class="thumb"> + <input type="checkbox" class="chk " checked="checked" name="" value="0" /> + <%= image_tag image_path('learning-object-preview.png'), class: "logo" %>Obj8 + </div> + </div> + <div class="col-md-4"> + <div class="thumb"> + <input type="checkbox" class="chk " checked="checked" name="" value="0" /> + <%= image_tag image_path('learning-object-preview.png'), class: "logo" %>Obj3 + </div><br/> + <div class="thumb"> + <input type="checkbox" class="chk " checked="checked" name="" value="0" /> + <%= image_tag image_path('learning-object-preview.png'), class: "logo" %>Obj6 + </div><br/> + <div class="thumb"> + <input type="checkbox" class="chk " checked="checked" name="" value="0" /> + <%= image_tag image_path('learning-object-preview.png'), class: "logo" %>Obj9 + </div> + </div> +</div> diff --git a/app/views/welcome/index.html.erb b/app/views/welcome/index.html.erb index 49f1f354f7f43cfb23bc0ff0e79f399be15d2afe..265470328f7ef607fc381d21f5e3d3a9380a5552 100644 --- a/app/views/welcome/index.html.erb +++ b/app/views/welcome/index.html.erb @@ -1,86 +1,86 @@ <div class="row"> - <div class="col-md-7"> + <div class="<%= (user_signed_in?) ? 'col-md-12' : 'col-md-7' %>"> <div class="row"> <% if @carousel.present? %> - <div id="myCarousel" class="carousel slide" data-ride="carousel"> - <!-- Indicators --> - <ol class="carousel-indicators"> - <% i = 0 %> - <% @carousel.each do |highlight| %> - <% if highlight == @carousel.first %> - <li data-target="#myCarousel" data-slide-to="<%= i %>" class="active"></li> - <% else %> - <li data-target="#myCarousel" data-slide-to="<%= i %>"></li> + <div id="myCarousel" class="carousel slide" data-ride="carousel"> + <!-- Indicators --> + <ol class="carousel-indicators"> + <% i = 0 %> + <% @carousel.each do |highlight| %> + <% if highlight == @carousel.first %> + <li data-target="#myCarousel" data-slide-to="<%= i %>" class="active"></li> + <% else %> + <li data-target="#myCarousel" data-slide-to="<%= i %>"></li> + <% end %> + <% i+= 1 %> <% end %> - <% i+= 1 %> - <% end %> - </ol> - <div class="carousel-inner" role="listbox"> - <% @carousel.each do |highlight|%> - <% if highlight == @carousel.first %> - <% highlight_class="item active" %> - <% else %> - <% highlight_class="item" %> - <% end %> - <div class="<%= highlight_class %>"> - <%= image_tag highlight.image.url(:larger) %> - <div class="container"> - <div class="carousel-caption"> - <h1><%= link_to highlight.title, highlight.url, style: 'color: white;'%></h1> + </ol> + <div class="carousel-inner" role="listbox"> + <% @carousel.each do |highlight| %> + <% if highlight == @carousel.first %> + <% highlight_class="item active" %> + <% else %> + <% highlight_class="item" %> + <% end %> + <div class="<%= highlight_class %>"> + <%= image_tag highlight.image.url(:larger) %> + <div class="container"> + <div class="carousel-caption"> + <h1><%= link_to highlight.title, highlight.url, style: 'color: white;' %></h1> - </div> - </div> + </div> + </div> + </div> + <% end %> </div> - <% end %> </div> - </div> <% end %> </div> <div class="row mainpage-highlights"> <% if @general.present? %> - <ul class="list-unstyled"> - <h2>Destaques</h2> - <%= render @general, orientation: 'horizontal' %> - <% end %> + <ul class="list-unstyled"> + <h2>Destaques</h2> + <%= render @general, orientation: 'horizontal' %> + <% end %> </ul> </div> </div> + <% if !user_signed_in? %> <div class="col-md-3 col-md-offset-1 hidden-xs hidden-sm"> <div class="panel-wrapper"> - <div style="padding: 30px; min-height: 400px"> - <h2>Cadastre-se!</h2><br> - <h2>Vantagens de cadastrar:</h2><br> - <h2>Faça suas coleções.</h2><br> - <h2>Curta objetos.</h2><br> - <h2>Tenha seus objetos favoritos.</h2><br> + <div style="padding: 30px; min-height: 400px;"> + <div style="text-align:center"><%= image_tag image_path('icons/signup.png'), class: "logo",size: "140x140" %></div> + <div style="text-align:center"><h2>Cadastre-se para aproveitar:</h2></div><br/> + <h4><div class="left-edge"><%= image_tag image_path('icons/star-gold.png'), class: "logo",size: "30x30" %></div><div class="right-edge">Avalie, comente e favorite arquivos.</div></h4> + <h4><div class="left-edge"><%= image_tag image_path('icons/foldergreen.png'), class: "logo",size: "30x30" %></div><div class="right-edge">Siga coleções e usuários.</div></h4> + <h4><div class="left-edge"><%= image_tag image_path('icons/downloadred.png'), class: "logo",size: "30x30" %></div><div class="right-edge">Crie coleções para rápido acesso e download.</div></h4> </div> <div style="width: 100%; padding: 30px;"> <%= form_tag(new_user_registration_path, method: 'get') do %> - <%= text_field_tag :email, '', placeholder: "Seu email", class: 'form-control'%> - <%= button_to "Cadastrar-se", new_user_registration_path,class: "btn btn-danger", style: 'margin-top: 10px; width: 230px; background-color: #FF2134;'%> + <%= text_field_tag :email, '', placeholder: "Seu email", class: 'form-control'%> + <div class="right-button"><%= button_to "Cadastrar", new_user_registration_path,class: "btn btn-danger", style: 'margin-top: 10px; width: 230px; background-color: #FF2134;'%></div> <% end %> </div> </div> </div> + <% end %> </div> <div class="row mainpage-subjects"> <div class="col-md-12"> <% unless @subjects.blank? %> - <div class="row learning-object-columns"> - <h2>Destaque por assunto</h2> - <% @subjects.each do |subject|%> - <% if !subject.highlights.empty? %> - <div class="row mainpage-subject-element"> - <h4><b><%= subject.name %></b></h4> - <%= render subject.highlights.first, orientation: 'vertical'%> - <p class="more"> - <a href="#">Ver Mais</a> - </p> - </div> + <div class="row learning-object-columns"> + <h2>Destaque por assunto</h2> + <% @subjects.each do |subject| %> + <div class="row mainpage-subject-element"> + <h4><b><%= subject.name %></b></h4> + <%= render subject.highlights.first, orientation: 'vertical' unless subject.highlights.first.nil? %> + <p class="more"> + <a href="#">Ver Mais</a> + </p> + </div> <% end %> - <% end %> - </div> + </div> <% end %> </div> </div> diff --git a/app/views/welcome/signup.html.erb b/app/views/welcome/signup.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..dbf4419fa9dc1f586c088cfc6df39e69423abfbe --- /dev/null +++ b/app/views/welcome/signup.html.erb @@ -0,0 +1,40 @@ + <div class="container"> + <div class="row"> + <div class="col-md-12"> + <div class="grey-panel"> + <div class="center_data"> + <h2 ><FONT COLOR="#343D3E" FACE="Arial">Cadastre-se</font></h2><br/> + <%= image_tag image_path("user-anon.png")%><br/> + <font color="#1676bc">adicionar foto</font><br/></br></div> + <div class="col-md-10"> + <p style="line-height: 170%"><div class="col-md-10"><span class="pull-right">Nome: + <input type="text" value="nome completo" size="35"></span></div><br/></p> + <p style="line-height: 15%"><br/></p> + <p style="line-height: 170%"><div class="col-md-10"><span class="pull-right">Email: + <input type="text" value="email@email.com" size="35"></span></div><br/></p> + <p style="line-height: 15%"><br/></p> + <p style="line-height: 170%"><div class="col-md-10"><span class="pull-right">Senha: + <input type="password" value="*********" size="35" ></span></div><br/></p> + <p style="line-height: 15%"><br/></p> + <p style="line-height: 170%"><div class="col-md-10"><span class="pull-right">Confirmar senha: + <input type="password" value="*********" size="35" ></span></div><br/><br/></p> + </div> + + <div class="container-fluid"> + <div class="col-md-offset-3 col-md-5"> + <div class="center_data"> + <div class="col-md-6"> + <br/><span class="pull-right">Já possui conta?</span><br/> + <span class="pull-right"><%= link_to 'Entre aqui', search_path, {:style=>'color:#1676bc'} %></span> + </div> + <div class=" col-md-5"> + <br/><span class="pull-right"><button class="but but-shadow but-rc">Cadastrar</button></span><br/> + </div> + </div> + </div> + </div> + + </div> + </div> + </div> +</div> diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 71977fe5551090ba930d3331fd148e0eb6c93ac4..783f03dc6d622195238cc581483f63e697cee4c2 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -107,6 +107,7 @@ pt-BR: models: attribute: "Atributo" carousel: "Carossel" + bookmarks: "Favoritos" collection: "Coleção" institution: "Instituição" learning_object: "Objeto Educacional" @@ -122,6 +123,12 @@ pt-BR: password: "Senha" password_confirmation: "Confirme sua senha" current_password: "Senha atual" + remember_me: "lembrar de mim?" + bookmarks: + name: "Nome" + description: "Descrição" + privacy: "Privacidade" + learning_objects: "Objetos Educacionais" errors: template: header: @@ -148,4 +155,4 @@ pt-BR: less_than: "precisa ser menor do que {{count}}" less_than_or_equal_to: "precisa ser menor ou igual a {{count}}" odd: "precisa ser Ãmpar" - even: "precisa ser par" + even: "precisa ser par" \ No newline at end of file diff --git a/config/puma.rb b/config/puma.rb new file mode 100644 index 0000000000000000000000000000000000000000..9642a0d7ded117cf53d4aee0fae656b9bab7eb95 --- /dev/null +++ b/config/puma.rb @@ -0,0 +1,29 @@ +# Change to match your CPU core count +workers 2 + +# Min and Max threads per worker +threads 1, 6 + +app_dir = File.expand_path("../..", __FILE__) +shared_dir = "#{app_dir}/shared" + +# Default to production +rails_env = ENV['RAILS_ENV'] || "production" +environment rails_env + +# Set up socket location +bind "unix://#{shared_dir}/sockets/puma.sock" + +# Logging +stdout_redirect "#{shared_dir}/logs/puma.stdout.log", "#{shared_dir}/logs/puma.stderr.log", true + +# Set master PID and state locations +pidfile "#{shared_dir}/pids/puma.pid" +state_path "#{shared_dir}/pids/puma.state" +activate_control_app + +on_worker_boot do + require "active_record" + ActiveRecord::Base.connection.disconnect! rescue ActiveRecord::ConnectionNotEstablished + ActiveRecord::Base.establish_connection(YAML.load_file("#{app_dir}/config/database.yml")[rails_env]) +end diff --git a/config/routes.rb b/config/routes.rb index 6440f510d04452d2f3d6a1d18c360bd7aee265ba..5d3b9eb774f9b36c11c692e35075cd7909af5aa9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -31,11 +31,14 @@ Rails.application.routes.draw do resources :learning_objects do member do post :like + post :bookmarks end end resources :institutions - resources :collections + resources :collections do + + end resources :subjects, only: [:index, :show] resources :complaints, only: [:create, :destroy] @@ -47,4 +50,9 @@ Rails.application.routes.draw do get '/search' => 'search#index', as: 'search' get '/search/fetch' => 'search#fetch', as: 'search_fetch' + get '/subject/:id' => 'welcome#subject', as: 'subject_index' + get '/collection' => 'welcome#collection' + get '/add_file' => 'welcome#add_file' + get '/signup' => 'welcome#signup' + get '/follow_collection' => 'welcome#follow_collection' end diff --git a/db/migrate/20150902192904_create_learning_objects.rb b/db/migrate/20150902192904_create_learning_objects.rb deleted file mode 100644 index 95408cf251572aeeddf761bc9eb0a46c120b510e..0000000000000000000000000000000000000000 --- a/db/migrate/20150902192904_create_learning_objects.rb +++ /dev/null @@ -1,8 +0,0 @@ -class CreateLearningObjects < ActiveRecord::Migration - def change - create_table :learning_objects do |t| - - t.timestamps null: false - end - end -end diff --git a/lib/orient_db/methods/generic_methods.rb b/lib/orient_db/methods/finder_methods.rb similarity index 94% rename from lib/orient_db/methods/generic_methods.rb rename to lib/orient_db/methods/finder_methods.rb index d858ecabda32919bf1639854e71a2839005e7950..93af468623d5dfb0fca172dd65e3d9e262c9dfc3 100644 --- a/lib/orient_db/methods/generic_methods.rb +++ b/lib/orient_db/methods/finder_methods.rb @@ -1,6 +1,6 @@ module OrientDb module Methods - module GenericMethods + module FinderMethods def get_by_rid(rid) connection.get_document(rid) diff --git a/lib/orient_db/record_duplicated_error.rb b/lib/orient_db/record_duplicated_error.rb new file mode 100644 index 0000000000000000000000000000000000000000..4e513a738e3a8fe5281c830a000ae9ecd1b3b9d3 --- /dev/null +++ b/lib/orient_db/record_duplicated_error.rb @@ -0,0 +1 @@ +class OrientDb::RecordDuplicatedError < Orientdb4r::ServerError; end \ No newline at end of file diff --git a/lib/repository/environments.rb b/lib/repository/environments.rb index 55ea9ae9aa68f66c9838c73c42728a4baecbbd71..4b6d90d31f21a931d0fcbc7101e9e863423b5b03 100644 --- a/lib/repository/environments.rb +++ b/lib/repository/environments.rb @@ -2,7 +2,6 @@ class Repository::Environments def self.create(env) - env = env environments[env] = Repository::Repository.new yield(environments[env]) if block_given? end diff --git a/portalmec.service b/portalmec.service new file mode 100644 index 0000000000000000000000000000000000000000..ed539a61d6c1a25e32427ced4775e225b33ae12c --- /dev/null +++ b/portalmec.service @@ -0,0 +1,10 @@ +[Unit] +Description=Control puma for portalmec +After=nginx.service + +[Service] +ExecStart=/portalmec/puma.sh start +ExecStop=/portalmec/puma.sh stop + +[Install] +WantedBy=multi-user.target diff --git a/puma.sh b/puma.sh new file mode 100644 index 0000000000000000000000000000000000000000..2baa709eed089d4c08061a55e8d642c616f7d587 --- /dev/null +++ b/puma.sh @@ -0,0 +1,19 @@ +#!/bin/bash +source /home/.rvm/scripts/rvm + +export PUMA_APP_DIR=/portalmec + +option="${1}" + +case ${option} in + start) + source start_puma.sh + ;; + stop) + source stop_puma.sh + ;; + *) + echo "`basename ${0}`:usage: [start] | [stop]" + exit 1 # Command to come out of the program with status 1 + ;; +esac diff --git a/shared/logs/.keep b/shared/logs/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/shared/pids/.keep b/shared/pids/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/shared/sockets/.keep b/shared/sockets/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/start_puma.sh b/start_puma.sh new file mode 100644 index 0000000000000000000000000000000000000000..056882f3d52623eefec7b98eee4a9a12beacd3d7 --- /dev/null +++ b/start_puma.sh @@ -0,0 +1,6 @@ +#!/bin/bash +source $PUMA_APP_DIR/config/env_vars.sh + +cd $PUMA_APP_DIR +#rake assets:precompile +bundle exec puma -C config/puma.rb diff --git a/stop_puma.sh b/stop_puma.sh new file mode 100644 index 0000000000000000000000000000000000000000..3d0833f24f0f24fb1dad3a601d80bfe7957a4b07 --- /dev/null +++ b/stop_puma.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +cd $PUMA_APP_DIR +pumactl -P shared/sockets/pumactl.sock stop diff --git a/vendor/assets/javascripts/bootstrap-tagsinput.js b/vendor/assets/javascripts/bootstrap-tagsinput.js new file mode 100644 index 0000000000000000000000000000000000000000..4d225fa69aa3af5473d2707071f8b30bfbcbbec3 --- /dev/null +++ b/vendor/assets/javascripts/bootstrap-tagsinput.js @@ -0,0 +1,635 @@ +(function ($) { + "use strict"; + + var defaultOptions = { + tagClass: function(item) { + return 'label label-info'; + }, + itemValue: function(item) { + return item ? item.toString() : item; + }, + itemText: function(item) { + return this.itemValue(item); + }, + itemTitle: function(item) { + return null; + }, + freeInput: true, + addOnBlur: true, + maxTags: undefined, + maxChars: undefined, + confirmKeys: [13, 44], + onTagExists: function(item, $tag) { + $tag.hide().fadeIn(); + }, + trimValue: false, + allowDuplicates: false + }; + + /** + * Constructor function + */ + function TagsInput(element, options) { + this.itemsArray = []; + + this.$element = $(element); + this.$element.hide(); + + this.isSelect = (element.tagName === 'SELECT'); + this.multiple = (this.isSelect && element.hasAttribute('multiple')); + this.objectItems = options && options.itemValue; + this.placeholderText = element.hasAttribute('placeholder') ? this.$element.attr('placeholder') : ''; + this.inputSize = Math.max(1, this.placeholderText.length); + + this.$container = $('<div class="bootstrap-tagsinput"></div>'); + this.$input = $('<input type="text" placeholder="' + this.placeholderText + '"/>').appendTo(this.$container); + + this.$element.before(this.$container); + + this.build(options); + } + + TagsInput.prototype = { + constructor: TagsInput, + + /** + * Adds the given item as a new tag. Pass true to dontPushVal to prevent + * updating the elements val() + */ + add: function(item, dontPushVal, options) { + var self = this; + + if (self.options.maxTags && self.itemsArray.length >= self.options.maxTags) + return; + + // Ignore falsey values, except false + if (item !== false && !item) + return; + + // Trim value + if (typeof item === "string" && self.options.trimValue) { + item = $.trim(item); + } + + // Throw an error when trying to add an object while the itemValue option was not set + if (typeof item === "object" && !self.objectItems) + throw("Can't add objects when itemValue option is not set"); + + // Ignore strings only containg whitespace + if (item.toString().match(/^\s*$/)) + return; + + // If SELECT but not multiple, remove current tag + if (self.isSelect && !self.multiple && self.itemsArray.length > 0) + self.remove(self.itemsArray[0]); + + if (typeof item === "string" && this.$element[0].tagName === 'INPUT') { + var items = item.split(','); + if (items.length > 1) { + for (var i = 0; i < items.length; i++) { + this.add(items[i], true); + } + + if (!dontPushVal) + self.pushVal(); + return; + } + } + + var itemValue = self.options.itemValue(item), + itemText = self.options.itemText(item), + tagClass = self.options.tagClass(item), + itemTitle = self.options.itemTitle(item); + + // Ignore items allready added + var existing = $.grep(self.itemsArray, function(item) { return self.options.itemValue(item) === itemValue; } )[0]; + if (existing && !self.options.allowDuplicates) { + // Invoke onTagExists + if (self.options.onTagExists) { + var $existingTag = $(".tag", self.$container).filter(function() { return $(this).data("item") === existing; }); + self.options.onTagExists(item, $existingTag); + } + return; + } + + // if length greater than limit + if (self.items().toString().length + item.length + 1 > self.options.maxInputLength) + return; + + // raise beforeItemAdd arg + var beforeItemAddEvent = $.Event('beforeItemAdd', { item: item, cancel: false, options: options}); + self.$element.trigger(beforeItemAddEvent); + if (beforeItemAddEvent.cancel) + return; + + // register item in internal array and map + self.itemsArray.push(item); + + // add a tag element + + var $tag = $('<span class="tag ' + htmlEncode(tagClass) + (itemTitle !== null ? ('" title="' + itemTitle) : '') + '">' + htmlEncode(itemText) + '<span data-role="remove"></span></span>'); + $tag.data('item', item); + self.findInputWrapper().before($tag); + $tag.after(' '); + + // add <option /> if item represents a value not present in one of the <select />'s options + if (self.isSelect && !$('option[value="' + encodeURIComponent(itemValue) + '"]',self.$element)[0]) { + var $option = $('<option selected>' + htmlEncode(itemText) + '</option>'); + $option.data('item', item); + $option.attr('value', itemValue); + self.$element.append($option); + } + + if (!dontPushVal) + self.pushVal(); + + // Add class when reached maxTags + if (self.options.maxTags === self.itemsArray.length || self.items().toString().length === self.options.maxInputLength) + self.$container.addClass('bootstrap-tagsinput-max'); + + self.$element.trigger($.Event('itemAdded', { item: item, options: options })); + }, + + /** + * Removes the given item. Pass true to dontPushVal to prevent updating the + * elements val() + */ + remove: function(item, dontPushVal, options) { + var self = this; + + if (self.objectItems) { + if (typeof item === "object") + item = $.grep(self.itemsArray, function(other) { return self.options.itemValue(other) == self.options.itemValue(item); } ); + else + item = $.grep(self.itemsArray, function(other) { return self.options.itemValue(other) == item; } ); + + item = item[item.length-1]; + } + + if (item) { + var beforeItemRemoveEvent = $.Event('beforeItemRemove', { item: item, cancel: false, options: options }); + self.$element.trigger(beforeItemRemoveEvent); + if (beforeItemRemoveEvent.cancel) + return; + + $('.tag', self.$container).filter(function() { return $(this).data('item') === item; }).remove(); + $('option', self.$element).filter(function() { return $(this).data('item') === item; }).remove(); + if($.inArray(item, self.itemsArray) !== -1) + self.itemsArray.splice($.inArray(item, self.itemsArray), 1); + } + + if (!dontPushVal) + self.pushVal(); + + // Remove class when reached maxTags + if (self.options.maxTags > self.itemsArray.length) + self.$container.removeClass('bootstrap-tagsinput-max'); + + self.$element.trigger($.Event('itemRemoved', { item: item, options: options })); + }, + + /** + * Removes all items + */ + removeAll: function() { + var self = this; + + $('.tag', self.$container).remove(); + $('option', self.$element).remove(); + + while(self.itemsArray.length > 0) + self.itemsArray.pop(); + + self.pushVal(); + }, + + /** + * Refreshes the tags so they match the text/value of their corresponding + * item. + */ + refresh: function() { + var self = this; + $('.tag', self.$container).each(function() { + var $tag = $(this), + item = $tag.data('item'), + itemValue = self.options.itemValue(item), + itemText = self.options.itemText(item), + tagClass = self.options.tagClass(item); + + // Update tag's class and inner text + $tag.attr('class', null); + $tag.addClass('tag ' + htmlEncode(tagClass)); + $tag.contents().filter(function() { + return this.nodeType == 3; + })[0].nodeValue = htmlEncode(itemText); + + if (self.isSelect) { + var option = $('option', self.$element).filter(function() { return $(this).data('item') === item; }); + option.attr('value', itemValue); + } + }); + }, + + /** + * Returns the items added as tags + */ + items: function() { + return this.itemsArray; + }, + + /** + * Assembly value by retrieving the value of each item, and set it on the + * element. + */ + pushVal: function() { + var self = this, + val = $.map(self.items(), function(item) { + return self.options.itemValue(item).toString(); + }); + + self.$element.val(val, true).trigger('change'); + }, + + /** + * Initializes the tags input behaviour on the element + */ + build: function(options) { + var self = this; + + self.options = $.extend({}, defaultOptions, options); + // When itemValue is set, freeInput should always be false + if (self.objectItems) + self.options.freeInput = false; + + makeOptionItemFunction(self.options, 'itemValue'); + makeOptionItemFunction(self.options, 'itemText'); + makeOptionFunction(self.options, 'tagClass'); + + // Typeahead Bootstrap version 2.3.2 + if (self.options.typeahead) { + var typeahead = self.options.typeahead || {}; + + makeOptionFunction(typeahead, 'source'); + + self.$input.typeahead($.extend({}, typeahead, { + source: function (query, process) { + function processItems(items) { + var texts = []; + + for (var i = 0; i < items.length; i++) { + var text = self.options.itemText(items[i]); + map[text] = items[i]; + texts.push(text); + } + process(texts); + } + + this.map = {}; + var map = this.map, + data = typeahead.source(query); + + if ($.isFunction(data.success)) { + // support for Angular callbacks + data.success(processItems); + } else if ($.isFunction(data.then)) { + // support for Angular promises + data.then(processItems); + } else { + // support for functions and jquery promises + $.when(data) + .then(processItems); + } + }, + updater: function (text) { + self.add(this.map[text]); + return this.map[text]; + }, + matcher: function (text) { + return (text.toLowerCase().indexOf(this.query.trim().toLowerCase()) !== -1); + }, + sorter: function (texts) { + return texts.sort(); + }, + highlighter: function (text) { + var regex = new RegExp( '(' + this.query + ')', 'gi' ); + return text.replace( regex, "<strong>$1</strong>" ); + } + })); + } + + // typeahead.js + if (self.options.typeaheadjs) { + var typeaheadConfig = null; + var typeaheadDatasets = {}; + + // Determine if main configurations were passed or simply a dataset + var typeaheadjs = self.options.typeaheadjs; + if ($.isArray(typeaheadjs)) { + typeaheadConfig = typeaheadjs[0]; + typeaheadDatasets = typeaheadjs[1]; + } else { + typeaheadDatasets = typeaheadjs; + } + + self.$input.typeahead(typeaheadConfig, typeaheadDatasets).on('typeahead:selected', $.proxy(function (obj, datum) { + if (typeaheadDatasets.valueKey) + self.add(datum[typeaheadDatasets.valueKey]); + else + self.add(datum); + self.$input.typeahead('val', ''); + }, self)); + } + + self.$container.on('click', $.proxy(function(event) { + if (! self.$element.attr('disabled')) { + self.$input.removeAttr('disabled'); + } + self.$input.focus(); + }, self)); + + if (self.options.addOnBlur && self.options.freeInput) { + self.$input.on('focusout', $.proxy(function(event) { + // HACK: only process on focusout when no typeahead opened, to + // avoid adding the typeahead text as tag + if ($('.typeahead, .twitter-typeahead', self.$container).length === 0) { + self.add(self.$input.val()); + self.$input.val(''); + } + }, self)); + } + + + self.$container.on('keydown', 'input', $.proxy(function(event) { + var $input = $(event.target), + $inputWrapper = self.findInputWrapper(); + + if (self.$element.attr('disabled')) { + self.$input.attr('disabled', 'disabled'); + return; + } + + switch (event.which) { + // BACKSPACE + case 8: + if (doGetCaretPosition($input[0]) === 0) { + var prev = $inputWrapper.prev(); + if (prev) { + self.remove(prev.data('item')); + } + } + break; + + // DELETE + case 46: + if (doGetCaretPosition($input[0]) === 0) { + var next = $inputWrapper.next(); + if (next) { + self.remove(next.data('item')); + } + } + break; + + // LEFT ARROW + case 37: + // Try to move the input before the previous tag + var $prevTag = $inputWrapper.prev(); + if ($input.val().length === 0 && $prevTag[0]) { + $prevTag.before($inputWrapper); + $input.focus(); + } + break; + // RIGHT ARROW + case 39: + // Try to move the input after the next tag + var $nextTag = $inputWrapper.next(); + if ($input.val().length === 0 && $nextTag[0]) { + $nextTag.after($inputWrapper); + $input.focus(); + } + break; + default: + // ignore + } + + // Reset internal input's size + var textLength = $input.val().length, + wordSpace = Math.ceil(textLength / 5), + size = textLength + wordSpace + 1; + $input.attr('size', Math.max(this.inputSize, $input.val().length)); + }, self)); + + self.$container.on('keypress', 'input', $.proxy(function(event) { + var $input = $(event.target); + + if (self.$element.attr('disabled')) { + self.$input.attr('disabled', 'disabled'); + return; + } + + var text = $input.val(), + maxLengthReached = self.options.maxChars && text.length >= self.options.maxChars; + if (self.options.freeInput && (keyCombinationInList(event, self.options.confirmKeys) || maxLengthReached)) { + self.add(maxLengthReached ? text.substr(0, self.options.maxChars) : text); + $input.val(''); + event.preventDefault(); + } + + // Reset internal input's size + var textLength = $input.val().length, + wordSpace = Math.ceil(textLength / 5), + size = textLength + wordSpace + 1; + $input.attr('size', Math.max(this.inputSize, $input.val().length)); + }, self)); + + // Remove icon clicked + self.$container.on('click', '[data-role=remove]', $.proxy(function(event) { + if (self.$element.attr('disabled')) { + return; + } + self.remove($(event.target).closest('.tag').data('item')); + }, self)); + + // Only add existing value as tags when using strings as tags + if (self.options.itemValue === defaultOptions.itemValue) { + if (self.$element[0].tagName === 'INPUT') { + self.add(self.$element.val()); + } else { + $('option', self.$element).each(function() { + self.add($(this).attr('value'), true); + }); + } + } + }, + + /** + * Removes all tagsinput behaviour and unregsiter all event handlers + */ + destroy: function() { + var self = this; + + // Unbind events + self.$container.off('keypress', 'input'); + self.$container.off('click', '[role=remove]'); + + self.$container.remove(); + self.$element.removeData('tagsinput'); + self.$element.show(); + }, + + /** + * Sets focus on the tagsinput + */ + focus: function() { + this.$input.focus(); + }, + + /** + * Returns the internal input element + */ + input: function() { + return this.$input; + }, + + /** + * Returns the element which is wrapped around the internal input. This + * is normally the $container, but typeahead.js moves the $input element. + */ + findInputWrapper: function() { + var elt = this.$input[0], + container = this.$container[0]; + while(elt && elt.parentNode !== container) + elt = elt.parentNode; + + return $(elt); + } + }; + + /** + * Register JQuery plugin + */ + $.fn.tagsinput = function(arg1, arg2, arg3) { + var results = []; + + this.each(function() { + var tagsinput = $(this).data('tagsinput'); + // Initialize a new tags input + if (!tagsinput) { + tagsinput = new TagsInput(this, arg1); + $(this).data('tagsinput', tagsinput); + results.push(tagsinput); + + if (this.tagName === 'SELECT') { + $('option', $(this)).attr('selected', 'selected'); + } + + // Init tags from $(this).val() + $(this).val($(this).val()); + } else if (!arg1 && !arg2) { + // tagsinput already exists + // no function, trying to init + results.push(tagsinput); + } else if(tagsinput[arg1] !== undefined) { + // Invoke function on existing tags input + if(tagsinput[arg1].length === 3 && arg3 !== undefined){ + var retVal = tagsinput[arg1](arg2, null, arg3); + }else{ + var retVal = tagsinput[arg1](arg2); + } + if (retVal !== undefined) + results.push(retVal); + } + }); + + if ( typeof arg1 == 'string') { + // Return the results from the invoked function calls + return results.length > 1 ? results : results[0]; + } else { + return results; + } + }; + + $.fn.tagsinput.Constructor = TagsInput; + + /** + * Most options support both a string or number as well as a function as + * option value. This function makes sure that the option with the given + * key in the given options is wrapped in a function + */ + function makeOptionItemFunction(options, key) { + if (typeof options[key] !== 'function') { + var propertyName = options[key]; + options[key] = function(item) { return item[propertyName]; }; + } + } + function makeOptionFunction(options, key) { + if (typeof options[key] !== 'function') { + var value = options[key]; + options[key] = function() { return value; }; + } + } + /** + * HtmlEncodes the given value + */ + var htmlEncodeContainer = $('<div />'); + function htmlEncode(value) { + if (value) { + return htmlEncodeContainer.text(value).html(); + } else { + return ''; + } + } + + /** + * Returns the position of the caret in the given input field + * http://flightschool.acylt.com/devnotes/caret-position-woes/ + */ + function doGetCaretPosition(oField) { + var iCaretPos = 0; + if (document.selection) { + oField.focus (); + var oSel = document.selection.createRange(); + oSel.moveStart ('character', -oField.value.length); + iCaretPos = oSel.text.length; + } else if (oField.selectionStart || oField.selectionStart == '0') { + iCaretPos = oField.selectionStart; + } + return (iCaretPos); + } + + /** + * Returns boolean indicates whether user has pressed an expected key combination. + * @param object keyPressEvent: JavaScript event object, refer + * http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html + * @param object lookupList: expected key combinations, as in: + * [13, {which: 188, shiftKey: true}] + */ + function keyCombinationInList(keyPressEvent, lookupList) { + var found = false; + $.each(lookupList, function (index, keyCombination) { + if (typeof (keyCombination) === 'number' && keyPressEvent.which === keyCombination) { + found = true; + return false; + } + + if (keyPressEvent.which === keyCombination.which) { + var alt = !keyCombination.hasOwnProperty('altKey') || keyPressEvent.altKey === keyCombination.altKey, + shift = !keyCombination.hasOwnProperty('shiftKey') || keyPressEvent.shiftKey === keyCombination.shiftKey, + ctrl = !keyCombination.hasOwnProperty('ctrlKey') || keyPressEvent.ctrlKey === keyCombination.ctrlKey; + if (alt && shift && ctrl) { + found = true; + return false; + } + } + }); + + return found; + } + + /** + * Initialize tagsinput behaviour on inputs and selects which have + * data-role=tagsinput + */ + $(function() { + $("input[data-role=tagsinput], select[multiple][data-role=tagsinput]").tagsinput(); + }); +})(window.jQuery); diff --git a/vendor/assets/stylesheets/bootstrap-tagsinput.css b/vendor/assets/stylesheets/bootstrap-tagsinput.css new file mode 100644 index 0000000000000000000000000000000000000000..b31f01c773a377117c8f4e88f7a390a67d15dc72 --- /dev/null +++ b/vendor/assets/stylesheets/bootstrap-tagsinput.css @@ -0,0 +1,55 @@ +.bootstrap-tagsinput { + background-color: #fff; + border: 1px solid #ccc; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + display: inline-block; + padding: 4px 6px; + color: #555; + vertical-align: middle; + border-radius: 4px; + max-width: 100%; + line-height: 22px; + cursor: text; +} +.bootstrap-tagsinput input { + border: none; + box-shadow: none; + outline: none; + background-color: transparent; + padding: 0 6px; + margin: 0; + width: auto; + max-width: inherit; +} +.bootstrap-tagsinput.form-control input::-moz-placeholder { + color: #777; + opacity: 1; +} +.bootstrap-tagsinput.form-control input:-ms-input-placeholder { + color: #777; +} +.bootstrap-tagsinput.form-control input::-webkit-input-placeholder { + color: #777; +} +.bootstrap-tagsinput input:focus { + border: none; + box-shadow: none; +} +.bootstrap-tagsinput .tag { + margin-right: 2px; + color: white; +} +.bootstrap-tagsinput .tag [data-role="remove"] { + margin-left: 8px; + cursor: pointer; +} +.bootstrap-tagsinput .tag [data-role="remove"]:after { + content: "x"; + padding: 0px 2px; +} +.bootstrap-tagsinput .tag [data-role="remove"]:hover { + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +} +.bootstrap-tagsinput .tag [data-role="remove"]:hover:active { + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} diff --git a/app/assets/stylesheets/application/spinners.css b/vendor/assets/stylesheets/spinners.css similarity index 100% rename from app/assets/stylesheets/application/spinners.css rename to vendor/assets/stylesheets/spinners.css