├── .dockerignore ├── .gitignore ├── .rspec ├── .ruby-version ├── Dockerfile.glossa ├── Dockerfile.glossa-base ├── Dockerfile.glossa-data ├── Gemfile ├── Gemfile.lock ├── Guardfile ├── MIT-LICENSE ├── README.md ├── README.rails ├── README.rdoc ├── Rakefile ├── app ├── assets │ ├── images │ │ ├── clarin.png │ │ ├── rails.png │ │ └── rglossa │ │ │ ├── .gitkeep │ │ │ ├── .keep │ │ │ └── speech │ │ │ ├── _6.6-'T'_ligo.skev.graa.jpg │ │ │ ├── jplayer.blue.monday.jpg │ │ │ ├── jplayer.blue.monday.video.play.png │ │ │ ├── mm_20_black.png │ │ │ ├── mm_20_blue.png │ │ │ ├── mm_20_brown.png │ │ │ ├── mm_20_green.png │ │ │ ├── mm_20_orange.png │ │ │ ├── mm_20_purple.png │ │ │ ├── mm_20_red.png │ │ │ ├── mm_20_shadow.png │ │ │ ├── mm_20_white.png │ │ │ ├── mm_20_yellow.png │ │ │ ├── play-pause.png │ │ │ ├── red_dot.png │ │ │ ├── ui-bg_flat_75_ffffff_40x100.png │ │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ │ ├── ui-bg_glass_75_dadada_1x400.png │ │ │ ├── ui-bg_glass_75_e6e6e6_1x400.png │ │ │ ├── ui-bg_highlight-soft_75_cccccc_1x100.png │ │ │ ├── waveform.png │ │ │ ├── zoom-in.png │ │ │ └── zoom-out.png │ ├── javascripts │ │ ├── application.js │ │ └── rglossa │ │ │ ├── .gitkeep │ │ │ ├── .keep │ │ │ ├── application.js │ │ │ ├── bundle.js │ │ │ ├── components │ │ │ ├── app.jsx.coffee │ │ │ ├── centre │ │ │ │ ├── main_area.jsx.coffee │ │ │ │ ├── main_area_bottom.jsx.coffee │ │ │ │ ├── main_area_top.jsx.coffee │ │ │ │ ├── results │ │ │ │ │ ├── cwb_results_table.jsx.coffee │ │ │ │ │ ├── geo_distribution_map.js │ │ │ │ │ ├── geo_distribution_map_window.jsx.coffee │ │ │ │ │ ├── marker_picker.jsx.coffee │ │ │ │ │ ├── num_hits.jsx.coffee │ │ │ │ │ ├── results_main.jsx.coffee │ │ │ │ │ ├── results_paginator.jsx.coffee │ │ │ │ │ ├── results_toolbar.jsx.coffee │ │ │ │ │ └── results_top.jsx.coffee │ │ │ │ ├── search_inputs │ │ │ │ │ ├── cwb_cqp_query_input.jsx.coffee │ │ │ │ │ ├── cwb_multiword_input.jsx.coffee │ │ │ │ │ ├── cwb_multiword_menu.jsx.coffee │ │ │ │ │ ├── cwb_multiword_term.jsx.coffee │ │ │ │ │ ├── cwb_search_inputs.jsx.coffee │ │ │ │ │ ├── cwb_simple_input.jsx.coffee │ │ │ │ │ └── language_select.jsx.coffee │ │ │ │ └── start │ │ │ │ │ ├── corpus_info.jsx.coffee │ │ │ │ │ └── start_main.jsx.coffee │ │ │ ├── left │ │ │ │ ├── metadata_categories.jsx.coffee │ │ │ │ └── metadata_select.jsx.coffee │ │ │ └── top │ │ │ │ └── navbar.js.jsx.coffee │ │ │ ├── entry.js │ │ │ ├── main.jsx.coffee │ │ │ ├── models │ │ │ └── corpus.coffee │ │ │ ├── speech │ │ │ ├── application.js │ │ │ ├── components │ │ │ │ └── centre │ │ │ │ │ ├── results │ │ │ │ │ ├── jplayer.jsx.coffee │ │ │ │ │ ├── speech_cwb_results_table.jsx.coffee │ │ │ │ │ └── wfplayer.jsx.coffee │ │ │ │ │ └── search_inputs │ │ │ │ │ └── speech_cwb_search_inputs.jsx.coffee │ │ │ ├── jquery.colorpicker.js │ │ │ ├── jquery.jplayer.min.js │ │ │ └── wfplayer.js │ │ │ ├── statechart.coffee │ │ │ ├── store.coffee │ │ │ ├── translations │ │ │ ├── en.coffee │ │ │ ├── nb.coffee │ │ │ └── translations.coffee │ │ │ └── utils.coffee │ └── stylesheets │ │ ├── application.css │ │ └── rglossa │ │ ├── .keep │ │ ├── application.css │ │ ├── bootstrap_overrides.css.scss │ │ ├── geo-distribution.css.scss │ │ ├── home.css.scss │ │ └── speech │ │ ├── application.css │ │ ├── jplayer.blue.monday.css │ │ ├── jquery-ui.css │ │ ├── jquery.colorpicker.css │ │ ├── media.scss │ │ ├── wfplayer-flashblock.css │ │ └── wfplayer.css ├── controllers │ ├── .keep │ ├── application_controller.rb │ ├── front_controller.rb │ └── rglossa │ │ ├── application_controller.rb │ │ ├── corpora_controller.rb │ │ ├── home_controller.rb │ │ ├── metadata_categories_controller.rb │ │ ├── metadata_values_controller.rb │ │ ├── r │ │ └── search_engines │ │ │ └── cwb_controller.rb │ │ ├── saml_controller.rb │ │ ├── search_engines │ │ └── cwb_searches_controller.rb │ │ ├── searches_controller.rb │ │ └── speech │ │ ├── search_engines │ │ └── speech_cwb_searches_controller.rb │ │ └── waveform_player_controller.rb ├── helpers │ ├── .keep │ ├── application_helper.rb │ ├── front_helper.rb │ └── rglossa │ │ ├── application_helper.rb │ │ ├── corpora_helper.rb │ │ ├── home_helper.rb │ │ ├── metadata_categories_helper.rb │ │ ├── metadata_values_helper.rb │ │ ├── search_engines │ │ └── cwb_searches_helper.rb │ │ └── searches_helper.rb ├── mailers │ ├── .gitkeep │ └── .keep ├── models │ ├── .gitkeep │ ├── .keep │ ├── corpus.rb │ └── rglossa │ │ ├── access_permission.rb │ │ ├── account.rb │ │ ├── corpus_text.rb │ │ ├── deleted_hit.rb │ │ ├── media_file.rb │ │ ├── metadata_category.rb │ │ ├── metadata_value.rb │ │ ├── metadata_values │ │ ├── boolean.rb │ │ ├── integer.rb │ │ └── text.rb │ │ ├── search.rb │ │ ├── search_engines │ │ └── cwb_search.rb │ │ ├── search_types.rb │ │ ├── speech │ │ ├── search_engines │ │ │ └── speech_cwb_search.rb │ │ ├── speaker.rb │ │ └── waveform_player.rb │ │ └── user.rb └── views │ ├── .keep │ ├── front │ └── index.html.erb │ ├── layouts │ └── application.html.erb │ └── rglossa │ ├── corpora │ ├── cimdi.xml.erb │ └── index.html.erb │ ├── home │ └── index.html.erb │ ├── searches │ ├── create.html.erb │ └── destroy.html.erb │ └── speech │ └── waveform_player │ └── show.html.erb ├── app_template.rb ├── bin └── rails ├── bower.json ├── build_docker_image.sh ├── config.ru ├── config ├── application.rb ├── boot.rb ├── cwb.example ├── database.yml ├── environment.rb ├── environments │ ├── development.rb │ ├── production.rb │ └── test.rb ├── i18n-js.yml ├── initializers │ ├── backtrace_silencers.rb │ ├── devise.rb │ ├── inflections.rb │ ├── mime_types.rb │ ├── rglossa.rb │ ├── secret_token.rb │ ├── session_store.rb │ └── wrap_parameters.rb ├── locales │ ├── devise.en.yml │ ├── en.yml │ └── nb.yml ├── routes.rb ├── taggers │ ├── elrc.yml │ ├── elrc_am.json │ ├── obt_bm.json │ ├── obt_bm_lbk.json │ ├── oromo.yml │ └── scandiasyn.yml ├── trinidad.yml └── waveforms.json ├── db ├── migrate │ ├── 20130904181612_create_rglossa_corpora.rglossa.rb │ ├── 20130904181613_create_rglossa_metadata_categories.rglossa.rb │ ├── 20130904181614_create_rglossa_searches.rglossa.rb │ ├── 20130904181615_create_rglossa_corpus_texts.rglossa.rb │ ├── 20130904181616_create_rglossa_metadata_values.rglossa.rb │ ├── 20130904181617_create_rglossa_deleted_hits.rglossa.rb │ ├── 20130904181618_add_join_table_for_corpus_text_and_metadata_value.rglossa.rb │ ├── 20130904181619_devise_create_rglossa_users.rglossa.rb │ ├── 20130904181620_add_corpus_id_to_corpus_text.rglossa.rb │ ├── 20130904181621_add_encoding_to_corpus.rglossa.rb │ ├── 20130904181622_add_max_hits_to_search.rglossa.rb │ ├── 20130904181623_remove_default_max_hits_from_corpus.rglossa.rb │ ├── 20130904181624_add_config_to_corpus.rglossa.rb │ ├── 20130908211800_add_logo_to_corpus.rglossa.rb │ ├── 20130908223643_add_search_engine_to_corpus.rglossa.rb │ ├── 20131014230038_add_index_on_metadata_category_id.rglossa.rb │ ├── 20131014230039_set_num_hits_to_zero.rglossa.rb │ ├── 20131015205819_add_corpus_part_counts_to_search.rglossa.rb │ ├── 20140226133446_add_type_to_corpus_text.rglossa.rb │ ├── 20140715154830_add_corpus_short_name_to_search.rglossa.rb │ ├── 20140916203917_add_positions_to_corpus_text.rglossa.rb │ ├── 20140916203918_create_rglossa_media_files.rglossa.rb │ ├── 20141127013945_add_cimdi_to_corpora.rglossa.rb │ ├── 20150414151848_create_access_permissions.rb │ └── 20150415123131_add_admin_to_users.rb ├── schema.rb └── seeds.rb ├── doc └── README_FOR_APP ├── lib ├── assets │ ├── .gitkeep │ ├── cljs │ │ └── cglossa │ │ │ ├── app.cljs │ │ │ ├── core.cljs │ │ │ ├── left.cljs │ │ │ ├── react_adapters │ │ │ ├── bootstrap.clj │ │ │ └── bootstrap.cljs │ │ │ ├── result_views │ │ │ ├── cwb │ │ │ │ ├── core.cljs │ │ │ │ ├── shared.cljs │ │ │ │ ├── speech.cljs │ │ │ │ └── written.cljs │ │ │ └── fcs │ │ │ │ └── core.cljs │ │ │ ├── results.cljs │ │ │ ├── search_engines.cljs │ │ │ ├── search_views │ │ │ ├── cwb │ │ │ │ ├── core.cljs │ │ │ │ ├── extended.cljs │ │ │ │ └── shared.cljs │ │ │ ├── fcs │ │ │ │ └── core.cljs │ │ │ └── shared.cljs │ │ │ ├── select2.cljs │ │ │ ├── shared.cljs │ │ │ └── start.cljs │ └── stylesheets │ │ ├── bootstrap-3.3.4 │ │ ├── bootstrap-theme.min.css │ │ ├── bootstrap.css │ │ └── bootstrap.min.css │ │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ │ ├── simple-sidebar.css │ │ ├── style.css │ │ ├── style.css.map │ │ └── style.scss ├── commons-configuration-1.10.jar ├── copy_to_app │ └── application.js ├── orientdb.rb ├── orientdb │ ├── blueprints-core-2.6.0.jar │ ├── concurrentlinkedhashmap-lru-1.4.1.jar │ ├── jna-4.0.0.jar │ ├── jna-platform-4.0.0.jar │ ├── orientdb-client-2.1.0.jar │ ├── orientdb-core-2.1.0.jar │ ├── orientdb-enterprise-2.1.0.jar │ └── orientdb-graphdb-2.1.0.jar ├── rglossa.rb ├── rglossa │ ├── engine.rb │ ├── incompatible_metadata_error.rb │ ├── query_error.rb │ └── version.rb ├── tasks │ ├── .gitkeep │ ├── assets.rake │ ├── cwb_test_corpus.rake │ ├── rglossa_line_keys.thor │ ├── rglossa_metadata.thor │ ├── rglossa_metadata_old_glossa.thor │ ├── rglossa_tasks.rake │ └── thor_utils.rb └── waveforms │ ├── genwaveform.py │ ├── install_snack.sh │ └── snack.patch ├── log └── .gitkeep ├── package.json ├── project.clj ├── public ├── 404.html ├── 422.html ├── 500.html ├── favicon.ico ├── img │ ├── book-clip-art-3.png │ ├── tekstlab.gif │ └── waveform.png ├── robots.txt ├── swf │ ├── Jplayer.swf │ ├── soundmanager2.swf │ └── soundmanager2_flash9.swf └── tekstlab.png ├── rglossa.gemspec ├── script ├── build_ubuntu_essential.sh ├── docker_build_conf.sh ├── docker_build_deps.sh ├── docker_glossa_postinst.sh ├── docker_install_deps.sh ├── get_saml_conf.rb ├── glossa_addr.sh ├── glossa_start.sh ├── glossa_stop.sh ├── make_saml_metadata.py └── rails ├── test ├── dummy │ ├── README.rdoc │ ├── Rakefile │ ├── app │ │ ├── assets │ │ │ ├── javascripts │ │ │ │ └── application.js │ │ │ └── stylesheets │ │ │ │ └── application.css │ │ ├── controllers │ │ │ └── application_controller.rb │ │ ├── helpers │ │ │ └── application_helper.rb │ │ ├── mailers │ │ │ └── .gitkeep │ │ ├── models │ │ │ └── .gitkeep │ │ └── views │ │ │ └── layouts │ │ │ └── application.html.erb │ ├── config.ru │ ├── config │ │ ├── application.rb │ │ ├── boot.rb │ │ ├── environment.rb │ │ ├── environments │ │ │ ├── development.rb │ │ │ ├── production.rb │ │ │ └── test.rb │ │ ├── initializers │ │ │ ├── backtrace_silencers.rb │ │ │ ├── devise.rb │ │ │ ├── inflections.rb │ │ │ ├── konacha.rb │ │ │ ├── mime_types.rb │ │ │ ├── secret_token.rb │ │ │ ├── session_store.rb │ │ │ └── wrap_parameters.rb │ │ ├── locales │ │ │ ├── devise.en.yml │ │ │ └── en.yml │ │ └── routes.rb │ ├── db │ │ ├── migrate │ │ │ ├── 20130416154321_create_rglossa_corpora.rglossa.rb │ │ │ ├── 20130416154322_create_rglossa_metadata_categories.rglossa.rb │ │ │ ├── 20130416154323_create_rglossa_searches.rglossa.rb │ │ │ ├── 20130416154324_create_rglossa_corpus_texts.rglossa.rb │ │ │ ├── 20130416154325_create_rglossa_metadata_values.rglossa.rb │ │ │ ├── 20130416154326_create_rglossa_deleted_hits.rglossa.rb │ │ │ ├── 20130416154327_add_join_table_for_corpus_text_and_metadata_value.rglossa.rb │ │ │ ├── 20130416154328_devise_create_rglossa_users.rglossa.rb │ │ │ ├── 20130423174716_add_corpus_id_to_corpus_text.rglossa.rb │ │ │ ├── 20130424025517_add_encoding_to_corpus.rglossa.rb │ │ │ ├── 20130730095637_add_max_hits_to_search.rglossa.rb │ │ │ ├── 20130802121402_remove_default_max_hits_from_corpus.rglossa.rb │ │ │ └── 20130803193149_add_config_to_corpus.rglossa.rb │ │ ├── schema.rb │ │ └── seeds.rb │ ├── lib │ │ └── assets │ │ │ └── .gitkeep │ ├── log │ │ └── .gitkeep │ ├── public │ │ ├── 404.html │ │ ├── 422.html │ │ ├── 500.html │ │ └── favicon.ico │ ├── script │ │ └── rails │ └── test │ │ ├── fixtures │ │ └── rglossa │ │ │ └── users.yml │ │ └── unit │ │ └── rglossa │ │ └── user_test.rb ├── fixtures │ └── .gitkeep ├── functional │ ├── .gitkeep │ └── front_controller_test.rb ├── integration │ ├── .gitkeep │ └── navigation_test.rb ├── performance │ └── browsing_test.rb ├── rglossa_test.rb ├── test_helper.rb └── unit │ ├── .gitkeep │ └── helpers │ └── front_helper_test.rb ├── vendor ├── assets │ ├── chinese-ime │ │ ├── caret.js │ │ ├── ime.scss │ │ ├── jQuery.chineseIME.js │ │ ├── jquery-migrate-1.2.1.js │ │ ├── license.txt │ │ └── trad_chars.js │ ├── flash │ │ └── rglossa │ │ │ └── speech │ │ │ └── Jplayer.swf │ ├── images │ │ ├── bootstrap-2.3.1 │ │ │ ├── glyphicons-halflings-white.png │ │ │ └── glyphicons-halflings.png │ │ ├── font │ │ │ ├── FontAwesome.otf │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.svg │ │ │ ├── fontawesome-webfont.ttf │ │ │ └── fontawesome-webfont.woff │ │ ├── rglossa │ │ │ ├── spinner-large.gif │ │ │ └── spinner-small.gif │ │ ├── select2-spinner.gif │ │ ├── select2.png │ │ └── select2x2.png │ ├── javascripts │ │ ├── .gitkeep │ │ ├── bootstrap-2.3.1 │ │ │ └── bootstrap.js │ │ ├── bootstrap-tags.coffee │ │ ├── dialog.jsx │ │ ├── es5-sham.min.js │ │ ├── es5-shim.min.js │ │ ├── filterable.js │ │ ├── jed.js │ │ ├── jquery-ui.min.js │ │ ├── jquery.spin.js │ │ ├── opentip-jquery-excanvas.min.js │ │ ├── rglossa │ │ │ └── speech │ │ │ │ └── soundmanager2-nodebug-jsmin.js │ │ ├── select2.js │ │ ├── select2.min.js │ │ └── spin.min.js │ └── stylesheets │ │ ├── .gitkeep │ │ ├── bootstrap-2.3.1 │ │ └── bootstrap.css │ │ ├── bootstrap-tags.css │ │ ├── font-awesome.min.css │ │ ├── opentip.css │ │ ├── select2.css │ │ └── select2.min.css └── plugins │ └── .gitkeep └── webpack.config.js /.dockerignore: -------------------------------------------------------------------------------- 1 | fig.yml 2 | .git 3 | .gitignore 4 | log 5 | tmp 6 | *.sublime-project 7 | *.sublime-workspace 8 | .idea 9 | public/media 10 | public/tmp_waveforms 11 | .bundle 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile ~/.gitignore_global 6 | 7 | # Ignore bundler config 8 | /.bundle 9 | 10 | # Ignore the default SQLite database. 11 | /db/*.sqlite3 12 | 13 | # Ignore all logfiles and tempfiles. 14 | /log/*.log 15 | /tmp 16 | 17 | # Ignore an optional file that can be used to set local Ubuntu and gem mirrors. 18 | /script/set_build_mirrors.sh 19 | 20 | pkg/ 21 | test/dummy/db/*.sqlite3 22 | test/dummy/db/*.sqlite3-journal 23 | test/dummy/log/*.log 24 | test/dummy/tmp/ 25 | test/dummy/.sass-cache 26 | test/dummy/config/database.yml 27 | node_modules 28 | 29 | # Ignore precompiled assets 30 | public/assets/ 31 | 32 | # Ignore generated temporary waveforms 33 | public/tmp_waveforms/ 34 | 35 | # Ignore installation-specific media files 36 | public/media/ 37 | 38 | /.lein-* 39 | figwheel_server.log 40 | bower_components 41 | 42 | # Ignore JavaScript files generated from ClojureScript 43 | /lib/assets/javascripts/ 44 | /target/ 45 | .nrepl-port 46 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | jruby-1.7.19 2 | -------------------------------------------------------------------------------- /Dockerfile.glossa: -------------------------------------------------------------------------------- 1 | FROM textlab/glossa-base 2 | MAINTAINER Anders Nøklestad , Michał Kosek 3 | 4 | # Copy the application code to the container and fix links/permissions 5 | ADD . /glossa/ 6 | RUN script/docker_glossa_postinst.sh 7 | 8 | # Make thin reachable to other containers 9 | EXPOSE 3000 10 | 11 | # Run the application with an SQLite database 12 | USER glossa 13 | ENV DATABASE_URL sqlite3:////corpora/glossa.sqlite3 14 | CMD rake db:migrate && exec rails server -p 3000 15 | -------------------------------------------------------------------------------- /Dockerfile.glossa-base: -------------------------------------------------------------------------------- 1 | # Base image (https://registry.hub.docker.com/_/ubuntu/) 2 | FROM textlab/ubuntu-essential 3 | MAINTAINER Anders Nøklestad , Michał Kosek 4 | 5 | WORKDIR /glossa 6 | ADD script/ /glossa/script/ 7 | RUN script/docker_install_deps.sh 8 | 9 | ADD Gemfile /glossa/ 10 | ADD Gemfile.lock /glossa/ 11 | ADD config/waveforms.json /glossa/config/waveforms.json 12 | RUN script/docker_build_deps.sh 13 | -------------------------------------------------------------------------------- /Dockerfile.glossa-data: -------------------------------------------------------------------------------- 1 | FROM busybox 2 | MAINTAINER Michał Kosek 3 | 4 | RUN adduser -Du 61054 glossa && mkdir /corpora && chown glossa /corpora 5 | VOLUME /corpora 6 | CMD ["echo", "OK"] 7 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | ruby '1.9.3', engine: 'jruby', engine_version: '1.7.19' 4 | #ruby=jruby-1.7.19 5 | 6 | gem 'rails', '3.2.19' 7 | 8 | # Bundle edge Rails instead: 9 | # gem 'rails', :git => 'git://github.com/rails/rails.git' 10 | 11 | gem 'activerecord-jdbc-adapter', platform: :jruby 12 | gem 'sqlite3', :platform => :ruby 13 | gem 'jdbc-sqlite3', :platform => :jruby 14 | gem 'mysql2', :platform => :ruby 15 | gem 'jdbc-mysql', platform: :jruby 16 | gem 'react-rails' 17 | gem 'therubyracer', :platform => :ruby 18 | gem 'therubyrhino', :platform => :jruby 19 | 20 | 21 | # Gems used only for assets and not required 22 | # in production environments by default. 23 | group :assets do 24 | gem 'sass-rails', '~> 3.2.5' 25 | gem 'coffee-rails', '~> 3.2.2' 26 | 27 | # See https://github.com/sstephenson/execjs#readme for more supported runtimes 28 | # gem 'therubyracer', :platforms => :ruby 29 | 30 | gem 'uglifier', '>= 1.2.7' 31 | end 32 | 33 | gem 'jquery-rails' 34 | 35 | # To use ActiveModel has_secure_password 36 | # gem 'bcrypt-ruby', '~> 3.0.0' 37 | 38 | # To use Jbuilder templates for JSON 39 | # gem 'jbuilder' 40 | 41 | # Use unicorn as the app server 42 | # gem 'unicorn' 43 | 44 | # Deploy with Capistrano 45 | # gem 'capistrano' 46 | 47 | # To use debugger 48 | # gem 'debugger' 49 | 50 | gem "rglossa-fcs", :github => 'textlab/rglossa-fcs' 51 | #gem "rglossa-r", :github => 'textlab/rglossa-r' 52 | gem 'nokogiri', '= 1.6.1' 53 | gem 'devise', '~> 2.2.3' 54 | gem 'cancan' 55 | 56 | gem 'oj', :platform => :ruby # more efficient parsing and generation of JSON 57 | gem 'json', :platform => :jruby 58 | gem 'turbo-sprockets-rails3' # faster precompilation of assets 59 | gem 'globalize', '~> 3.0.0' 60 | gem 'i18n-js' 61 | gem 'fastimage' 62 | gem 'headless' 63 | gem 'daemon_controller' 64 | gem 'rubyzip' 65 | gem 'ruby-saml' 66 | gem "rserve-client", "~> 0.3.1" 67 | gem 'ting' 68 | 69 | group :development do 70 | gem 'thin', :platform => :ruby 71 | gem 'trinidad', :platform => :jruby 72 | gem 'pry' 73 | gem 'table_print' 74 | gem 'awesome_print' 75 | gem 'test-unit' 76 | gem 'rb-fsevent', '~> 0.9.1' 77 | gem 'rspec-rails' 78 | gem 'factory_girl_rails' 79 | gem 'capybara' 80 | gem 'guard-rspec' 81 | gem 'poltergeist' 82 | gem 'konacha' # for testing JavaScript with Mocha and chai 83 | end 84 | -------------------------------------------------------------------------------- /Guardfile: -------------------------------------------------------------------------------- 1 | # A sample Guardfile 2 | # More info at https://github.com/guard/guard#readme 3 | 4 | guard 'rspec' do 5 | watch(%r{^spec/.+_spec\.rb$}) 6 | watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" } 7 | watch('spec/spec_helper.rb') { "spec" } 8 | 9 | # Rails example 10 | watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } 11 | watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" } 12 | watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] } 13 | watch(%r{^spec/support/(.+)\.rb$}) { "spec" } 14 | watch('config/routes.rb') { "spec/routing" } 15 | watch('app/controllers/application_controller.rb') { "spec/controllers" } 16 | 17 | # Capybara request specs 18 | watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" } 19 | 20 | # Turnip features and steps 21 | watch(%r{^spec/acceptance/(.+)\.feature$}) 22 | watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' } 23 | end 24 | 25 | -------------------------------------------------------------------------------- /MIT-LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2012 The Text Laboratory, University of Oslo 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | # Add your own tasks in files placed in lib/tasks ending in .rake, 3 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 4 | 5 | require File.expand_path('../config/application', __FILE__) 6 | 7 | Glossa2::Application.load_tasks 8 | -------------------------------------------------------------------------------- /app/assets/images/clarin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/clarin.png -------------------------------------------------------------------------------- /app/assets/images/rails.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rails.png -------------------------------------------------------------------------------- /app/assets/images/rglossa/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rglossa/.gitkeep -------------------------------------------------------------------------------- /app/assets/images/rglossa/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rglossa/.keep -------------------------------------------------------------------------------- /app/assets/images/rglossa/speech/_6.6-'T'_ligo.skev.graa.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rglossa/speech/_6.6-'T'_ligo.skev.graa.jpg -------------------------------------------------------------------------------- /app/assets/images/rglossa/speech/jplayer.blue.monday.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rglossa/speech/jplayer.blue.monday.jpg -------------------------------------------------------------------------------- /app/assets/images/rglossa/speech/jplayer.blue.monday.video.play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rglossa/speech/jplayer.blue.monday.video.play.png -------------------------------------------------------------------------------- /app/assets/images/rglossa/speech/mm_20_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rglossa/speech/mm_20_black.png -------------------------------------------------------------------------------- /app/assets/images/rglossa/speech/mm_20_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rglossa/speech/mm_20_blue.png -------------------------------------------------------------------------------- /app/assets/images/rglossa/speech/mm_20_brown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rglossa/speech/mm_20_brown.png -------------------------------------------------------------------------------- /app/assets/images/rglossa/speech/mm_20_green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rglossa/speech/mm_20_green.png -------------------------------------------------------------------------------- /app/assets/images/rglossa/speech/mm_20_orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rglossa/speech/mm_20_orange.png -------------------------------------------------------------------------------- /app/assets/images/rglossa/speech/mm_20_purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rglossa/speech/mm_20_purple.png -------------------------------------------------------------------------------- /app/assets/images/rglossa/speech/mm_20_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rglossa/speech/mm_20_red.png -------------------------------------------------------------------------------- /app/assets/images/rglossa/speech/mm_20_shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rglossa/speech/mm_20_shadow.png -------------------------------------------------------------------------------- /app/assets/images/rglossa/speech/mm_20_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rglossa/speech/mm_20_white.png -------------------------------------------------------------------------------- /app/assets/images/rglossa/speech/mm_20_yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rglossa/speech/mm_20_yellow.png -------------------------------------------------------------------------------- /app/assets/images/rglossa/speech/play-pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rglossa/speech/play-pause.png -------------------------------------------------------------------------------- /app/assets/images/rglossa/speech/red_dot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rglossa/speech/red_dot.png -------------------------------------------------------------------------------- /app/assets/images/rglossa/speech/ui-bg_flat_75_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rglossa/speech/ui-bg_flat_75_ffffff_40x100.png -------------------------------------------------------------------------------- /app/assets/images/rglossa/speech/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rglossa/speech/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /app/assets/images/rglossa/speech/ui-bg_glass_75_dadada_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rglossa/speech/ui-bg_glass_75_dadada_1x400.png -------------------------------------------------------------------------------- /app/assets/images/rglossa/speech/ui-bg_glass_75_e6e6e6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rglossa/speech/ui-bg_glass_75_e6e6e6_1x400.png -------------------------------------------------------------------------------- /app/assets/images/rglossa/speech/ui-bg_highlight-soft_75_cccccc_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rglossa/speech/ui-bg_highlight-soft_75_cccccc_1x100.png -------------------------------------------------------------------------------- /app/assets/images/rglossa/speech/waveform.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rglossa/speech/waveform.png -------------------------------------------------------------------------------- /app/assets/images/rglossa/speech/zoom-in.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rglossa/speech/zoom-in.png -------------------------------------------------------------------------------- /app/assets/images/rglossa/speech/zoom-out.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/images/rglossa/speech/zoom-out.png -------------------------------------------------------------------------------- /app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, 5 | // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // the compiled file. 9 | // 10 | // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD 11 | // GO AFTER THE REQUIRES BELOW. 12 | // 13 | //= require rglossa/speech/application 14 | //= require rglossa/fcs/application 15 | //= require rglossa/application 16 | -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/javascripts/rglossa/.gitkeep -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/javascripts/rglossa/.keep -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into including all the files listed below. 2 | // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically 3 | // be included in the compiled file accessible from http://example.com/assets/application.js 4 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 5 | // the compiled file. 6 | // 7 | // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD 8 | // GO AFTER THE REQUIRES BELOW. 9 | //= require ./bundle 10 | //= require jquery 11 | //= require jquery_ujs 12 | //= require bootstrap-2.3.1/bootstrap 13 | //= require jquery-ui.min 14 | //= require select2 15 | //= require bootstrap-tags 16 | //= require opentip-jquery-excanvas.min 17 | //= require spin.min 18 | //= require jquery.spin 19 | //= require jquery-migrate-1.2.1.js 20 | //= require trad_chars.js 21 | //= require caret.js 22 | //= require jQuery.chineseIME.js 23 | // 24 | //= require i18n 25 | //= require i18n/translations 26 | // 27 | //= require ./main 28 | -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/components/app.jsx.coffee: -------------------------------------------------------------------------------- 1 | #= require ../store 2 | #= require ../statechart 3 | #= require ./top/navbar 4 | #= require ./centre/main_area 5 | 6 | ###* @jsx React.DOM ### 7 | 8 | models = [ 9 | 'corpora' 10 | 'searches' 11 | 'results' 12 | ] 13 | 14 | plurals = 15 | corpus: 'corpora' 16 | search: 'searches' 17 | 18 | root = 19 | initialSubstate: 'start' 20 | actions: 21 | showResults: (searchId, pageNo = 1) -> 22 | @transitionTo('results', 23 | searchId: searchId 24 | currentResultPageNo: pageNo) 25 | resetSearchForm: -> 26 | @transitionTo('start') 27 | substates: 28 | start: {} 29 | results: {} 30 | 31 | window.App = React.createClass 32 | getInitialState: -> 33 | store: new Store(models, plurals, (store) => @setState(store: store)) 34 | statechart: new Statechart('Main', root, (sc) => @setState(statechart: sc)) 35 | 36 | preloadImages: -> 37 | `[, 38 | ]` 39 | 40 | render: -> 41 | corpusShortName = location.search.match(/corpus=(.+)/)?[1] 42 | alert('Please provide a corpus name in the query string') unless corpusShortName 43 | 44 | corpus = @state.store.findBy('corpus', 'short_name', corpusShortName) 45 | ` 46 | {this.preloadImages()} 47 | 48 | {corpus 49 | ? 53 | : null} 54 | ` 55 | -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/components/centre/main_area_top.jsx.coffee: -------------------------------------------------------------------------------- 1 | #= require ./results/results_top 2 | 3 | ###* @jsx React.DOM ### 4 | 5 | window.MainAreaTop = React.createClass 6 | propTypes: 7 | statechart: React.PropTypes.object.isRequired 8 | corpus: React.PropTypes.object.isRequired 9 | results: React.PropTypes.object 10 | maxHits: React.PropTypes.number 11 | handleMaxHitsChanged: React.PropTypes.func.isRequired 12 | isShowingSidebar: React.PropTypes.bool.isRequired 13 | toggleSidebar: React.PropTypes.func.isRequired 14 | handleResetSearchForm: React.PropTypes.func.isRequired 15 | 16 | sideBarButtons: -> 17 | ` 18 | {this.props.isShowingSidebar 19 | ? 23 | : } 27 | ` 28 | 29 | 30 | render: -> 31 | {statechart, corpus, results, maxHits, handleMaxHitsChanged} = @props 32 | `
33 |
34 | {this.props.corpus.metadata_categories.length ? this.sideBarButtons() : null} 35 | 38 |
39 |
40 | {statechart.pathContains('start') 41 | ? null 42 | : } 47 |
48 |
` 49 | -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/components/centre/results/marker_picker.jsx.coffee: -------------------------------------------------------------------------------- 1 | ###* @jsx React.DOM ### 2 | 3 | window.MarkerPicker = React.createClass 4 | propTypes: 5 | data: React.PropTypes.object 6 | addMarkers: React.PropTypes.func.isRequired 7 | 8 | getPhons: -> 9 | if @props.data? 10 | Object.keys(@props.data.phons_per_place).filter (key) -> key isnt '_' 11 | else [] 12 | 13 | 14 | componentDidUpdate: -> 15 | return unless @props.data 16 | for phon in @getPhons() 17 | $("#phon_#{phon}").colorpicker 18 | label: phon 19 | func: (a, id) => @props.addMarkers(a, id) 20 | 21 | 22 | render: -> 23 | phons = @getPhons() 24 | 25 | `
26 | {phons.map(function(phon) { 27 | return ( 28 | 29 | {phon} 30 | 31 | ) 32 | })} 33 |
` 34 | -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/components/centre/results/num_hits.jsx.coffee: -------------------------------------------------------------------------------- 1 | #= require rglossa/utils 2 | 3 | ###* @jsx React.DOM ### 4 | 5 | window.NumHits = React.createClass 6 | propTypes: 7 | corpus: React.PropTypes.object.isRequired 8 | results: React.PropTypes.object 9 | maxHits: React.PropTypes.number 10 | handleMaxHitsChanged: React.PropTypes.func.isRequired 11 | 12 | getInitialState: -> 13 | displayedMaxHits: @props.results?.num_hits # see comments in handleMaxHitsChanged below 14 | 15 | componentWillReceiveProps: (nextProps) -> 16 | num_hits = nextProps.results?.num_hits ? null 17 | if num_hits isnt @state.displayedMaxHits 18 | # see comments in handleMaxHitsChanged below for why we need displayedMaxHits 19 | @setState(displayedMaxHits: num_hits) 20 | 21 | handleMaxHitsChanged: (e) -> 22 | maxHits = parseInt(e.target.value) 23 | unless isNaN(maxHits) 24 | # Set displayedMaxHits right away so that the text box shows the updated number... 25 | @setState(displayedMaxHits: e.target.value) 26 | # ...but debounce the new search in order to give the user time to finish writing 27 | # the new page number 28 | @debouncedHandleMaxHitsChanged(maxHits) if maxHits > 0 29 | 30 | debouncedHandleMaxHitsChanged: rglossaUtils.debounce ((maxHits) -> @props.handleMaxHitsChanged(maxHits)), 500 31 | 32 | handleShowAll: -> 33 | @props.handleMaxHitsChanged(null) 34 | 35 | numHitsInfo: -> 36 | results = @props.results 37 | noResultsFound = results.num_hits is 0 38 | hasReceivedTotal = results.total? 39 | 40 | if noResultsFound 41 | `No matches found` 42 | else 43 | if hasReceivedTotal 44 | `Found {results.total} {results.num_hits === 1 ? 'match' : 'matches'}` 45 | else 46 | `
Counting matches` 47 | 48 | 49 | render: -> 50 | {corpus, results, maxHits} = @props 51 | 52 | if results 53 | parts = corpus.parts or [] 54 | hitsAreCutOff = results.num_hits is maxHits 55 | 56 | `
57 | {this.numHitsInfo()} 58 | {hitsAreCutOff 59 | ? ; showing the first 62 | 63 | 64 | : null 65 | } 66 | {parts.map(function(part) { 67 | {part.short_name} = {part.name} 68 | })} 69 |
` 70 | else 71 | `
Searching...
` 72 | 73 | -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/components/centre/results/results_top.jsx.coffee: -------------------------------------------------------------------------------- 1 | #= require ./num_hits 2 | 3 | ###* @jsx React.DOM ### 4 | 5 | window.ResultsTop = React.createClass 6 | propTypes: 7 | corpus: React.PropTypes.object.isRequired 8 | results: React.PropTypes.object 9 | maxHits: React.PropTypes.number 10 | handleMaxHitsChanged: React.PropTypes.func.isRequired 11 | 12 | render: -> 13 | {results, corpus, maxHits, handleMaxHitsChanged} = @props 14 | `` 19 | -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/components/centre/search_inputs/cwb_cqp_query_input.jsx.coffee: -------------------------------------------------------------------------------- 1 | ###* @jsx React.DOM ### 2 | 3 | window.CwbCqpQueryInput = React.createClass 4 | propTypes: 5 | showRemoveRow: React.PropTypes.bool.isRequired 6 | searchQuery: React.PropTypes.object.isRequired 7 | handleQueryChanged: React.PropTypes.func.isRequired 8 | handleRemoveRow: React.PropTypes.func.isRequired 9 | handleSearch: React.PropTypes.func.isRequired 10 | 11 | componentDidMount: -> 12 | @refs.searchfield.getDOMNode().focus() 13 | 14 | handleTextChanged: (e) -> 15 | @props.handleQueryChanged 16 | lang: @props.searchQuery.lang 17 | query: MainArea.convertToNonHeadwordQuery(e.target.value) 18 | headwordSearch: MainArea.convertToHeadwordQuery( 19 | MainArea.convertToNonHeadwordQuery(e.target.value)) == e.target.value 20 | 21 | displayedQuery: -> 22 | # Just take the CQP expression 23 | @props.searchQuery.query 24 | 25 | handleKeyDown: (e) -> 26 | if e.key is 'Enter' 27 | e.preventDefault() 28 | @props.handleSearch(searchInput: 'cqp') 29 | 30 | render: -> 31 | `
32 |
33 |
34 | {this.props.showRemoveRow ? : null} 35 | 37 |
38 |
39 |
` 40 | -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/components/centre/search_inputs/cwb_multiword_menu.jsx.coffee: -------------------------------------------------------------------------------- 1 | ###* @jsx React.DOM ### 2 | 3 | window.CwbMultiwordMenu = React.createClass 4 | propTypes: 5 | tags: React.PropTypes.array 6 | handleAddPos: React.PropTypes.func.isRequired 7 | handleAddFeature: React.PropTypes.func.isRequired 8 | 9 | getDefaultProps: -> 10 | tags: [] 11 | 12 | createPosMenu: (pos) -> 13 | if pos.features 14 | `
  • 15 | {pos.name} 16 |
      17 | {pos.features.map(this.createFeatureMenu)} 18 |
    19 |
  • ` 20 | else 21 | `
  • 22 | {pos.name} 23 |
  • ` 24 | 25 | 26 | createFeatureMenu: (feature) -> 27 | heading = if feature.name then `
  • {feature.name}
  • ` else null 28 | options = feature.options.map ((option) -> 29 | `
  • 30 | {option.name || option.value} 31 |
  • `), this 32 | [heading, options] 33 | 34 | 35 | render: -> 36 | `
      37 | {this.props.tags.map(this.createPosMenu)} 38 |
    ` -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/components/centre/search_inputs/language_select.jsx.coffee: -------------------------------------------------------------------------------- 1 | #= require rglossa/models/corpus 2 | 3 | ###* @jsx React.DOM ### 4 | 5 | window.LanguageSelect = React.createClass 6 | propTypes: 7 | corpus: React.PropTypes.object.isRequired 8 | selectedValue: React.PropTypes.string.isRequired 9 | index: React.PropTypes.number.isRequired 10 | handleChangeLanguage: React.PropTypes.func.isRequired 11 | 12 | onChange: (e) -> 13 | @props.handleChangeLanguage(this.props.index, e.target.value) 14 | 15 | render: -> 16 | languageList = corpusNs.getLanguageList(@props.corpus) 17 | 18 | `` 23 | -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/components/centre/start/corpus_info.jsx.coffee: -------------------------------------------------------------------------------- 1 | ###* @jsx React.DOM ### 2 | 3 | window.CorpusInfo = React.createClass 4 | propTypes: 5 | corpusName: React.PropTypes.string.isRequired 6 | corpusLogoUrl: React.PropTypes.string 7 | 8 | render: -> 9 | `
    10 |
    11 |
    12 |

    13 | 14 |

    15 |
    16 |
    17 |
    18 | {this.props.corpusLogoUrl ? : ''} 19 |
    20 |
    ` 21 | -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/components/centre/start/start_main.jsx.coffee: -------------------------------------------------------------------------------- 1 | #= require rglossa/utils 2 | #= require ./corpus_info 3 | #= require ../search_inputs/cwb_search_inputs 4 | 5 | ###* @jsx React.DOM ### 6 | 7 | window.StartMain = React.createClass 8 | propTypes: 9 | store: React.PropTypes.object.isRequired 10 | statechart: React.PropTypes.object.isRequired 11 | corpus: React.PropTypes.object.isRequired 12 | searchQueries: React.PropTypes.array.isRequired 13 | handleQueryChanged: React.PropTypes.func.isRequired 14 | handleSearch: React.PropTypes.func.isRequired 15 | handleAddLanguage: React.PropTypes.func.isRequired 16 | handleChangeLanguage: React.PropTypes.func.isRequired 17 | handleAddPhrase: React.PropTypes.func.isRequired 18 | handleRemoveRow: React.PropTypes.func.isRequired 19 | 20 | render: -> 21 | {store, statechart, corpus, searchQueries, handleQueryChanged, handleSearch, 22 | handleAddLanguage, handleChangeLanguage, handleAddPhrase, handleRemoveRow} = @props 23 | {name, logo} = corpus 24 | 25 | # Select a component based on the search engine name, e.g. CwbSearchInputs 26 | searchEngine = corpus.search_engine or 'cwb' 27 | SearchInputs = window["#{rglossaUtils.capitalize(searchEngine)}SearchInputs"] 28 | 29 | ` 30 | 33 | 44 | ` 45 | -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/components/top/navbar.js.jsx.coffee: -------------------------------------------------------------------------------- 1 | ###* @jsx React.DOM ### 2 | 3 | window.Navbar = React.createClass 4 | render: -> 5 | idp_login_links = $.map login_urls, (url, idp) -> 6 | ` 7 | Log in ({idp}) ` 8 | 9 | login_status = if username is '' 10 | idp_login_links 11 | else 12 | `Logged in as: {displayName}  13 | Log out` 14 | 15 | `
    16 |
    17 |
    18 | Glossa 19 | {login_status} 20 |
    21 |
    22 |
    ` 23 | -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/entry.js: -------------------------------------------------------------------------------- 1 | window.React = require('../../../../node_modules/react/addons') 2 | -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/main.jsx.coffee: -------------------------------------------------------------------------------- 1 | #= require ./translations/translations 2 | #= require ./components/app 3 | 4 | ###* @jsx React.DOM ### 5 | 6 | React.render(``, document.getElementById('application')) 7 | -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/models/corpus.coffee: -------------------------------------------------------------------------------- 1 | class Corpus 2 | getLanguages: (corpus) -> corpus.langs 3 | 4 | getLanguageList: (corpus) -> 5 | languages = @getLanguages(corpus) 6 | for language in languages 7 | value: language.lang 8 | text: i18n.translate(language.lang).onDomain('languages').fetch() 9 | 10 | getLanguage: (corpus, languageCode) -> 11 | languages = @getLanguages(corpus) 12 | 13 | if languageCode is 'single' # monolingual corpus 14 | if languages.length then languages[0] else null 15 | else 16 | (language for language in languages when language.lang is languageCode)?[0] 17 | 18 | 19 | getLabels: (corpus, languageCode = 'single') -> 20 | language = @getLanguage(corpus, languageCode) 21 | language?.displayAttrs or corpus.display_attrs or [] 22 | 23 | getPOSAttribute: (corpus, languageCode = 'single') -> 24 | language = @getLanguage(corpus, languageCode) 25 | language?.tags?.attr or 'pos' 26 | 27 | getTags: (corpus, languageCode = 'single') -> 28 | language = @getLanguage(corpus, languageCode) 29 | language?.tags or [] 30 | 31 | isMultilingual: (corpus) -> 32 | @getLanguages(corpus).length > 1 33 | 34 | 35 | window.corpusNs = new Corpus 36 | -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/speech/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into including all the files listed below. 2 | // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically 3 | // be included in the compiled file accessible from http://example.com/assets/application.js 4 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 5 | // the compiled file. 6 | // 7 | // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD 8 | // GO AFTER THE REQUIRES BELOW. 9 | //= require rglossa/bundle 10 | //= require jquery 11 | //= require_tree ./components 12 | //= require ./jquery.jplayer.min 13 | //= require ./jquery.colorpicker 14 | -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/speech/components/centre/results/speech_cwb_results_table.jsx.coffee: -------------------------------------------------------------------------------- 1 | #= require rglossa/components/centre/results/cwb_results_table 2 | 3 | ###* @jsx React.DOM ### 4 | 5 | window.SpeechCwbResultsTable = window.CwbResultsTable 6 | -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/speech/components/centre/results/wfplayer.jsx.coffee: -------------------------------------------------------------------------------- 1 | ###* @jsx React.DOM ### 2 | 3 | window.WFplayer = React.createClass 4 | componentDidMount: -> 5 | $node = $(@getDOMNode()) 6 | mediaObj = @props.mediaObj 7 | 8 | $(document).tooltip 9 | content: -> $node.prop('title') 10 | 11 | corpus_id = mediaObj.corpus_id 12 | line_key = mediaObj.mov.line_key 13 | $("#movietitle").text(mediaObj.title) 14 | start = mediaObj.divs.annotation[@props.startAt || parseInt(mediaObj.start_at)].from 15 | stop = mediaObj.divs.annotation[@props.endAt || parseInt(mediaObj.end_at)].to 16 | 17 | $node.find("#waveframe").attr('src', "wfplayer-#{corpus_id}-#{line_key}-#{start}-#{stop}") 18 | 19 | render: -> 20 | `
    ` 21 | -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/speech/components/centre/search_inputs/speech_cwb_search_inputs.jsx.coffee: -------------------------------------------------------------------------------- 1 | #= require rglossa/components/centre/search_inputs/cwb_search_inputs 2 | 3 | window.SpeechCwbSearchInputs = window.CwbSearchInputs -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/store.coffee: -------------------------------------------------------------------------------- 1 | class Store 2 | constructor: (models, @plurals, @storeChangedHandler, autoLoad = false) -> 3 | @models = {} 4 | @models[model] = {} for model in models 5 | @fetchData(models) if autoLoad 6 | 7 | getPlural: (singular) -> @plurals[singular] ? "#{singular}s" 8 | 9 | fetchData: (models) -> 10 | promises = for model in models 11 | do (model) => 12 | $.getJSON(model) 13 | .done( (res) => 14 | for data in res 15 | id = data.id 16 | @models[model][id] = data 17 | ) 18 | .fail -> alert('Error fetching data from the server. Please reload the page.') 19 | $.when.apply(null, promises).done(=> @storeChangedHandler(@)) 20 | 21 | 22 | find: (model, id) -> 23 | @findBy(model, 'id', id) 24 | 25 | # Looks up the model in the store by the given attribute, assuming that this attribute 26 | # will be the one that is used as the key in the store. If the model is not already 27 | # loaded, we send a request to the server to fetch it. If the attribute is 'id', we 28 | # use the normal RESTful plural-model-name/id approach which will cause the 'show' method 29 | # to be called in Rails; otherwise we use plural-model-name/find_by?attribute=value, which 30 | # will have to be supported by the Rails controller for the resouce. 31 | findBy: (model, attribute, value) -> 32 | plural = @getPlural(model) 33 | data = @models[plural][value] 34 | return data if data? # Store already contains the model 35 | 36 | # Store does not already contain the model, so fetch it 37 | url = if attribute is 'id' 38 | "#{plural}/#{value}" 39 | else 40 | "#{plural}/find_by?#{attribute}=#{value}" 41 | 42 | $.getJSON(url) 43 | .done( (res) => 44 | @setData(model, value, res[model]) 45 | ) 46 | .fail -> alert('Error fetching data from the server. Please reload the page.') 47 | 48 | # Return null since the store did not contain the model. When the model has been 49 | # loaded, @storeChangedHandler will be called (via @setData), and then the client 50 | # can call `find` again to retrieve the model. 51 | null 52 | 53 | 54 | setData: (model, id, data) -> 55 | plural = @getPlural(model) 56 | @models[plural][id] = data 57 | # Notify the client that the model has been loaded 58 | @storeChangedHandler(@) 59 | 60 | 61 | window.Store = Store -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/translations/en.coffee: -------------------------------------------------------------------------------- 1 | window.translations ||= {} 2 | 3 | window.translations['en'] = 4 | languages: 5 | "": 6 | lang: "en" 7 | "en": [null, "English"] 8 | "no": [null, "Norwegian"] 9 | "nb": [null, "Norwegian bokmål"] 10 | "nn": [null, "Norwegian nynorsk"] 11 | "ru": [null, "Russian"] 12 | "fr": [null, "French"] 13 | "it": [null, "Italian"] 14 | "se": [null, "Swedish"] 15 | -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/translations/nb.coffee: -------------------------------------------------------------------------------- 1 | window.translations ||= {} 2 | 3 | window.translations['nb'] = 4 | languages: 5 | "": 6 | lang: "nb" 7 | "en": [null, "engelsk"] 8 | "no": [null, "norsk"] 9 | "nb": [null, "bokmål"] 10 | "nn": [null, "nynorsk"] 11 | "ru": [null, "russisk"] 12 | -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/translations/translations.coffee: -------------------------------------------------------------------------------- 1 | #= require jed 2 | #= require ./en 3 | #= require ./nb 4 | 5 | window.i18n = new Jed 6 | locale_data: window.translations['en'] 7 | -------------------------------------------------------------------------------- /app/assets/javascripts/rglossa/utils.coffee: -------------------------------------------------------------------------------- 1 | window.rglossaUtils = 2 | capitalize: (str) -> 3 | return '' unless str.length 4 | (str.split('_').map (part) -> part[0].toUpperCase() + part.slice(1)).join('') 5 | 6 | 7 | # From http://davidwalsh.name/javascript-debounce-function 8 | 9 | # Returns a function, that, as long as it continues to be invoked, will not 10 | # be triggered. The function will be called after it stops being called for 11 | # N milliseconds. If `immediate` is passed, trigger the function on the 12 | # leading edge, instead of the trailing. 13 | debounce: (func, wait, immediate) -> 14 | timeout = null 15 | -> 16 | context = @ 17 | args = arguments 18 | clearTimeout(timeout) 19 | timeout = setTimeout((-> 20 | timeout = null 21 | func.apply(context, args) unless immediate), wait) 22 | if immediate && not timeout 23 | func.apply(context, args) 24 | 25 | 26 | # Merges the key/value pairs from obj1 and obj2 into one object, with pairs 27 | # from obj2 overriding any pairs from obj1 with identical keys. 28 | merge: (obj1, obj2) -> 29 | res = {} 30 | res[key] = value for key, value of obj1 31 | res[key] = value for key, value of obj2 32 | res 33 | 34 | 35 | withoutPrefix: (str, prefix) -> 36 | if str.substr(0, prefix.length) == prefix 37 | str.substr(prefix.length) 38 | else 39 | str 40 | 41 | 42 | withoutSuffix: (str, suffix) -> 43 | if str.substr(-suffix.length) == suffix 44 | str.substr(0, str.length - suffix.length) 45 | else 46 | str 47 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, 6 | * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the top of the 9 | * compiled file, but it's generally better to create a new file per style scope. 10 | * 11 | *= require_self 12 | *= require bootstrap-3.3.4/bootstrap.min 13 | *= require bootstrap-3.3.4/bootstrap-theme.min 14 | *= require simple-sidebar 15 | *= require select2 16 | *= require style 17 | */ 18 | -------------------------------------------------------------------------------- /app/assets/stylesheets/rglossa/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/assets/stylesheets/rglossa/.keep -------------------------------------------------------------------------------- /app/assets/stylesheets/rglossa/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll automatically include all the stylesheets available in this directory 3 | * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at 4 | * the top of the compiled file, but it's generally better to create a new file per style scope. 5 | *= require_self 6 | *= require bootstrap-2.3.1/bootstrap 7 | *= require rglossa/bootstrap_overrides 8 | *= require font-awesome.min 9 | *= require select2 10 | *= require bootstrap-tags 11 | *= require opentip 12 | *= require_tree ./speech 13 | *= require ./geo-distribution 14 | *= require ./home 15 | *= require ime 16 | */ 17 | -------------------------------------------------------------------------------- /app/assets/stylesheets/rglossa/bootstrap_overrides.css.scss: -------------------------------------------------------------------------------- 1 | .modal.fade { 2 | /* Need to change this from -50% to prevent modals from covering 3 | links on the page even after they are hidden (since half of the 4 | modal still exists on the page as an invisible cover which prevents 5 | links from working) */ 6 | top: -100%; 7 | } -------------------------------------------------------------------------------- /app/assets/stylesheets/rglossa/geo-distribution.css.scss: -------------------------------------------------------------------------------- 1 | .colorpicker-trigger { 2 | margin-top: 3px; 3 | } 4 | 5 | .distr-map { 6 | width: 850px; 7 | margin-left: -400px; 8 | } 9 | 10 | .distr-legend { 11 | border: 3px solid #E6E6E6; 12 | border-radius: 5px; 13 | -moz-border-radius: 5px; 14 | -webkit-border-radius: 5px; 15 | position: absolute; 16 | left: 670px; 17 | background-color: #FAFAFA; 18 | width: 140px; 19 | height: 536px; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /app/assets/stylesheets/rglossa/speech/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll automatically include all the stylesheets available in this directory 3 | * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at 4 | * the top of the compiled file, but it's generally better to create a new file per style scope. 5 | *= require_tree . 6 | */ 7 | -------------------------------------------------------------------------------- /app/assets/stylesheets/rglossa/speech/media.scss: -------------------------------------------------------------------------------- 1 | .jplayer-container { 2 | position: relative; 3 | 4 | a { 5 | color: black; 6 | text-decoration: none; 7 | } 8 | } 9 | 10 | .media-player { 11 | a { 12 | font-family: courier; 13 | font-size: .8em; 14 | } 15 | 16 | a.match{ 17 | color:#b00; 18 | font-weight:bold; 19 | font-size:0.9em; 20 | } 21 | } 22 | 23 | .autocue{ 24 | width: 100%; 25 | background-color: #fff; 26 | border-style:solid; 27 | border-width:1px; 28 | border-color: #efe; 29 | } 30 | .textDiv{ 31 | display: table-row; 32 | } 33 | .waveDiv{ 34 | display: block; 35 | } 36 | .slider-range{ 37 | width:480px; 38 | 39 | } 40 | .speakerDiv,.waveformBtnDiv{ 41 | /* 42 | border-style:solid; 43 | border-width:1px; 44 | border-color: #efe; 45 | */ 46 | color:#33c; 47 | display: table-cell; 48 | } 49 | .segmentDiv{ 50 | /* 51 | border-style:solid; 52 | border-width:1px; 53 | border-color: #eef; 54 | */ 55 | padding: 3px 15px; 56 | display: table-cell; 57 | } 58 | div.console 59 | { 60 | border:2px solid; 61 | border-radius:25px; 62 | } 63 | 64 | .wfplayer { 65 | border: 0; 66 | } 67 | -------------------------------------------------------------------------------- /app/controllers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/controllers/.keep -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | protect_from_forgery 3 | end 4 | -------------------------------------------------------------------------------- /app/controllers/front_controller.rb: -------------------------------------------------------------------------------- 1 | class FrontController < ApplicationController 2 | layout false 3 | 4 | def index 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/controllers/rglossa/application_controller.rb: -------------------------------------------------------------------------------- 1 | # Filters added to this controller apply to all controllers in the application. 2 | # Likewise, all the methods added will be available for all controllers. 3 | 4 | module Rglossa 5 | class ApplicationController < ActionController::Base 6 | 7 | protect_from_forgery # See ActionController::RequestForgeryProtection for details 8 | 9 | # before_filter :authenticate_user! 10 | 11 | ######## 12 | private 13 | ######## 14 | 15 | def received_id_for?(klass) 16 | params["#{klass}_id"].to_i > 0 17 | end 18 | 19 | end 20 | end -------------------------------------------------------------------------------- /app/controllers/rglossa/home_controller.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | class HomeController < ApplicationController 3 | layout 'application' 4 | 5 | def index 6 | if Rails.env == 'development' && params.has_key?(:user) 7 | session[:current_username] = params[:user] 8 | end 9 | unless params[:corpus].present? 10 | redirect_to front_url 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /app/controllers/rglossa/metadata_categories_controller.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | class MetadataCategoriesController < ApplicationController 3 | def index 4 | raise "Corpus ID is missing!" unless received_id_for?(:corpus) 5 | 6 | categories = MetadataCategory.where(corpus_id: params[:corpus_id]) 7 | 8 | respond_to do |format| 9 | format.json { render json: categories } 10 | format.xml { render xml: categories } 11 | end 12 | end 13 | end 14 | end -------------------------------------------------------------------------------- /app/controllers/rglossa/metadata_values_controller.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | class MetadataValuesController < ApplicationController 3 | 4 | def index 5 | raise "Metadata category ID is missing!" unless received_id_for?(:metadata_category) 6 | 7 | metadata = [] 8 | metadata_value_ids = params[:metadata_value_ids] 9 | 10 | if metadata_value_ids && metadata_value_ids.length > 0 11 | # Restrict the set of possible values for this metadata category based on the set of 12 | # values that has already been selected from other categories to prevent selection of 13 | # incompatible values. We do this by finding all corpus texts that are associated with 14 | # the already chosen values and then finding all values from the desired category that 15 | # are associated with the same set of texts. 16 | metadata = metadata_value_ids.map do |cat, vals| 17 | # Don't restrict the possible values based on previous choices within the *same* category, 18 | # because then we could only select a single value from each category... 19 | cat != params[:metadata_category_id] ? vals.map(&:to_i) : nil 20 | end 21 | metadata = metadata.compact.flatten 22 | end 23 | 24 | if metadata.empty? 25 | values = MetadataValue.where(metadata_category_id: params[:metadata_category_id]) 26 | else 27 | values = MetadataValue.get_constrained_list(params[:metadata_category_id], metadata) 28 | end 29 | 30 | unless values.empty? || params[:query].blank? 31 | value_class = values.first.type.constantize 32 | 33 | # Different subclasses of MetadataValue implement different SQL searches 34 | values = value_class.search(params[:query], values) 35 | end 36 | 37 | respond_to do |format| 38 | format.json { render json: { metadata_values: values } } 39 | format.xml { render xml: values } 40 | end 41 | end 42 | 43 | end 44 | end -------------------------------------------------------------------------------- /app/controllers/rglossa/r/search_engines/cwb_controller.rb: -------------------------------------------------------------------------------- 1 | require 'rserve' 2 | 3 | module Rglossa 4 | module R 5 | module SearchEngines 6 | class CwbController < ApplicationController 7 | 8 | def query_freq 9 | attribute = params[:attribute] || 'word' 10 | 11 | # TODO: Handle multiple queries 12 | query = params[:query].first[:query] 13 | corpus = params[:corpus].upcase 14 | 15 | conn = Rserve::Connection.new 16 | conn.eval('library("rcqp")') 17 | conn.eval(%Q{corp <- corpus("#{corpus}")}) 18 | conn.eval(%Q{subcorp <- subcorpus(corp, '#{query}')}) 19 | 20 | freqs = conn.eval(%Q{freqs <- cqp_flist(subcorp, "match", "#{attribute}")}) 21 | 22 | pairs = [] 23 | freqs.attr.to_ruby[0].zip(freqs.to_ruby) do |a, f| 24 | pairs << {form: a, freq: f} 25 | end 26 | 27 | render json: {pairs: pairs, success: true} 28 | end 29 | 30 | end 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /app/controllers/rglossa/search_engines/cwb_searches_controller.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | module SearchEngines 3 | class CwbSearchesController < Rglossa::SearchesController 4 | 5 | # Used by the base controller to find the right kind of model to work with 6 | def model_class 7 | CwbSearch 8 | end 9 | 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /app/controllers/rglossa/speech/search_engines/speech_cwb_searches_controller.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | module Speech 3 | module SearchEngines 4 | class SpeechCwbSearchesController < Rglossa::SearchEngines::CwbSearchesController 5 | 6 | # Used by the base controller to find the right kind of model to work with 7 | def model_class 8 | SpeechCwbSearch 9 | end 10 | 11 | def geo_distr 12 | search = model_class.find(params[:id]) 13 | distribution = search.geo_distr 14 | render json: distribution 15 | end 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /app/helpers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/helpers/.keep -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/front_helper.rb: -------------------------------------------------------------------------------- 1 | module FrontHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/rglossa/application_helper.rb: -------------------------------------------------------------------------------- 1 | # Methods added to this helper will be available to all templates in the application. 2 | module Rglossa 3 | module ApplicationHelper 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/helpers/rglossa/corpora_helper.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | module CorporaHelper 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/helpers/rglossa/home_helper.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | module HomeHelper 3 | def possibly_debug_suffix 4 | Rails.env == 'development' ? '-debug' : '' 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/helpers/rglossa/metadata_categories_helper.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | module MetadataCategoriesHelper 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/helpers/rglossa/metadata_values_helper.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | module MetadataValuesHelper 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/helpers/rglossa/search_engines/cwb_searches_helper.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | module SearchEngines::CwbSearchesHelper 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/helpers/rglossa/searches_helper.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | module SearchesHelper 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/mailers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/mailers/.gitkeep -------------------------------------------------------------------------------- /app/mailers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/mailers/.keep -------------------------------------------------------------------------------- /app/models/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/models/.gitkeep -------------------------------------------------------------------------------- /app/models/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/models/.keep -------------------------------------------------------------------------------- /app/models/corpus.rb: -------------------------------------------------------------------------------- 1 | require 'ostruct' 2 | 3 | class Corpus < OpenStruct 4 | 5 | def multilingual? 6 | languages.class == Array && languages.size > 1 7 | end 8 | 9 | def has_sound? 10 | # Cannot use ||= since the value may be false 11 | @has_sound = has_media?('audio') if @has_sound.nil? 12 | @has_sound 13 | end 14 | 15 | def has_video? 16 | # Cannot use ||= since the value may be false 17 | @has_video = has_media?('video') if @has_video.nil? 18 | @has_video 19 | end 20 | 21 | def speech_corpus? 22 | has_sound || has_video 23 | end 24 | 25 | def metadata_category_ids 26 | metadata_categories.pluck(:id) 27 | end 28 | 29 | def langs 30 | if languages 31 | languages.map do |l| 32 | res = {lang: l[:lang]} 33 | tagger_config = Rglossa.taggers[l[:tagger].to_s] 34 | 35 | if tagger_config 36 | res.merge!({ 37 | displayAttrs: tagger_config['displayAttrs'], 38 | tags: tagger_config['tags'] 39 | }) 40 | end 41 | res 42 | end 43 | else 44 | [] 45 | end 46 | end 47 | 48 | private 49 | 50 | def has_media?(type) 51 | path = "public/media/#{code}/#{type}" 52 | Dir.exist?(path) && !Dir.entries(path).empty? 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /app/models/rglossa/access_permission.rb: -------------------------------------------------------------------------------- 1 | class Rglossa::AccessPermission < ActiveRecord::Base 2 | self.table_name = "rglossa_access_permissions" 3 | belongs_to :user 4 | belongs_to :corpus 5 | end 6 | -------------------------------------------------------------------------------- /app/models/rglossa/account.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | class Account < ActiveRecord::Base 3 | def self.get_saml_settings(idp) 4 | # To make things simpler with environment variable names, allow only 5 | # (case-insensitive) Latin characters and the underscore: 6 | idp_caps = idp.gsub(/[^a-z_]/i, '').upcase 7 | idp_lc = idp_caps.downcase 8 | settings = OneLogin::RubySaml::Settings.new 9 | app_url = URI::join(ENV['APP_HOST_URL'], ENV['RAILS_RELATIVE_URL_ROOT'] + "/") 10 | settings.assertion_consumer_service_url = URI::join(app_url, "auth/#{idp_lc}").to_s 11 | settings.assertion_consumer_logout_service_url = URI::join(app_url, "logout/#{idp_lc}").to_s 12 | settings.issuer = URI::join(app_url, "saml/metadata/#{idp_lc}") 13 | settings.idp_entity_id = ENV["#{idp_caps}_IDP_ENTITY_ID"] 14 | settings.idp_sso_target_url = ENV["#{idp_caps}_IDP_SSO_TARGET_URL"] 15 | settings.idp_slo_target_url = ENV["#{idp_caps}_IDP_SLO_TARGET_URL"] 16 | settings.idp_cert_fingerprint = ENV["#{idp_caps}_IDP_CERT_FINGERPRINT"] 17 | settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" 18 | settings 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /app/models/rglossa/deleted_hit.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | class DeletedHit < ActiveRecord::Base 3 | self.table_name = "rglossa_delete_hits" 4 | belongs_to :search 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/models/rglossa/media_file.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | class MediaFile < ActiveRecord::Base 3 | self.table_name = "rglossa_media_files" 4 | attr_accessible :line_key_begin, :line_key_end, :basename 5 | 6 | belongs_to :corpus 7 | 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/models/rglossa/metadata_category.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | class MetadataCategory < ActiveRecord::Base 3 | self.table_name = "rglossa_metadata_categories" 4 | attr_accessible :locale, :short_name, :name, :corpus, :category_type, :value_type 5 | 6 | translates :name, fallbacks_for_empty_translations: true 7 | 8 | validates_presence_of :short_name 9 | validates_presence_of :category_type 10 | validates_presence_of :value_type 11 | 12 | belongs_to :corpus 13 | 14 | has_many :metadata_values, 15 | dependent: :destroy, 16 | order: :text_value, 17 | before_add: ->(category, value) { value.type = category.value_type } 18 | 19 | def vtype 20 | value_type.demodulize.underscore 21 | end 22 | 23 | def metadata_value_ids 24 | metadata_values.pluck(:id) 25 | end 26 | 27 | def get_metadata_value(value) 28 | metadata_values.with_type_and_value(value_type, value) || 29 | metadata_values.create do |o| 30 | # For some reason, the before_add hook is not called here, so we cannot use the 31 | # text=() method of MetadataValue but need to figure out the correct column ourselves 32 | column = "#{value_type.demodulize.underscore}_value" 33 | o.update_attribute(column, value) 34 | end 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /app/models/rglossa/metadata_value.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | class MetadataValue < ActiveRecord::Base 3 | self.table_name = "rglossa_metadata_values" 4 | belongs_to :metadata_category 5 | has_and_belongs_to_many :corpus_texts, join_table: 'rglossa_corpus_texts_metadata_values', 6 | foreign_key: 'rglossa_metadata_value_id', 7 | association_foreign_key: 'rglossa_corpus_text_id' 8 | 9 | validates_presence_of :metadata_category_id 10 | 11 | def as_json(options={}) 12 | opts = {only: :id, methods: :text}.merge(options) 13 | super(opts) 14 | end 15 | 16 | class << self 17 | 18 | def get_constrained_list(category_id, constraining_values) 19 | ids = connection.execute( 20 | sanitize_sql(['SELECT DISTINCT rglossa_metadata_values.id ' + 21 | 'FROM rglossa_metadata_values INNER JOIN rglossa_corpus_texts_metadata_values j ' + 22 | 'ON j.rglossa_metadata_value_id = rglossa_metadata_values.id ' + 23 | 'INNER JOIN rglossa_corpus_texts t ' + 24 | 'ON j.rglossa_corpus_text_id = t.id ' + 25 | 'INNER JOIN rglossa_corpus_texts_metadata_values j2 ' + 26 | 'ON j2.rglossa_corpus_text_id = t.id ' + 27 | 'WHERE metadata_category_id = %s AND j2.rglossa_metadata_value_id IN (%s)', 28 | category_id, *constraining_values])).to_a 29 | find(ids) 30 | end 31 | 32 | def with_type_and_value(value_type, value) 33 | column = "#{value_type.demodulize.underscore}_value" 34 | value = value_type.constantize.convert_text_value(value) 35 | where(["#{column} = ?", value]).first 36 | end 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /app/models/rglossa/metadata_values/boolean.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | module MetadataValues 3 | class Boolean < MetadataValue 4 | def text 5 | boolean_value ? 'yes' : 'no' 6 | end 7 | 8 | def text=(val) 9 | # Set the "text" of this metadata value to *true* if the given value is 10 | # true and it is not one of the strings "no" and "false"; otherwise, set 11 | # it to false 12 | self.boolean_value = val && !val.in?('no', 'false') 13 | end 14 | 15 | # Converts a text value to a value of the type handled by this class 16 | def self.convert_text_value(val) 17 | val.in?('no', 'false') ? false : true 18 | end 19 | 20 | def self.search(query, scope = scoped) 21 | scope.where('boolean_value = ?', query.in?('true', 'yes')) 22 | end 23 | end 24 | end 25 | end -------------------------------------------------------------------------------- /app/models/rglossa/metadata_values/integer.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | module MetadataValues 3 | class Integer < MetadataValue 4 | def text 5 | integer_value.to_s 6 | end 7 | 8 | def text=(val) 9 | self.integer_value = val.to_i 10 | end 11 | 12 | # Converts a text value to a value of the type handled by this class 13 | def self.convert_text_value(value) 14 | value.to_i 15 | end 16 | 17 | def self.search(query, scope = scoped) 18 | scope.where('integer_value = ?', query.to_i) 19 | end 20 | end 21 | end 22 | end -------------------------------------------------------------------------------- /app/models/rglossa/metadata_values/text.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | module MetadataValues 3 | class Text < MetadataValue 4 | def text 5 | text_value || '' 6 | end 7 | 8 | def text=(val) 9 | self.text_value = val.to_s 10 | end 11 | 12 | # Converts a text value to a value of the type handled by this class 13 | def self.convert_text_value(value) 14 | value 15 | end 16 | 17 | def self.search(query, scope = scoped) 18 | scope.where('text_value LIKE ?', "%#{query}%") 19 | end 20 | end 21 | end 22 | end -------------------------------------------------------------------------------- /app/models/rglossa/search.rb: -------------------------------------------------------------------------------- 1 | require 'ostruct' 2 | require './lib/orientdb' 3 | 4 | module Rglossa 5 | class Search < OpenStruct 6 | include OrientDb 7 | 8 | def corpus 9 | @corpus ||= one(Corpus, "SELECT expand(out('inCorpus')) FROM #TARGET", {target: rid}) 10 | end 11 | 12 | def query_array 13 | @query_array ||= JSON.parse(queries) 14 | end 15 | 16 | # This is run after the search record has been created. It 17 | # should set num_hits on the model and store either the actual search 18 | # results or the search itself in some way that makes it possible to 19 | # retrieve results using get_result_page (which also needs to be 20 | # implemented by each subclass). 21 | def run_queries(step, cut = nil, options = {}) 22 | raise "Implement this method in subclasses and throw an " + 23 | "Rglossa::QueryError if running queries produces an error." 24 | end 25 | 26 | # This will be included in the response returned from the *create* action 27 | # so that we don't have to send an extra request in order to get the first 28 | # two result pages after creating the search (we get two pages in order to 29 | # preload the second page when the user views the first page) 30 | def first_two_result_pages(options = {}) 31 | get_result_pages([1, 2], options) 32 | end 33 | 34 | # Returns a hash with page numbers as keys and page results as values 35 | def get_result_pages(page_nos, options = {}) 36 | pages = {} 37 | page_nos.map(&:to_i).each do |page_no| 38 | pages[page_no] = get_result_page(page_no, options) 39 | end 40 | pages 41 | end 42 | 43 | def get_results(start, stop, options = {}) 44 | raise "Implement in subclasses" 45 | end 46 | 47 | def count 48 | raise "Implement in subclasses" 49 | end 50 | 51 | def get_total_corpus_part_count(parts) 52 | query = queries.first['query'].gsub('"', '') 53 | self.num_hits = 0 54 | 55 | parts.each_with_index do |part, index| 56 | self.num_hits += corpus_part_counts[index] ||= get_corpus_part_count(part, query) 57 | end 58 | save! # In case we made any new corpus part counts 59 | 60 | num_hits 61 | end 62 | 63 | def page_size 64 | # TODO: Get this from the user's preferences or something 65 | 15 66 | end 67 | 68 | def get_corpus_part_count(part, query) 69 | raise "Implement this method in a subclass if you use multipart corpora" 70 | end 71 | 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /app/models/rglossa/search_types.rb: -------------------------------------------------------------------------------- 1 | module Rglossa::SearchEngines 2 | def self.table_name_prefix 3 | 'search_engines_' 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/models/rglossa/speech/speaker.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | module Speech 3 | class Speaker < ::Rglossa::CorpusText 4 | 5 | class << self 6 | 7 | ######## 8 | private 9 | ######## 10 | 11 | # Overrides the one in CorpusText 12 | def position_field_str 13 | 'positions' 14 | end 15 | 16 | # Overrides the one in CorpusText 17 | def run_query(sql) 18 | connection.select_values(sql) 19 | end 20 | 21 | # Overrides the one in CorpusText 22 | def write_positions(filename, conditions, sql) 23 | sql << " WHERE #{conditions.join(" AND ")} AND positions IS NOT NULL" 24 | rows = run_query(sql) 25 | 26 | # in Speaker, each row contains a string with a set of dash-separated start and end 27 | # positions that need to be split and spaces replaced by newlines. Unlike with CorpusText 28 | # we cannot ask MySQL to write directly to outfile since we need to do this processing 29 | # first. 30 | rows.map! { |row| row.gsub(/\s+/, "\n").gsub(/-/, "\t") } 31 | File.write(filename, rows.join("\n")) 32 | end 33 | 34 | end 35 | 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /app/models/rglossa/speech/waveform_player.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | module Speech 3 | 4 | class WaveformPlayer 5 | def self.conf_path 6 | Rails.root.join('config/waveforms.json').to_s 7 | end 8 | 9 | def self.conf 10 | JSON.parse(File.read(self.conf_path)) 11 | end 12 | end 13 | 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /app/models/rglossa/user.rb: -------------------------------------------------------------------------------- 1 | class Rglossa::User < ActiveRecord::Base 2 | self.table_name = "rglossa_users" 3 | # Include default devise modules. Others available are: 4 | # :token_authenticatable, :confirmable, 5 | # :lockable, :timeoutable and :omniauthable 6 | devise :database_authenticatable, :registerable, 7 | :recoverable, :rememberable, :trackable, :validatable 8 | 9 | # Setup accessible (or protected) attributes for your model 10 | attr_accessible :email, :password, :password_confirmation, :remember_me 11 | # attr_accessible :title, :body 12 | has_many :access_permissions 13 | has_many :corpora, through: :access_permissions 14 | end 15 | -------------------------------------------------------------------------------- /app/views/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/app/views/.keep -------------------------------------------------------------------------------- /app/views/front/index.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Glossa 5 | <%= csrf_meta_tag %> 6 | <%= stylesheet_link_tag 'bootstrap-2.3.1/bootstrap' %> 7 | 8 | 9 |
    10 |
    11 |
    12 |
    <%= image_tag "clarin.png", class: "pull-right", style: "height: 100px; margin-bottom: 10px;" %>
    13 |
    14 |
    15 |
    16 |

    Glossa

    17 |

    Corpus search and results handling system

    18 |
    19 | 24 | 25 |

    Demo corpora

    26 | 33 | 34 |
    35 |
    36 |
    37 | 38 | 39 | -------------------------------------------------------------------------------- /app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Glossa 5 | 8 | 9 | <%= csrf_meta_tag %> 10 | 11 | 12 | <%= stylesheet_link_tag 'application' %> 13 | 14 | 28 | 29 | 30 | 31 | <%= javascript_include_tag asset_path('cljs/app.js') %> 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/views/rglossa/corpora/index.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Glossa 5 | 8 | 9 | <%= csrf_meta_tag %> 10 | 11 | 12 | 15 | 16 | 17 | <%= javascript_include_tag 'application' %> 18 | <% if flash[:msg] %><%= flash[:msg] %>
    <% end %> 19 | Upload corpus: 20 | <%= form_tag({controller: :corpora, action: :upload}, multipart: true) do %> 21 | <%= file_field_tag 'corpus' %> 22 | <%= submit_tag %> 23 | <% end %> 24 |

    25 | Available corpora: 26 |

      27 | <% @corpora.each do |c| %> 28 |
    • <%= link_to c.name, controller: 'home', corpus: c.code %> 29 | <%= link_to 'Delete', "corpora/#{c.rid}", :confirm => 'Are you sure?', :method => :delete %> 30 | <% end %> 31 |
    32 | 33 | 34 | -------------------------------------------------------------------------------- /app/views/rglossa/home/index.html.erb: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/views/rglossa/searches/create.html.erb: -------------------------------------------------------------------------------- 1 |

    Searches#create

    2 |

    Find me in app/views/searches/create.html.erb

    3 | -------------------------------------------------------------------------------- /app/views/rglossa/searches/destroy.html.erb: -------------------------------------------------------------------------------- 1 |

    Searches#destroy

    2 |

    Find me in app/views/searches/destroy.html.erb

    3 | -------------------------------------------------------------------------------- /app_template.rb: -------------------------------------------------------------------------------- 1 | def install_devise 2 | generate("devise:install") 3 | 4 | devise_sender = ask("Please provide a sender e-mail address to use when sending info to users " + 5 | "(in the case of a lost password etc.). Can be changed later in " + 6 | "config/initializers/devise.rb:") 7 | 8 | gsub_file("config/initializers/devise.rb", 9 | /(config.mailer_sender = ").+?"/, 10 | %Q(\\1#{devise_sender}")) 11 | end 12 | 13 | 14 | def configure_react(environment) 15 | insert_into_file("config/environments/#{environment}.rb", 16 | "\n" + 17 | " config.react.variant = :#{environment}\n" + 18 | " config.react.addons = true\n", 19 | after: "# Settings specified here will take precedence over those in config/application.rb\n") 20 | end 21 | 22 | 23 | ############## 24 | # Main script 25 | ############## 26 | 27 | gem "rglossa", github: "textlab/rglossa" 28 | gem "devise", "~> 2.2.3" 29 | gem "therubyracer" 30 | gem "thin" 31 | gem "react-rails" 32 | 33 | run "bundle install" 34 | 35 | rake("rglossa:install:copy_files") 36 | 37 | run "rm public/index.html" 38 | 39 | route "mount Rglossa::Engine => '/'" 40 | 41 | rake("railties:install:migrations") 42 | 43 | rake("rglossa:install:thor") 44 | 45 | install_devise 46 | 47 | rake("db:migrate") 48 | 49 | insert_into_file("app/assets/stylesheets/application.css", 50 | " *= require rglossa/application\n", 51 | after: "*= require_self\n") 52 | 53 | insert_into_file("config/application.rb", 54 | "\n # Silence deprecation notice from i18n\n" + 55 | " config.i18n.enforce_available_locales = true\n", 56 | after: "config.assets.version = '1.0'\n") 57 | 58 | configure_react("development") 59 | configure_react("production") 60 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. 3 | 4 | ENGINE_ROOT = File.expand_path('../..', __FILE__) 5 | ENGINE_PATH = File.expand_path('../../lib/rglossa/engine', __FILE__) 6 | 7 | require 'rails/all' 8 | require 'rails/engine/commands' 9 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cglossa", 3 | "version": "0.0.0", 4 | "authors": [ 5 | "Anders Nøklestad " 6 | ], 7 | "license": "MIT", 8 | "ignore": [ 9 | "**/.*", 10 | "node_modules", 11 | "bower_components", 12 | "test", 13 | "tests" 14 | ], 15 | "dependencies": { 16 | "react-select": "~0.6.7" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /build_docker_image.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | if [ "$1" = "--full" ]; then 5 | bundle update 6 | else 7 | bundle update --source rglossa rglossa-r rglossa-fcs 8 | fi 9 | rake railties:install:migrations # installs migrations for all engines 10 | rake rglossa:install:thor 11 | 12 | rm_dockerfile() { 13 | if [ -h Dockerfile ]; then rm -f Dockerfile; fi 14 | } 15 | 16 | docker_build() { 17 | rm_dockerfile 18 | ln -s Dockerfile.$1 Dockerfile || exit 1 19 | docker build -t textlab/$1 . || { rm -f Dockerfile; exit 1; } 20 | } 21 | 22 | if [ "$1" = "--full" ]; then 23 | docker_build glossa-data 24 | docker_build glossa-base 25 | fi 26 | docker_build glossa 27 | rm_dockerfile 28 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Glossa2::Application 5 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | 3 | # Set up gems listed in the Gemfile. 4 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 5 | 6 | require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) 7 | -------------------------------------------------------------------------------- /config/cwb.example: -------------------------------------------------------------------------------- 1 | # config/cwb.yml 2 | development: 3 | registry: "/Users/stinky/Documents/tekstlab/glossa-arabisk-test-corpus/reg/" 4 | cwb_bin_path: '/Users/stinky/Documents/tekstlab/cwb/bin/' 5 | 6 | test: 7 | registry: "test/cwb_test_data/reg" 8 | cwb_bin_path: '/Users/stinky/Documents/tekstlab/cwb/bin/' 9 | -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3 3 | # 4 | # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # gem 'sqlite3' 6 | # 7 | # To integrate Glossa with the Docker MySQL container, the following code may be used: 8 | # db = URI.parse(ENV['DATABASE_URL'] || 9 | # 'mysql2://root:%s@mysql:%d/glossa' % [URI.encode(ENV['MYSQL_ENV_MYSQL_ROOT_PASSWORD'] || ''), 10 | # ENV['MYSQL_PORT_3306_TCP_PORT'] || 3306]) 11 | 12 | development: &DEFAULT 13 | <% db = URI.parse(ENV['DATABASE_URL'] || 'sqlite3:///db/development.sqlite3') %> 14 | adapter: <%= db.scheme %> 15 | host: <%= db.host %> 16 | port: <%= db.port %> 17 | database: <%= URI.decode db.path[1..-1] || "" %> 18 | username: <%= URI.decode db.user || "" %> 19 | password: <%= URI.decode db.password || "" %> 20 | encoding: utf8 21 | pool: 5 22 | timeout: 5000 23 | 24 | # Warning: The database defined as "test" will be erased and 25 | # re-generated from your development database when you run "rake". 26 | # Do not set this db to the same as development or production. 27 | test: 28 | adapter: sqlite3 29 | database: db/test.sqlite3 30 | pool: 5 31 | timeout: 5000 32 | 33 | production: 34 | <<: *DEFAULT 35 | 36 | oldglossa: 37 | <% old_db = URI.parse ENV['OLD_GLOSSA_DB_URL'] || "" %> 38 | adapter: <%= old_db.scheme %> 39 | host: <%= old_db.host %> 40 | port: <%= old_db.port %> 41 | database: <%= URI.decode old_db.path[1..-1] || "" %> 42 | username: <%= URI.decode old_db.user || "" %> 43 | password: <%= URI.decode old_db.password || "" %> 44 | encoding: utf8 45 | pool: 5 46 | timeout: 5000 47 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the rails application 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the rails application 5 | Glossa2::Application.initialize! 6 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | require 'react-rails' 2 | 3 | Glossa2::Application.configure do 4 | # Settings specified here will take precedence over those in config/application.rb 5 | 6 | # In the development environment your application's code is reloaded on 7 | # every request. This slows down response time but is perfect for development 8 | # since you don't have to restart the web server when you make code changes. 9 | config.cache_classes = false 10 | 11 | # Log error messages when you accidentally call methods on nil. 12 | config.whiny_nils = true 13 | 14 | # Show full error reports and disable caching 15 | config.consider_all_requests_local = true 16 | config.action_controller.perform_caching = false 17 | 18 | # Don't care if the mailer can't send 19 | config.action_mailer.raise_delivery_errors = false 20 | 21 | # Print deprecation notices to the Rails logger 22 | config.active_support.deprecation = :log 23 | 24 | # Only use best-standards-support built into browsers 25 | config.action_dispatch.best_standards_support = :builtin 26 | 27 | # Raise exception on mass assignment protection for Active Record models 28 | config.active_record.mass_assignment_sanitizer = :strict 29 | 30 | # Log the query plan for queries taking more than this (works 31 | # with SQLite, MySQL, and PostgreSQL) 32 | config.active_record.auto_explain_threshold_in_seconds = 0.5 33 | 34 | # Do not compress assets 35 | config.assets.compress = false 36 | 37 | # Expands the lines which load the assets 38 | config.assets.debug = true 39 | 40 | config.react.variant = :development 41 | config.react.addons = true 42 | end 43 | 44 | silence_warnings do 45 | require "pry" 46 | IRB = Pry 47 | end 48 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Glossa2::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Configure static asset server for tests with Cache-Control for performance 11 | config.serve_static_assets = true 12 | config.static_cache_control = "public, max-age=3600" 13 | 14 | # Log error messages when you accidentally call methods on nil 15 | config.whiny_nils = true 16 | 17 | # Show full error reports and disable caching 18 | config.consider_all_requests_local = true 19 | config.action_controller.perform_caching = false 20 | 21 | # Raise exceptions instead of rendering exception templates 22 | config.action_dispatch.show_exceptions = false 23 | 24 | # Disable request forgery protection in test environment 25 | config.action_controller.allow_forgery_protection = false 26 | 27 | # Tell Action Mailer not to deliver emails to the real world. 28 | # The :test delivery method accumulates sent emails in the 29 | # ActionMailer::Base.deliveries array. 30 | config.action_mailer.delivery_method = :test 31 | 32 | # Raise exception on mass assignment protection for Active Record models 33 | config.active_record.mass_assignment_sanitizer = :strict 34 | 35 | # Print deprecation notices to the stderr 36 | config.active_support.deprecation = :stderr 37 | end 38 | -------------------------------------------------------------------------------- /config/i18n-js.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/config/i18n-js.yml -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format 4 | # (all these examples are active by default): 5 | ActiveSupport::Inflector.inflections do |inflect| 6 | # inflect.plural /^(ox)$/i, '\1en' 7 | # inflect.singular /^(ox)en/i, '\1' 8 | # inflect.irregular 'person', 'people' 9 | # inflect.uncountable %w( fish sheep ) 10 | inflect.irregular 'corpus', 'corpora' 11 | inflect.irregular 'subcorpus', 'subcorpora' 12 | end 13 | # 14 | # These inflection rules are supported but not enabled by default: 15 | # ActiveSupport::Inflector.inflections do |inflect| 16 | # inflect.acronym 'RESTful' 17 | # end 18 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | # Mime::Type.register_alias "text/html", :iphone 6 | -------------------------------------------------------------------------------- /config/initializers/rglossa.rb: -------------------------------------------------------------------------------- 1 | require 'i18n-js' 2 | 3 | Rails.application.config.assets.paths << 4 | SimplesIdeias::I18n::Engine.root.join('vendor', 'assets', 'javascripts').to_s 5 | 6 | 7 | module Rglossa 8 | @taggers = {} 9 | 10 | Dir.glob(Rails.root.join('config', 'taggers', '*.json')) do |filename| 11 | tagger = File.basename(filename, '.json') 12 | @taggers[tagger] = JSON.parse(File.read(filename)) 13 | end 14 | Dir.glob(Rails.root.join('config', 'taggers', '*.yml')) do |filename| 15 | tagger = File.basename(filename, '.yml') 16 | @taggers[tagger] = YAML.load_file(filename) 17 | end 18 | 19 | def self.taggers 20 | @taggers 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /config/initializers/secret_token.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | # Make sure the secret is at least 30 characters and all random, 6 | # no regular words or you'll be exposed to dictionary attacks. 7 | Glossa2::Application.config.secret_token = 'a21887dd74e9f2ff55f7bfeefab34c609ddf9e59ac3efb7d4505138483b6eea32749ab58811fde9fe675ead97f98ae3dc030151fbc88e58988dc322d218a5432' 8 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Glossa2::Application.config.session_store :cookie_store, key: '_glossa2_session' 4 | 5 | # Use the database for sessions instead of the cookie-based default, 6 | # which shouldn't be used to store highly confidential information 7 | # (create the session table with "rails generate session_migration") 8 | # Glossa2::Application.config.session_store :active_record_store 9 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | # 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | 11 | # Disable root element in JSON by default. 12 | ActiveSupport.on_load(:active_record) do 13 | self.include_root_in_json = false 14 | end 15 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | rglossa: 3 | save: 'Save' 4 | search: 'Search' 5 | 6 | navbar: 7 | my_results: 'My results' 8 | log_out: 'Log out' 9 | 10 | search_results: 11 | annotate: 'Annotate' 12 | statistics: 'Statistics' 13 | metadata: 'Metadata' 14 | -------------------------------------------------------------------------------- /config/locales/nb.yml: -------------------------------------------------------------------------------- 1 | nb: 2 | rglossa: 3 | save: 'Lagre' 4 | search: 'Søk' 5 | 6 | navbar: 7 | my_results: 'Mine resultater' 8 | log_out: 'Logg ut' 9 | 10 | search_results: 11 | annotate: 'Annotér' 12 | statistics: 'Statistikk' 13 | metadata: 'Metadata' 14 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Glossa2::Application.routes.draw do 2 | match 'front', to: 'front#index' 3 | scope module: 'rglossa' do 4 | devise_for :users, :class_name => "Rglossa::User", module: :devise 5 | 6 | root :to => 'home#index' 7 | get 'admin', to: 'corpora#index' 8 | 9 | resources :corpora do 10 | collection do 11 | get 'find_by' 12 | post 'upload' 13 | end 14 | member do 15 | get 'cimdi' 16 | end 17 | end 18 | 19 | resources :metadata_values 20 | 21 | resources :metadata_categories do 22 | resources :metadata_values 23 | end 24 | 25 | namespace :search_engines do 26 | # Add more search types to the resource list as they are implemented, e.g. 27 | # resources :cwb_searches, :corpuscle_searches, :annis2_searches do 28 | resources :cwb_searches do 29 | member do 30 | get 'results' 31 | get 'count' 32 | end 33 | end 34 | end 35 | 36 | namespace :r do 37 | namespace :search_engines do 38 | match 'cwb/query_freq', to: 'cwb#query_freq' 39 | end 40 | end 41 | 42 | resources :saml, only: [] do 43 | collection do 44 | get :sso 45 | post :acs 46 | get :metadata 47 | get :logout 48 | end 49 | end 50 | 51 | get 'login/:idp' => 'saml#sso' 52 | post 'auth/:idp' => 'saml#acs' 53 | get 'logout/:idp' => 'saml#logout' 54 | get 'saml/metadata/:idp' => 'saml#metadata' 55 | 56 | post '(:idp)_auth' => 'saml#acs' 57 | get 'logout_(:idp)_user' => 'saml#logout' 58 | 59 | scope module: 'speech' do 60 | get '/wfplayer-:corpus_id-:line_key-:start-:stop(-:oldstart-:oldstop(-:width))', to: 'waveform_player#show', 61 | :constraints => {:start => /\d+(\.\d+)?/, :stop => /\d+(\.\d+)?/, :width => /\d+/, 62 | :oldstart => /\d+(\.\d+)?/, :oldstop => /\d+(\.\d+)?/} 63 | namespace :search_engines do 64 | # Add more search types to the resource list as they are implemented, e.g. 65 | # resources :cwb_searches, :corpuscle_searches, :annis2_searches do 66 | resources :speech_cwb_searches do 67 | member do 68 | get 'results' 69 | get 'count' 70 | get 'geo_distr' 71 | end 72 | end 73 | end 74 | end 75 | end 76 | end 77 | -------------------------------------------------------------------------------- /config/taggers/oromo.yml: -------------------------------------------------------------------------------- 1 | description: Oromo tags developed by the Ethiopian Languages Research Center at Addis Ababa University 2 | displayAttrs: [part-of-speech] 3 | 4 | tags: 5 | attr: pos 6 | name: part-of-speech 7 | options: 8 | - name: N 9 | value: N 10 | - name: V 11 | value: V 12 | - name: PRON 13 | value: PRON 14 | - name: ADJ 15 | value: ADJ 16 | - name: DET 17 | value: DET 18 | - name: POSTP 19 | value: POSTP 20 | - name: PREP 21 | value: PREP 22 | - name: COP 23 | value: COP 24 | - name: RELT 25 | value: RELT 26 | - name: CONJ 27 | value: CONJ 28 | - name: PARTICLE 29 | value: PARTICLE 30 | - name: NEG 31 | value: NEG 32 | - name: NUM 33 | value: NUM 34 | - name: ADV 35 | value: ADV 36 | - name: RELAT 37 | value: RELAT 38 | - name: POST 39 | value: POST 40 | - name: NUMB 41 | value: NUMB 42 | - name: QUANT 43 | value: QUANT 44 | - name: PROP 45 | value: PROP 46 | - name: PRO 47 | value: PRO 48 | - name: POETP 49 | value: POETP 50 | - name: POS 51 | value: POS 52 | - name: OSTP 53 | value: OSTP 54 | - name: RON 55 | value: RON 56 | - name: DEM 57 | value: DEM 58 | - name: SDV 59 | value: SDV 60 | - name: ADN 61 | value: ADN 62 | - name: NRG 63 | value: NRG 64 | - name: RRON 65 | value: RRON 66 | - name: ET 67 | value: ET 68 | - name: DJ 69 | value: DJ 70 | - name: POSP 71 | value: POSP 72 | - name: ONJ 73 | value: ONJ 74 | - name: OP 75 | value: OP 76 | -------------------------------------------------------------------------------- /config/trinidad.yml: -------------------------------------------------------------------------------- 1 | --- 2 | port: 61054 3 | address: 0.0.0.0 4 | jruby_min_runtimes: 3 5 | jruby_max_runtimes: 3 6 | web_apps: 7 | default: 8 | root_dir: '.' 9 | context_path: <%= ENV['RAILS_RELATIVE_URL_ROOT'] %> 10 | -------------------------------------------------------------------------------- /config/waveforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "snack_dir": "/usr/local", 3 | "tcl_dir": "/usr/lib64:/usr/lib:/usr/lib/tcl8.5:/usr/lib/tcl8.4", 4 | "tk_dir": "/usr/lib64:/usr/lib:/usr/lib/tk8.5:/usr/lib/tk8.4", 5 | "output_dir": "tmp_waveforms", 6 | "pid_file": "tmp/pids/genwaveform.pid", 7 | "log_file": "log/genwaveform.log", 8 | "sock_file": "tmp/sockets/genwaveform.sock", 9 | "pixels_per_second": 216, 10 | "waveform_height": 72, 11 | "total_height": 216 12 | } 13 | -------------------------------------------------------------------------------- /db/migrate/20130904181612_create_rglossa_corpora.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20091203090812) 2 | class CreateRglossaCorpora < ActiveRecord::Migration 3 | def up 4 | create_table :rglossa_corpora do |t| 5 | t.string :name, null: false 6 | t.string :short_name # optional "code" used by e.g. CWB 7 | 8 | # it might be a good idea to set this if the corpus is very big: 9 | t.integer :default_max_hits 10 | 11 | t.timestamps 12 | end 13 | 14 | Rglossa::Corpus.create_translation_table!(name: :string) 15 | end 16 | 17 | def down 18 | drop_table :rglossa_corpora 19 | Rglossa::Corpus.drop_translation_table! 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /db/migrate/20130904181613_create_rglossa_metadata_categories.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20091205210334) 2 | class CreateRglossaMetadataCategories < ActiveRecord::Migration 3 | def up 4 | create_table :rglossa_metadata_categories do |t| 5 | t.belongs_to :corpus, null: false 6 | t.string :short_name, null: false 7 | t.string :category_type, null: false 8 | t.string :value_type, null: false 9 | 10 | t.timestamps 11 | 12 | Rglossa::MetadataCategory.create_translation_table!(name: :string) 13 | end 14 | 15 | def down 16 | drop_table :rglossa_metadata_categories 17 | Rglossa::MetadataCategory.drop_translation_table! 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /db/migrate/20130904181614_create_rglossa_searches.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20091206173444) 2 | class CreateRglossaSearches < ActiveRecord::Migration 3 | def change 4 | create_table :rglossa_searches do |t| 5 | t.integer :user_id, null: false 6 | t.string :type 7 | t.text :queries, null: false 8 | t.text :search_options 9 | t.text :metadata_value_ids 10 | t.integer :num_hits 11 | 12 | t.timestamps 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /db/migrate/20130904181615_create_rglossa_corpus_texts.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20091209231651) 2 | class CreateRglossaCorpusTexts < ActiveRecord::Migration 3 | def change 4 | create_table :rglossa_corpus_texts do |t| 5 | t.integer :startpos, limit: 8 # limit = 8 means bigint 6 | t.integer :endpos, limit: 8 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20130904181616_create_rglossa_metadata_values.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20091223175749) 2 | class CreateRglossaMetadataValues < ActiveRecord::Migration 3 | def change 4 | create_table :rglossa_metadata_values do |t| 5 | t.belongs_to :metadata_category, null: false 6 | t.string :type, null: false 7 | t.text :text_value 8 | t.integer :integer_value 9 | t.boolean :boolean_value 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /db/migrate/20130904181617_create_rglossa_deleted_hits.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20100108140812) 2 | class CreateRglossaDeletedHits < ActiveRecord::Migration 3 | def change 4 | create_table :rglossa_deleted_hits do |t| 5 | t.integer :search_id, null: false 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20130904181618_add_join_table_for_corpus_text_and_metadata_value.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20121110003219) 2 | class AddJoinTableForCorpusTextAndMetadataValue < ActiveRecord::Migration 3 | def change 4 | create_table :rglossa_corpus_texts_metadata_values do |t| 5 | t.belongs_to :rglossa_corpus_text, null: false 6 | t.belongs_to :rglossa_metadata_value, null: false 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20130904181619_devise_create_rglossa_users.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20130318185404) 2 | class DeviseCreateRglossaUsers < ActiveRecord::Migration 3 | def change 4 | create_table(:rglossa_users) do |t| 5 | ## Database authenticatable 6 | t.string :email, :null => false, :default => "" 7 | t.string :encrypted_password, :null => false, :default => "" 8 | 9 | ## Recoverable 10 | t.string :reset_password_token 11 | t.datetime :reset_password_sent_at 12 | 13 | ## Rememberable 14 | t.datetime :remember_created_at 15 | 16 | ## Trackable 17 | t.integer :sign_in_count, :default => 0 18 | t.datetime :current_sign_in_at 19 | t.datetime :last_sign_in_at 20 | t.string :current_sign_in_ip 21 | t.string :last_sign_in_ip 22 | 23 | ## Confirmable 24 | # t.string :confirmation_token 25 | # t.datetime :confirmed_at 26 | # t.datetime :confirmation_sent_at 27 | # t.string :unconfirmed_email # Only if using reconfirmable 28 | 29 | ## Lockable 30 | # t.integer :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts 31 | # t.string :unlock_token # Only if unlock strategy is :email or :both 32 | # t.datetime :locked_at 33 | 34 | ## Token authenticatable 35 | # t.string :authentication_token 36 | 37 | 38 | t.timestamps 39 | end 40 | 41 | add_index :rglossa_users, :email, :unique => true 42 | add_index :rglossa_users, :reset_password_token, :unique => true 43 | # add_index :rglossa_users, :confirmation_token, :unique => true 44 | # add_index :rglossa_users, :unlock_token, :unique => true 45 | # add_index :rglossa_users, :authentication_token, :unique => true 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /db/migrate/20130904181620_add_corpus_id_to_corpus_text.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20130423174400) 2 | class AddCorpusIdToCorpusText < ActiveRecord::Migration 3 | def change 4 | # Breaks db normalization, but lets us list the texts belonging to a corpus without going 5 | # through corpus->metadata_categories->metadata_values->corpus_texts 6 | add_column :rglossa_corpus_texts, :corpus_id, :integer 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /db/migrate/20130904181621_add_encoding_to_corpus.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20130424025423) 2 | class AddEncodingToCorpus < ActiveRecord::Migration 3 | def change 4 | add_column :rglossa_corpora, :encoding, :string, default: 'utf-8' 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20130904181622_add_max_hits_to_search.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20130730095239) 2 | class AddMaxHitsToSearch < ActiveRecord::Migration 3 | def change 4 | add_column :rglossa_searches, :max_hits, :integer 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20130904181623_remove_default_max_hits_from_corpus.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20130802121247) 2 | class RemoveDefaultMaxHitsFromCorpus < ActiveRecord::Migration 3 | def change 4 | remove_column :rglossa_corpora, :default_max_hits 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20130904181624_add_config_to_corpus.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20130803192831) 2 | class AddConfigToCorpus < ActiveRecord::Migration 3 | def change 4 | add_column :rglossa_corpora, :config, :text 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20130908211800_add_logo_to_corpus.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20130908211716) 2 | class AddLogoToCorpus < ActiveRecord::Migration 3 | def change 4 | add_column :rglossa_corpora, :logo, :string 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20130908223643_add_search_engine_to_corpus.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20130908223618) 2 | class AddSearchEngineToCorpus < ActiveRecord::Migration 3 | def change 4 | add_column :rglossa_corpora, :search_engine, :string 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20131014230038_add_index_on_metadata_category_id.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20130910221355) 2 | class AddIndexOnMetadataCategoryId < ActiveRecord::Migration 3 | def change 4 | add_index :rglossa_metadata_values, :metadata_category_id 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20131014230039_set_num_hits_to_zero.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20131014225856) 2 | class SetNumHitsToZero < ActiveRecord::Migration 3 | def up 4 | change_column :rglossa_searches, :num_hits, :integer, null: false, default: 0 5 | end 6 | 7 | def down 8 | change_column :rglossa_searches, :num_hits, :integer 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20131015205819_add_corpus_part_counts_to_search.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20131015142228) 2 | class AddCorpusPartCountsToSearch < ActiveRecord::Migration 3 | def change 4 | add_column :rglossa_searches, :corpus_part_counts, :text, null: false, default: '' 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20140226133446_add_type_to_corpus_text.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20140226133000) 2 | class AddTypeToCorpusText < ActiveRecord::Migration 3 | def change 4 | add_column :rglossa_corpus_texts, :type, :string 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20140715154830_add_corpus_short_name_to_search.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20140715154548) 2 | class AddCorpusShortNameToSearch < ActiveRecord::Migration 3 | def change 4 | add_column :rglossa_searches, :corpus_short_name, :string 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20140916203917_add_positions_to_corpus_text.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20140831235817) 2 | class AddPositionsToCorpusText < ActiveRecord::Migration 3 | def change 4 | add_column :rglossa_corpus_texts, :positions, :text 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20140916203918_create_rglossa_media_files.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20140908111628) 2 | class CreateRglossaMediaFiles < ActiveRecord::Migration 3 | def up 4 | create_table :rglossa_media_files do |t| 5 | t.belongs_to :corpus, null: false 6 | t.integer :line_key_begin, null: false 7 | t.integer :line_key_end, null: false 8 | t.string :basename, null: false 9 | end 10 | end 11 | 12 | def down 13 | drop_table :rglossa_media_files 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /db/migrate/20141127013945_add_cimdi_to_corpora.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20141127012945) 2 | class AddCimdiToCorpora < ActiveRecord::Migration 3 | def change 4 | add_column :rglossa_corpora, :cimdi, :text 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20150414151848_create_access_permissions.rb: -------------------------------------------------------------------------------- 1 | class CreateAccessPermissions < ActiveRecord::Migration 2 | def change 3 | create_table :rglossa_access_permissions do |t| 4 | t.belongs_to :user, index: true, null: false 5 | t.belongs_to :corpus, index: true, null: false 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /db/migrate/20150415123131_add_admin_to_users.rb: -------------------------------------------------------------------------------- 1 | class AddAdminToUsers < ActiveRecord::Migration 2 | def change 3 | add_column :rglossa_users, :admin, :boolean, :default => false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should contain all the record creation needed to seed the database with its default values. 2 | # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). 3 | # 4 | # Examples: 5 | # 6 | # cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) 7 | # Mayor.create(name: 'Emanuel', city: cities.first) 8 | -------------------------------------------------------------------------------- /doc/README_FOR_APP: -------------------------------------------------------------------------------- 1 | Use this README file to introduce your application and point to useful places in the API for learning more. 2 | Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries. 3 | -------------------------------------------------------------------------------- /lib/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/lib/assets/.gitkeep -------------------------------------------------------------------------------- /lib/assets/cljs/cglossa/app.cljs: -------------------------------------------------------------------------------- 1 | (ns cglossa.app 2 | (:require [cglossa.left :refer [metadata-list]] 3 | [cglossa.start :refer [start]] 4 | [cglossa.results :refer [results]] 5 | [cglossa.react-adapters.bootstrap :as b])) 6 | 7 | (defn- header [] 8 | [b/navbar {:fixedTop true :brand "Glossa"}]) 9 | 10 | (defn- main-area [{{:keys [show?]} :results-view :as a} m] 11 | [:div#page-content-wrapper 12 | [:div.container-fluid {:style {:padding-left 50}} 13 | [:div.row>div#main-content.col-sm-12 14 | (if @show? 15 | [results a m] 16 | [start a m])]]]) 17 | 18 | (defn app [{:keys [showing-sidebar? narrow-view?] :as a} {:keys [corpus] :as m}] 19 | (let [cls (if (empty? (:metadata-categories @corpus)) "span12" "span9")] 20 | [:div 21 | [header] 22 | (when @corpus 23 | [:div#wrapper {:class-name (when (or @showing-sidebar? (not @narrow-view?)) "toggled")} 24 | [metadata-list a m] 25 | [main-area a m]]) 26 | [:div.app-footer>img.textlab-logo {:src "img/tekstlab.gif"}]])) 27 | -------------------------------------------------------------------------------- /lib/assets/cljs/cglossa/left.cljs: -------------------------------------------------------------------------------- 1 | (ns cglossa.left 2 | (:require [reagent.core :as r] 3 | [cglossa.react-adapters.bootstrap :as b] 4 | [cglossa.select2 :as s])) 5 | 6 | (def auto-opening-select (with-meta s/select2 {:component-did-mount #(s/trigger-event % "open")})) 7 | 8 | (defn metadata-list [{:keys [open-metadata-cat]} {:keys [search metadata-categories]}] 9 | [:div#sidebar-wrapper 10 | (doall 11 | (for [cat @metadata-categories 12 | :let [cat-id (:rid cat) 13 | open? (or (= @open-metadata-cat cat-id) 14 | (get @search cat-id))]] 15 | ^{:key cat-id} 16 | [:div.metadata-category 17 | [:a {:href "#" :on-click (fn [e] 18 | (reset! open-metadata-cat (if open? nil cat-id)) 19 | (.preventDefault e))} 20 | (:name cat)] 21 | (when open? 22 | (list 23 | ^{:key (str "close-btn" cat-id)} 24 | [b/button {:bs-size "xsmall" 25 | :bs-style "danger" 26 | :title "Remove selection" 27 | :class-name "close-cat-btn" 28 | :on-click #(reset! open-metadata-cat nil)} 29 | [b/glyphicon {:glyph "remove"}]] 30 | ^{:key (str "select" cat-id)} 31 | [auto-opening-select (r/atom nil) (r/atom nil) {:placeholder "Click to select..."} 32 | [:div 33 | [:select.list {:style {:width "100%"} :multiple true}]]]))]))]) 34 | -------------------------------------------------------------------------------- /lib/assets/cljs/cglossa/react_adapters/bootstrap.clj: -------------------------------------------------------------------------------- 1 | (ns cglossa.react-adapters.bootstrap 2 | (:require [clojure.string :as str])) 3 | 4 | ;; This needs to be a macro in order for it to access the ReactBootstrap 5 | ;; JS object in the js namespace (or is there another way?). It will define a set of Vars 6 | ;; in the namespace where the macro is called, one for each of the listed Bootstrap 7 | ;; components and resulting from running reagent.core/adapt-react-class 8 | ;; on the component. The Var names will be lower-cased, for instance `button` for 9 | ;; js/ReactBootstrap.Button. 10 | (defmacro adapt! [& components] 11 | `(do ~@(for [c components] 12 | `(def ~(symbol (str/lower-case c)) 13 | (reagent.core/adapt-react-class ~(symbol "js" (str "ReactBootstrap." c))))))) 14 | -------------------------------------------------------------------------------- /lib/assets/cljs/cglossa/react_adapters/bootstrap.cljs: -------------------------------------------------------------------------------- 1 | (ns cglossa.react-adapters.bootstrap 2 | (:require cljsjs.react-bootstrap 3 | reagent.core) 4 | (:require-macros [cglossa.react-adapters.bootstrap :refer [adapt!]])) 5 | 6 | ;; This will define a set of Vars in the current namespace, one for each of the 7 | ;; listed Bootstrap components and resulting from running reagent.core/adapt-react-class 8 | ;; on the component. The Var names will be lower-cased, for instance `button` for 9 | ;; js/ReactBootstrap.Button, so they should be referred like this in other namespaces: 10 | ;; (:require [cglossa.react-adapters.bootstrap :refer [button modal label]) 11 | (adapt! "Button" 12 | "ButtonToolbar" 13 | "DropdownButton" 14 | "Glyphicon" 15 | "Input" 16 | "Label" 17 | "MenuItem" 18 | "Modal" 19 | "ModalBody" 20 | "ModalFooter" 21 | "ModalHeader" 22 | "ModalTitle" 23 | "Navbar" 24 | "TabbedArea" 25 | "Table" 26 | "TabPane") 27 | -------------------------------------------------------------------------------- /lib/assets/cljs/cglossa/result_views/cwb/core.cljs: -------------------------------------------------------------------------------- 1 | (ns cglossa.result-views.cwb.core 2 | (:require [clojure.string :as str] 3 | [cglossa.react-adapters.bootstrap :as b] 4 | [cglossa.results :refer [concordance-table]])) 5 | 6 | (defmulti concordance-rows 7 | "Multimethod that returns one or more rows representing a single search result." 8 | (fn [_ {corpus :corpus} _ _] (keyword (:search-engine @corpus)))) 9 | 10 | (defmethod concordance-table :default [{{:keys [results page-no]} :results-view :as a} m] 11 | (let [res (get @results @page-no)] 12 | [:div.row>div.col-sm-12.search-result-table-container 13 | [b/table {:striped true :bordered true} 14 | [:tbody 15 | (doall (map (partial concordance-rows a m) 16 | res 17 | (range (count res))))]]])) 18 | -------------------------------------------------------------------------------- /lib/assets/cljs/cglossa/result_views/cwb/shared.cljs: -------------------------------------------------------------------------------- 1 | (ns cglossa.result-views.cwb.shared) 2 | 3 | (defn id-column [result] 4 | ;; If the 'match' property is defined, we know that we have a result from a monolingual 5 | ;; search or the first language of a multilingual one. If that is the case, and s-id is 6 | ;; defined, we print it in the first column (if we have a non-first language result, we 7 | ;; will include it in the next column instead). 8 | (when (and (:match result) (:s-id result)) 9 | [:td (:s-id result)])) 10 | 11 | (defn text-columns [result] 12 | (if (:match result) 13 | ;; If the 'match' value is defined, we know that we have a result from a monolingual 14 | ;; search or the first language of a multilingual one, and then we want pre-match, match 15 | ;; and post-match in separate columns. 16 | (list ^{:key 0} [:td.left-context {:dangerouslySetInnerHTML {:__html (:pre-match result)}}] 17 | ^{:key 1} [:td.match {:dangerouslySetInnerHTML {:__html (:match result)}}] 18 | ^{:key 2} [:td.right-context {:dangerouslySetInnerHTML {:__html (:post-match result)}}]) 19 | ;; Otherwise, we have a result from a non-first language of a multilingual search. In that 20 | ;; case, CQP doesn't mark the match, so we leave the first column blank and put all of the 21 | ;; text in a single following column. 22 | (list [:td] 23 | [:td.aligned-text {:col-span 3 24 | :dangerouslySetInnerHTML {:__html (:pre-match result)}}]))) 25 | -------------------------------------------------------------------------------- /lib/assets/cljs/cglossa/result_views/cwb/written.cljs: -------------------------------------------------------------------------------- 1 | (ns cglossa.result-views.cwb.written 2 | (:require [clojure.string :as str] 3 | [cglossa.result-views.cwb.core :refer [concordance-rows]] 4 | [cglossa.result-views.cwb.shared :as shared])) 5 | 6 | (defn- monolingual-or-first-multilingual [res] 7 | (let [m (re-find #"<(\w+_(?:id|name))(.*?)>(.*)\{\{(.+?)\}\}(.*?)$" (:text res))] 8 | ;; There will only be a surrounding structural attribute if the corpus has some 9 | ;; kind of s-unit segmentation 10 | (if m 11 | (let [[_ _ s-id pre match post] m] 12 | [(str/trim s-id) [pre match post]]) 13 | ;; Try again without the surrounding structural attribute 14 | (let [m (re-find #"(.*)\{\{(.+?)\}\}(.*)" (:text res)) 15 | [_ pre match post] m] 16 | ["" [pre match post]])))) 17 | 18 | (defn- non-first-multilingual [res] 19 | ;; Extract the IDs of all s-units (typically sentences) 20 | ;; and put them in front of their respective s-units. 21 | (let [text (str/replace res 22 | #"<(\w+_id)\s*(.+?)>(.*?)" 23 | "$2: $3")] 24 | [nil [text]])) 25 | 26 | (defn- extract-fields [res] 27 | (let [m (re-find #"(.*)\{\{(.+?)\}\}(.*?)$" (:text res))] 28 | (let [[_ s-id pre match post] m] 29 | [(str/trim s-id) [pre match post]]))) 30 | 31 | (defn- main-row [result index a {:keys [corpus] :as m}] 32 | ^{:key (hash result)} 33 | [:tr 34 | (shared/id-column result) 35 | (shared/text-columns result)]) 36 | 37 | (defn- process-field [field] 38 | "Processes a pre-match, match, or post-match field." 39 | (as-> field $ 40 | (str/split $ #"\s+") 41 | (map #(first (str/split % #"/")) $) 42 | (str/join \space $))) 43 | 44 | (defmethod concordance-rows :default [a m res index] 45 | "Returns one or more rows representing a single search result." 46 | (let [[s-id fields] (extract-fields res) 47 | [pre match post] (map process-field fields) 48 | res-info {:s-id s-id 49 | :pre-match pre 50 | :match match 51 | :post-match post} 52 | main (main-row res-info index a m)] 53 | main)) 54 | -------------------------------------------------------------------------------- /lib/assets/cljs/cglossa/result_views/fcs/core.cljs: -------------------------------------------------------------------------------- 1 | (ns cglossa.result-views.fcs.core) 2 | -------------------------------------------------------------------------------- /lib/assets/cljs/cglossa/search_engines.cljs: -------------------------------------------------------------------------------- 1 | (ns cglossa.search-engines 2 | "Require namespaces containing implementations for various search engines 3 | here in order to register any multimethod implementations found in those 4 | namespaces." 5 | (:require cglossa.search-views.cwb.core 6 | cglossa.search-views.fcs.core 7 | cglossa.result-views.cwb.written 8 | cglossa.result-views.cwb.speech 9 | cglossa.result-views.fcs.core)) 10 | -------------------------------------------------------------------------------- /lib/assets/cljs/cglossa/search_views/fcs/core.cljs: -------------------------------------------------------------------------------- 1 | (ns cglossa.search-views.fcs.core) 2 | -------------------------------------------------------------------------------- /lib/assets/cljs/cglossa/search_views/shared.cljs: -------------------------------------------------------------------------------- 1 | (ns cglossa.search-views.shared) 2 | 3 | (defmulti search-inputs 4 | "Multimethod that accepts two arguments - an app state map and a 5 | model/domain state map - and dispatches to the correct method based 6 | on the value of :search-engine in the corpus map found in the 7 | model/domain state map. The :default case implements CWB support." 8 | (fn [_ {corpus :corpus}] (:search-engine @corpus))) 9 | -------------------------------------------------------------------------------- /lib/assets/cljs/cglossa/shared.cljs: -------------------------------------------------------------------------------- 1 | (ns cglossa.shared 2 | (:require [cglossa.react-adapters.bootstrap :as b])) 3 | 4 | (defn top-toolbar [{:keys [num-resets showing-sidebar? narrow-view?] {queries :queries} 5 | :search-view}] 6 | [:div.col-sm-5 7 | [b/buttontoolbar {:style {:margin-bottom 20}} 8 | (if @showing-sidebar? 9 | [b/button {:bs-size "xsmall" 10 | :title "Hide search criteria" 11 | :on-click (fn [e] 12 | (reset! showing-sidebar? false) 13 | (.preventDefault e))} 14 | "Hide filters"] 15 | [b/button {:bs-size "xsmall" 16 | :title "Show search criteria" 17 | :on-click (fn [e] 18 | (reset! showing-sidebar? true) 19 | (.preventDefault e))} 20 | "Filters"]) 21 | [b/button {:bs-style "primary" 22 | :bs-size "xsmall" 23 | :title "Reset form" 24 | :on-click (fn [] 25 | (reset! queries [{:query ""}]) 26 | (swap! num-resets inc))} ; see comments in the start component 27 | "Reset form"]]]) 28 | -------------------------------------------------------------------------------- /lib/assets/cljs/cglossa/start.cljs: -------------------------------------------------------------------------------- 1 | (ns cglossa.start 2 | (:require [cglossa.search-views.shared :refer [search-inputs]] 3 | [cglossa.shared :refer [top-toolbar]] 4 | [cglossa.react-adapters.bootstrap :as b])) 5 | 6 | (defn- corpus-info [_ {:keys [corpus]}] 7 | ;; Remove the background image (gradient, really) set by bootstrap-theme, 8 | ;; since the unthemed well is actually nicer. 9 | [:div.row.corpus-info>div.col-sm-12 10 | [:div.well {:style {:background-image "url()"}} 11 | [:h2 12 | (:name @corpus) 13 | (when-let [logo (:logo @corpus)] 14 | (let [logo-path (if (or (.startsWith logo "http:") (.startsWith logo "https:")) logo (str "img/" logo))] 15 | (.log js/console logo-path) 16 | [:img.corpus-logo {:src (str logo-path)}]))]]]) 17 | 18 | (defn start [{:keys [num-resets] :as a} m] 19 | [:div 20 | [:div.row 21 | [top-toolbar a]] 22 | [corpus-info a m] 23 | ;; Using num-resets as key is a hackish way to force reagent to 24 | ;; re-mount the currently selected search inputs each time the form 25 | ;; is reset and num-resets incremented. Since the text inputs are uncontrolled 26 | ;; (to prevent the cursor from jumping to the end when we edit them) 27 | ;; we need to re-mount them in order for them to set the new, blank 28 | ;; query as their value. 29 | ^{:key @num-resets} [search-inputs a m]]) 30 | -------------------------------------------------------------------------------- /lib/assets/stylesheets/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/lib/assets/stylesheets/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /lib/assets/stylesheets/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/lib/assets/stylesheets/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /lib/assets/stylesheets/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/lib/assets/stylesheets/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /lib/assets/stylesheets/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/lib/assets/stylesheets/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /lib/assets/stylesheets/simple-sidebar.css: -------------------------------------------------------------------------------- 1 | /* Modified version of Simple Sidebar */ 2 | /*! 3 | * Start Bootstrap - Simple Sidebar HTML Template (http://startbootstrap.com) 4 | * Code licensed under the Apache License v2.0. 5 | * For details, see http://www.apache.org/licenses/LICENSE-2.0. 6 | */ 7 | 8 | /* Toggle Styles */ 9 | 10 | #wrapper { 11 | padding-left: 0; 12 | -webkit-transition: all 0.5s ease; 13 | -moz-transition: all 0.5s ease; 14 | -o-transition: all 0.5s ease; 15 | transition: all 0.5s ease; 16 | } 17 | 18 | #wrapper.toggled { 19 | padding-left: 165px; 20 | } 21 | 22 | #sidebar-wrapper { 23 | padding-left: 10px; 24 | z-index: 1000; 25 | position: fixed; 26 | left: 165px; 27 | width: 0; 28 | height: 100%; 29 | margin-left: -165px; 30 | overflow-y: auto; 31 | -webkit-transition: all 0.5s ease; 32 | -moz-transition: all 0.5s ease; 33 | -o-transition: all 0.5s ease; 34 | transition: all 0.5s ease; 35 | } 36 | 37 | #wrapper.toggled #sidebar-wrapper { 38 | width: 165px; 39 | } 40 | 41 | #page-content-wrapper { 42 | width: 100%; 43 | position: absolute; 44 | padding: 15px; 45 | } 46 | 47 | #wrapper.toggled #page-content-wrapper { 48 | position: absolute; 49 | margin-right: -165px; 50 | } 51 | 52 | /* Sidebar Styles */ 53 | 54 | .sidebar-nav { 55 | position: absolute; 56 | top: 0; 57 | width: 165px; 58 | margin: 0; 59 | padding: 0; 60 | list-style: none; 61 | } 62 | 63 | .sidebar-nav li { 64 | text-indent: 20px; 65 | line-height: 40px; 66 | } 67 | 68 | .sidebar-nav li a { 69 | display: block; 70 | text-decoration: none; 71 | } 72 | 73 | .sidebar-nav li a:hover { 74 | text-decoration: none; 75 | background: rgba(255,255,255,0.2); 76 | } 77 | 78 | .sidebar-nav li a:active, 79 | .sidebar-nav li a:focus { 80 | text-decoration: none; 81 | } 82 | 83 | @media(max-width:768px) { 84 | #wrapper { 85 | padding-left: 165px; 86 | } 87 | 88 | #wrapper.toggled { 89 | padding-left: 0; 90 | } 91 | 92 | #sidebar-wrapper { 93 | width: 165px; 94 | } 95 | 96 | #wrapper.toggled #sidebar-wrapper { 97 | width: 0; 98 | } 99 | 100 | #page-content-wrapper { 101 | padding: 20px; 102 | position: relative; 103 | } 104 | 105 | #wrapper.toggled #page-content-wrapper { 106 | position: relative; 107 | margin-right: 0; 108 | } 109 | } -------------------------------------------------------------------------------- /lib/assets/stylesheets/style.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "mappings": "AAEA,IAAK;EACH,WAAW,EAAE,IAAI;EACjB,cAAc,EAAE,IAAI;;AAGtB,WAAY;EACV,MAAM,EAAE,IAAI;EACZ,QAAQ,EAAE,KAAK;EACf,MAAM,EAAE,GAAG;EACX,KAAK,EAAE,IAAI;EACX,gBAAgB,EAAE,OAAO;;AAG3B,yBAA0B;EACxB,KAAK,EAAE,KAAK;;AAGd,kBAAmB;EACjB,KAAK,EAAE,OAAO;EACd,WAAW,EAAE,MAAM;EACnB,MAAM,EAAE,OAAO;EAEf,kCAAkB;IAChB,WAAW,EAAE,IAAI;;AAIrB,YAAa;EACX,KAAK,EAAE,KAAK;EACZ,WAAW,EAAE,IAAI;;AAGnB,YAAa;EACX,aAAa,EAAE,IAAI;;AAGrB,iBAAkB;EAChB,WAAW,EAAE,IAAI;;AAGnB,iBAAkB;EAChB,UAAU,EAAE,GAAG;;AAGjB,sCAAuC;EACrC,UAAU,EAAE,KAAK;;AAGnB,wBAAyB;EACvB,gBAAgB,EAAE,sBAAsB;EACxC,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,WAAW,EAAE,KAAK;EAClB,UAAU,EAAE,IAAI;;AAGlB,mDAAyB;EACvB,gBAAgB,EAAE,sBAAsB;EACxC,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,MAAM,EAAE,aAAa;EACrB,KAAK,EAAE,IAAI;;AAGb,yBAA0B;EAExB,UAAU,EAAE,IAAI;;AAGlB,aAAc;EACZ,KAAK,EAAE,IAAI;;AAIX,sCAAgB;EACd,OAAO,EAAE,UAAU;EAEnB,uDAAkB;IAChB,OAAO,EAAE,KAAK;IAEd,oEAAa;MACX,OAAO,EAAE,UAAU;MACnB,cAAc,EAAE,MAAM;MACtB,YAAY,EAAE,IAAI;MAClB,aAAa,EAAE,IAAI;MAEnB,mFAAe;QACb,MAAM,EAAE,IAAI;QACZ,KAAK,EAAE,IAAI;QACX,SAAS,EAAE,IAAI;MAGjB,uEAAG;QACD,UAAU,EAAE,CAAC;QACb,aAAa,EAAE,GAAG;IAItB,gEAAS;MACP,OAAO,EAAE,UAAU;MACnB,cAAc,EAAE,MAAM;IAGxB,2EAAoB;MAClB,OAAO,EAAE,UAAU;MACnB,cAAc,EAAE,MAAM;MACtB,YAAY,EAAE,IAAI;MAClB,cAAc,EAAE,GAAG;EAIvB,0DAAoB;IAClB,UAAU,EAAE,GAAG;AAInB,oCAAc;EACZ,WAAW,EAAE,IAAI;EACjB,aAAa,EAAE,IAAI;;AAIvB,oBAAqB;EACnB,OAAO,EAAE,iBAAiB;EAC1B,UAAU,EAAE,GAAG;EACf,YAAY,EAAE,UAAU;EACxB,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,IAAI;EACjB,KAAK,EAAE,IAAI;EACX,gBAAgB,EAAE,IAAI;EAEtB,kCAAgB;IACd,UAAU,EAAE,CAAC;;AAIjB,UAAW;;EAET,sBAAY;IACV,WAAW,EAAE,CAAC;EAGhB,wCAA8B;IAC5B,UAAU,EAAE,GAAG;IACf,WAAW,EAAE,GAAG;IAChB,cAAc,EAAE,QAAQ;;AAI5B,mBAAoB;EAClB,aAAa,EAAE,IAAI;;AAGrB,8BAA+B;EAC7B,MAAM,EAAE,KAAK;EACb,QAAQ,EAAE,IAAI;EAGZ,oDAAgB;IACd,KAAK,EAAE,GAAG;IACV,UAAU,EAAE,KAAK;EAGnB,qDAAiB;IACf,KAAK,EAAE,GAAG;EAGZ,oDAAgB;IACd,UAAU,EAAE,MAAM;IAElB,oEAAgB;MACd,KAAK,EAAE,IAAI;EAIf,oDAAgB;IACd,KAAK,EAAE,IAAI;EAGb,6CAAS;IACP,WAAW,EAAE,IAAI;;AAKvB,QAAS;EACP,UAAU,EAAE,SAAS;EAErB,sBAAgB;IACd,KAAK,EAAE,YAAY;EAGrB,6BAAuB;IACrB,KAAK,EAAE,YAAY;;AAIvB,WAAY;EACV,OAAO,EAAE,UAAU;;AAGrB,mBAAoB;EAClB,aAAa,EAAE,IAAI;EACnB,YAAY,EAAE,GAAG;EACjB,KAAK,EAAE,IAAI;;AAKb,yBAA0B;EACxB,IAAI,EAAE,CAAC;EACP,GAAG,EAAE,GAAG;EACR,KAAK,EAAE,KAAK;;AAGd,MAAO;EACL,KAAK,EAAE,KAAK;EACZ,OAAO,EAAE,GAAG;;AAGd,UAAW;EACT,WAAW,EAAE,IAAI;;AAKnB,+CAAgD;EAC9C,WAAW,EAAE,CAAC;;AAGhB,kCAAmC;EACjC,KAAK,EAAE,KAAK;EAEZ,4CAAY;IACV,KAAK,EAAE,KAAK;;AAIhB,WAAY;EACV,UAAU,EAAE,CAAC;EACb,aAAa,EAAE,IAAI;;AAGrB,mDAAoD;EAClD,WAAW,EAAE,IAAI;;AAGnB,4CAA6C;EAC3C,OAAO,EAAE,CAAC;EAEV,kDAAM;IACJ,MAAM,EAAE,CAAC;IACT,MAAM,EAAE,IAAI;IACZ,cAAc,EAAE,GAAG;IACnB,UAAU,EAAE,KAAK;;AAMrB,gBAAiB;EACf,KAAK,EAvQa,IAAI;;AA0QxB,kBAAmB;EACjB,KAAK,EA3Qa,IAAI;;AA8QxB,iBAAkB;EAChB,KAAK,EA/Qa,IAAI;;AAoRxB,gEAAiE;EAC/D,UAAU,EAAE,GAAG", 4 | "sources": ["../../scss/style.scss"], 5 | "names": [], 6 | "file": "style.css" 7 | } -------------------------------------------------------------------------------- /lib/commons-configuration-1.10.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/lib/commons-configuration-1.10.jar -------------------------------------------------------------------------------- /lib/copy_to_app/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, 5 | // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // the compiled file. 9 | // 10 | // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD 11 | // GO AFTER THE REQUIRES BELOW. 12 | // 13 | //= require rglossa/application 14 | //= require_tree . 15 | -------------------------------------------------------------------------------- /lib/orientdb/blueprints-core-2.6.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/lib/orientdb/blueprints-core-2.6.0.jar -------------------------------------------------------------------------------- /lib/orientdb/concurrentlinkedhashmap-lru-1.4.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/lib/orientdb/concurrentlinkedhashmap-lru-1.4.1.jar -------------------------------------------------------------------------------- /lib/orientdb/jna-4.0.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/lib/orientdb/jna-4.0.0.jar -------------------------------------------------------------------------------- /lib/orientdb/jna-platform-4.0.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/lib/orientdb/jna-platform-4.0.0.jar -------------------------------------------------------------------------------- /lib/orientdb/orientdb-client-2.1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/lib/orientdb/orientdb-client-2.1.0.jar -------------------------------------------------------------------------------- /lib/orientdb/orientdb-core-2.1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/lib/orientdb/orientdb-core-2.1.0.jar -------------------------------------------------------------------------------- /lib/orientdb/orientdb-enterprise-2.1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/lib/orientdb/orientdb-enterprise-2.1.0.jar -------------------------------------------------------------------------------- /lib/orientdb/orientdb-graphdb-2.1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/lib/orientdb/orientdb-graphdb-2.1.0.jar -------------------------------------------------------------------------------- /lib/rglossa.rb: -------------------------------------------------------------------------------- 1 | require "rglossa/engine" 2 | require "fastimage" 3 | require "daemon_controller" 4 | require "headless" 5 | require "zip" 6 | require "ruby-saml" 7 | 8 | module Rglossa 9 | end 10 | -------------------------------------------------------------------------------- /lib/rglossa/engine.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | class Engine < ::Rails::Engine 3 | isolate_namespace Rglossa 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /lib/rglossa/incompatible_metadata_error.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | class IncompatibleMetadataError < StandardError 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /lib/rglossa/query_error.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | class QueryError < StandardError 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /lib/rglossa/version.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | VERSION = "0.0.1" 3 | end 4 | -------------------------------------------------------------------------------- /lib/tasks/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/lib/tasks/.gitkeep -------------------------------------------------------------------------------- /lib/tasks/assets.rake: -------------------------------------------------------------------------------- 1 | # lib/tasks/assets.rake 2 | # From http://www.tomdooner.com/2014/05/26/webpack.html 3 | 4 | # The webpack task must run before assets:environment task. 5 | # Otherwise Sprockets cannot find the files that webpack produces. 6 | Rake::Task['assets:precompile'] 7 | .clear_prerequisites 8 | .enhance(['assets:compile_environment']) 9 | 10 | namespace :assets do 11 | # In this task, set prerequisites for the assets:precompile task 12 | task :compile_environment => :webpack do 13 | Rake::Task['assets:environment'].invoke 14 | end 15 | 16 | desc 'Compile assets with webpack' 17 | task :webpack do 18 | sh '$(npm bin)/webpack --config webpack.config.js' 19 | end 20 | 21 | task :clobber do 22 | rm_rf "#{app.config.root}/app/assets/javascripts/{bundle.js,components.js}" 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/tasks/cwb_test_corpus.rake: -------------------------------------------------------------------------------- 1 | namespace :cwb_test_corpus do 2 | desc "Create CWB test corpus." 3 | task :create do 't' 4 | Dir.chdir "test/cwb_test_data" 5 | 6 | sh "bash ./create_test_corpus.sh" 7 | end 8 | 9 | desc "Delete CWB test corpus." 10 | task :delete do 't' 11 | Dir.chdir "test/cwb_test_data" 12 | 13 | sh "bash ./delete_test_corpus.sh" 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/tasks/rglossa_tasks.rake: -------------------------------------------------------------------------------- 1 | namespace "rglossa" do 2 | namespace "install" do 3 | 4 | desc "Install thor scripts" 5 | task :thor do 6 | print "Installing thor scripts... " 7 | 8 | filenames = "rglossa_*.thor" 9 | source = Dir["#{Rails.root}/lib/tasks/#{filenames}"] 10 | dest = "#{Rails.root}/lib/tasks" 11 | old_files = Dir["#{dest}/#{filenames}"] 12 | 13 | FileUtils.rm(old_files) 14 | FileUtils.cp(source, dest) 15 | 16 | puts "done." 17 | end 18 | 19 | desc "Copy files to application" 20 | task :copy_files do 21 | print "Copying layout file..." 22 | 23 | source = Dir["#{Rails.root}/app/views/layouts/application.html.erb"] 24 | dest = "#{Rails.root}/app/views/layouts" 25 | FileUtils.cp(source, dest) 26 | 27 | puts "done." 28 | 29 | print "Copying application.js..." 30 | 31 | source = Dir["#{Rails.root}/lib/copy_to_app/application.js"] 32 | dest = "#{Rails.root}/app/assets/javascripts" 33 | FileUtils.cp(source, dest) 34 | 35 | puts "done." 36 | end 37 | 38 | desc "Download, compile and install the Snack Sound Toolkit" 39 | task :snack => :environment do 40 | conf = Rglossa::Speech::WaveformPlayer.conf 41 | Dir.chdir Rails.root.join('lib/waveforms') 42 | Process.wait spawn("./install_snack.sh", conf['snack_dir'], conf['tcl_dir'], 43 | conf['tk_dir'], Dir.mktmpdir) 44 | end 45 | 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /lib/tasks/thor_utils.rb: -------------------------------------------------------------------------------- 1 | module Rglossa 2 | module ThorUtils 3 | 4 | include Thor::Actions 5 | 6 | ######## 7 | private 8 | ######## 9 | 10 | def corpus 11 | @corpus ||= begin 12 | corpus = ::Rglossa::Corpus.find_by_short_name(lowercase_corpusname) 13 | 14 | unless corpus 15 | if yes?("No corpus with short name #{lowercase_corpusname} was found. Create one?") 16 | full_name = ask("Full name of the corpus:") 17 | encoding = ask("Corpus encoding (default = utf-8):") 18 | encoding = 'utf-8' if encoding.blank? 19 | corpus = ::Rglossa::Corpus.create(short_name: lowercase_corpusname, 20 | name: full_name, 21 | encoding: encoding) 22 | unless corpus 23 | say "Unable to create corpus #{lowercase_corpusname}!", :red 24 | say $! 25 | end 26 | else 27 | say "No corpus found - aborting!", :red 28 | end 29 | end 30 | corpus 31 | end 32 | end 33 | 34 | def table 35 | @table ||= "#{uppercase_corpusname}#{options[:table_suffix] || 'text'}" 36 | end 37 | 38 | def uppercase_corpusname 39 | @uppercase_corpusname ||= options[:corpus].upcase 40 | end 41 | 42 | def lowercase_corpusname 43 | @lowercase_corpusname ||= options[:corpus].downcase 44 | end 45 | 46 | def corpus_id 47 | @corpus_id = Corpus.find_by_short_name(lowercase_corpusname).id 48 | end 49 | 50 | def category_file 51 | @category_file ||= "#{Rails.root}/tmp/dumps/#{table}_categories.txt" 52 | end 53 | 54 | def data_file 55 | @data_file ||= "#{Rails.root}/tmp/dumps/#{table}_data.tsv" 56 | end 57 | 58 | def run_sql_command(outfile, sql) 59 | remove_file(outfile) 60 | command = %Q{mysql -u #{options[:user]} -p #{options[:database]} -e "#{sql}"} 61 | puts command 62 | system(command) 63 | end 64 | 65 | end 66 | end 67 | -------------------------------------------------------------------------------- /lib/waveforms/install_snack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$#" -ne 4 ]; then 4 | >&2 echo "Usage: ./install_snack.sh snack_dir tcl_dir_list tk_dir_list tmp_dir" 5 | exit 1 6 | fi 7 | 8 | snack_dir="$1" 9 | tcl_dir_list="$2" 10 | tk_dir_list="$3" 11 | tmp_dir="$4" 12 | 13 | IFS=: 14 | for dir in $tcl_dir_list; do 15 | tcl_dir="$dir" 16 | if [ -f "$dir/tclConfig.sh" ]; then 17 | break 18 | fi 19 | done 20 | 21 | for dir in $tk_dir_list; do 22 | tk_dir="$dir" 23 | if [ -f "$dir/tkConfig.sh" ]; then 24 | break 25 | fi 26 | done 27 | IFS= 28 | 29 | if [ -d "$tmp_dir/snack2.2.10" ]; then 30 | >&2 echo "Delete '$tmp_dir/snack2.2.10' to continue" 31 | exit 1 32 | fi 33 | 34 | set -ve 35 | [ -f "$tmp_dir/snack2.2.10.tar.gz" ] || curl http://www.speech.kth.se/snack/dist/snack2.2.10.tar.gz >"$tmp_dir/snack2.2.10.tar.gz" 36 | (cd "$tmp_dir" && tar zxf snack2.2.10.tar.gz) 37 | patch -d "$tmp_dir/snack2.2.10" -p1 7 | +#include 8 | #define FRAS2(is,a) ((is) > 0 ? t_43[(is)]*(a):-t_43[-(is)]*(a)) 9 | #define MAXFRAMESIZE 2106 /* frame size starting at header */ 10 | #define roundf(x) (floor((x)+(float )0.5f)) 11 | @@ -1309,8 +1310,6 @@ 12 | return len; 13 | } 14 | 15 | -#include 16 | - 17 | #define PI12 0.261799387f 18 | #define PI36 0.087266462f 19 | #define COSPI3 0.500000000f 20 | -------------------------------------------------------------------------------- /log/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/log/.gitkeep -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rglossa", 3 | "version": "0.0.1", 4 | "description": "RGlossa is a reimplementation of the [Glossa search system](https://github.com/noklesta/glossa_svn) in Ruby on Rails.", 5 | "main": "webpack.config.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git://github.com/textlab/rglossa.git" 15 | }, 16 | "author": "", 17 | "license": "ISC", 18 | "bugs": { 19 | "url": "https://github.com/textlab/rglossa/issues" 20 | }, 21 | "homepage": "https://github.com/textlab/rglossa", 22 | "dependencies": { 23 | "webpack": "~1.4.0-beta5", 24 | "jsx-loader": "~0.13.1", 25 | "react": "~0.13.1" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 17 | 18 | 19 | 20 | 21 |
    22 |

    The page you were looking for doesn't exist.

    23 |

    You may have mistyped the address or the page may have moved.

    24 |
    25 | 26 | 27 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 17 | 18 | 19 | 20 | 21 |
    22 |

    The change you wanted was rejected.

    23 |

    Maybe you tried to change something you didn't have access to.

    24 |
    25 | 26 | 27 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 17 | 18 | 19 | 20 | 21 |
    22 |

    We're sorry, but something went wrong.

    23 |
    24 | 25 | 26 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/public/favicon.ico -------------------------------------------------------------------------------- /public/img/book-clip-art-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/public/img/book-clip-art-3.png -------------------------------------------------------------------------------- /public/img/tekstlab.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/public/img/tekstlab.gif -------------------------------------------------------------------------------- /public/img/waveform.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/public/img/waveform.png -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-Agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /public/swf/Jplayer.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/public/swf/Jplayer.swf -------------------------------------------------------------------------------- /public/swf/soundmanager2.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/public/swf/soundmanager2.swf -------------------------------------------------------------------------------- /public/swf/soundmanager2_flash9.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/public/swf/soundmanager2_flash9.swf -------------------------------------------------------------------------------- /public/tekstlab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/public/tekstlab.png -------------------------------------------------------------------------------- /rglossa.gemspec: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | 3 | $:.push File.expand_path("../lib", __FILE__) 4 | 5 | # Maintain your gem's version: 6 | require 'rglossa/version' 7 | 8 | # Describe your gem and declare its dependencies: 9 | Gem::Specification.new do |s| 10 | s.name = 'rglossa' 11 | s.version = Rglossa::VERSION 12 | s.authors = ['Anders Nøklestad', 'André Lynum'] 13 | s.email = %w(tekstlab-post@iln.uio.no) 14 | s.homepage = 'http://www.hf.uio.no/iln/english/about/organization/text-laboratory/' 15 | s.summary = 'The Glossa corpus search system' 16 | s.description = 'Ruby on Rails version of the Glossa system for corpus search and results management' 17 | 18 | s.files = Dir['{app,config,db,lib}/**/*'] + %w(MIT-LICENSE Rakefile README.md README.rails) 19 | s.test_files = Dir['test/**/*'] 20 | 21 | s.add_dependency 'rails', '~> 3.2.19' 22 | s.add_dependency 'jquery-rails' 23 | s.add_dependency 'sass-rails', '~> 3.2.5' 24 | s.add_dependency 'coffee-rails', '~> 3.2.2' 25 | s.add_dependency 'uglifier', '>= 1.2.7' 26 | s.add_dependency 'oj' # more efficient parsing and generation of JSON 27 | s.add_dependency 'turbo-sprockets-rails3' # faster precompilation of assets 28 | s.add_dependency 'react-rails' 29 | s.add_dependency 'devise', '~> 2.2.3' 30 | s.add_dependency 'globalize', '~> 3.0.0' 31 | s.add_dependency 'i18n-js' 32 | s.add_dependency 'fastimage' 33 | s.add_dependency 'headless' 34 | s.add_dependency 'daemon_controller' 35 | s.add_dependency 'rubyzip' 36 | s.add_dependency 'ruby-saml' 37 | 38 | s.add_development_dependency 'sqlite3' 39 | s.add_development_dependency 'rb-fsevent', '~> 0.9.1' 40 | s.add_development_dependency 'rspec-rails' 41 | s.add_development_dependency 'factory_girl_rails' 42 | s.add_development_dependency 'capybara' 43 | s.add_development_dependency 'guard-rspec' 44 | s.add_development_dependency 'poltergeist' 45 | s.add_development_dependency 'konacha' # for testing JavaScript with Mocha and chai 46 | end 47 | -------------------------------------------------------------------------------- /script/build_ubuntu_essential.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | docker rm ubuntu-essential-multilayer 2>/dev/null 4 | set -ve 5 | docker build -t textlab/ubuntu-essential-multilayer - <<'EOF' 6 | FROM ubuntu:14.04 7 | # Make an exception for apt: it gets deselected, even though it probably shouldn't. 8 | RUN dpkg --clear-selections && echo apt install |dpkg --set-selections && \ 9 | SUDO_FORCE_REMOVE=yes DEBIAN_FRONTEND=noninteractive apt-get --purge -y dselect-upgrade && \ 10 | dpkg-query -Wf '${db:Status-Abbrev}\t${binary:Package}\n' |grep '^.i' |awk -F'\t' '{print $2 " install"}' |dpkg --set-selections && \ 11 | rm -r /var/cache/apt /var/lib/apt/lists 12 | EOF 13 | TMP_FILE="`mktemp -t ubuntu-essential-XXXXXXX.tar.gz`" 14 | docker run --rm -i textlab/ubuntu-essential-multilayer tar zpc --exclude=/etc/hostname \ 15 | --exclude=/etc/resolv.conf --exclude=/etc/hosts --one-file-system / >"$TMP_FILE" 16 | docker rmi textlab/ubuntu-essential-multilayer 17 | docker import - textlab/ubuntu-essential-nocmd <"$TMP_FILE" 18 | docker build -t textlab/ubuntu-essential - <<'EOF' 19 | FROM textlab/ubuntu-essential-nocmd 20 | CMD ["/bin/bash"] 21 | EOF 22 | docker rmi textlab/ubuntu-essential-nocmd 23 | rm -f "$TMP_FILE" 24 | -------------------------------------------------------------------------------- /script/docker_build_conf.sh: -------------------------------------------------------------------------------- 1 | install='apt-get install --no-install-recommends -y' 2 | remove='apt-get purge --auto-remove -y' 3 | autoremove='apt-get autoremove --purge -y' 4 | 5 | # Build dependencies for the gems, Corpus Workbench and Snack 6 | GEM_BUILD_DEPS='git make patch binutils perl gcc g++ libc6-dev ruby2.0-dev libmysqlclient-dev libsqlite3-dev' 7 | CWB_BUILD_DEPS='subversion autoconf bison flex libglib2.0-dev libglib2.0-data libncurses5-dev make binutils perl gcc g++ libc6-dev' 8 | SNACK_BUILD_DEPS='curl make patch binutils perl gcc g++ libc6-dev tcl8.4-dev tk8.4-dev bzip2 xz-utils' 9 | -------------------------------------------------------------------------------- /script/docker_build_deps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -ve 4 | 5 | . script/docker_build_conf.sh 6 | 7 | # Changes to these two files make the image unnecessarily large after running useradd: 8 | rm -f /var/log/faillog /var/log/lastlog 9 | useradd -u 61054 -d /glossa glossa 10 | 11 | # Ensure that we will get the newest packages 12 | apt-get update 13 | 14 | # Temporarily enable caching - we may install and remove same packages a few times 15 | mkdir -p /etc/apt/apt.conf.d/disabled 16 | mv /etc/apt/apt.conf.d/docker-clean /etc/apt/apt.conf.d/disabled/ 17 | mv /etc/apt/apt.conf.d/01autoremove /etc/apt/apt.conf.d/disabled/ 18 | 19 | # Install the necessary gems 20 | gem update --system && gem pristine --all && gem install bundler 21 | rm -rf /root/.gem 22 | $install $GEM_BUILD_DEPS 23 | bundle install 24 | $remove $GEM_BUILD_DEPS 25 | $autoremove 26 | 27 | # Install the IMS Open Corpus Workbench (http://cwb.sourceforge.net/) by 28 | # checking it out from svn and modifying config.mk to select linux-64 as the 29 | # platform to build for. 30 | $install $CWB_BUILD_DEPS 31 | svn export http://svn.code.sf.net/p/cwb/code/cwb/branches/3.0 /tmp/cwb 32 | cd /tmp/cwb 33 | ruby -i -pe '$_.sub!(%r{ / [^/\r\n]+ \s* $ }x, "/linux-64") if $_.start_with? "include $(TOP)/config/platform/"' /tmp/cwb/config.mk 34 | make clean && make depend && make all && make install 35 | $remove $CWB_BUILD_DEPS 36 | $autoremove 37 | 38 | # Install the Snack Sound Toolkit 39 | cd /glossa 40 | $install $SNACK_BUILD_DEPS 41 | for dir in snack_dir tcl_dir tk_dir; do 42 | export $dir="`ruby -rjson </dev/null 2>&1; then 3 | IP=`boot2docker ip 2>/dev/null` 4 | run="boot2docker ssh" 5 | else 6 | IP=127.0.0.1 7 | run="sh -c" 8 | fi 9 | 10 | PORT=`$run 'ID=$(docker ps |awk '\''$NF=="glossa"{print $1}'\''); 11 | docker port "$ID" 2>/dev/null |awk -F: "{print \\\$2}"'` 12 | echo 13 | if [ "$PORT" = "" ]; then 14 | echo "Glossa is not running" 15 | else 16 | echo "Glossa is available at:" 17 | echo "http://$IP:$PORT" 18 | fi 19 | 20 | if [ "$1" != "--no-pause" ]; then 21 | echo "Press Enter..." 22 | read PAUSE 23 | fi 24 | -------------------------------------------------------------------------------- /script/glossa_start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if docker >/dev/null 2>&1; then 3 | run="sh -c" 4 | else 5 | run="boot2docker ssh" 6 | fi 7 | 8 | $run "docker run --name glossa-data textlab/glossa-data >/dev/null 2>&1; true" 9 | $run "docker rm glossa >/dev/null 2>&1; true" 10 | echo "Starting Glossa..." 11 | if ! $run "docker images |grep -q '^textlab/glossa[ \t]'" 2>/dev/null; then 12 | echo "(first download may take some time)" 13 | PULL_GLOSSA_BASE=yes 14 | fi 15 | 16 | $run "docker run -d -p 61054:3000 --name glossa --volumes-from glossa-data textlab/glossa" 17 | cwd="`dirname -- "$0"`" 18 | if [ -f "$cwd/glossa_addr.sh" ]; then 19 | "$cwd/glossa_addr.sh" --no-pause 20 | fi 21 | 22 | if [ "$PULL_GLOSSA_BASE" = "yes" ]; then 23 | # Pull textlab/glossa-base. Not strictly necessary, but it will stay 24 | # there even if textlab/glossa is removed, and reduce upgrade time. 25 | $run "docker pull textlab/glossa-base" 26 | fi 27 | echo "Press Enter..." 28 | read PAUSE 29 | -------------------------------------------------------------------------------- /script/glossa_stop.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if docker >/dev/null 2>&1; then 3 | run="sh -c" 4 | else 5 | run="boot2docker ssh" 6 | fi 7 | 8 | echo "Stopping Glossa..." 9 | $run "docker stop glossa; docker rm glossa" 10 | echo "Press Enter..." 11 | read PAUSE 12 | -------------------------------------------------------------------------------- /script/make_saml_metadata.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # encoding: utf-8 3 | 4 | # Script for generating metadata that need to be sent to an identity provider (IdP), such as Feide 5 | # Change APP_URL and CONFIG appropriately 6 | 7 | import sys 8 | import re 9 | import saml2.config 10 | import saml2.metadata 11 | import saml2.validate 12 | from saml2 import BINDING_HTTP_REDIRECT 13 | from saml2 import BINDING_HTTP_POST 14 | from saml2.saml import NAME_FORMAT_URI 15 | 16 | if len(sys.argv) != 2: 17 | print "Usage: ./make_saml_metadata.py idp_name" 18 | sys.exit(1) 19 | idp = re.sub(r'[^a-zA-Z_]', '', sys.argv[1]).lower() 20 | 21 | APP_URL = "https://www.tekstlab.uio.no/glossa2" 22 | CONFIG = { 23 | "entityid": "%s/saml/metadata/%s" % (APP_URL, idp), 24 | "description": "The Glossa corpus search system", 25 | "service": { 26 | "sp": { 27 | "name": "Glossa at University of Oslo", 28 | "endpoints": { 29 | "assertion_consumer_service": [("%s/auth/%s" % (APP_URL, idp), BINDING_HTTP_POST)], 30 | "single_logout_service" : [("%s/logout/%s" % (APP_URL, idp), BINDING_HTTP_REDIRECT)], 31 | }, 32 | "required_attributes": ["edupersonprincipalname", "mail", "displayname"], 33 | "optional_attributes": ["edupersonaffiliation", "edupersonorgdn", "edupersonorgunitdn", 34 | "edupersonprimaryaffiliation", "edupersonprimaryorgunitdn", 35 | "edupersonscopedaffiliation"], 36 | }, 37 | }, 38 | # Key and cert file used by the Apache instance that serves Glossa: 39 | "key_file": "/etc/pki/tls/private/www.tekstlab.uio.no.key", 40 | "cert_file": "/etc/pki/tls/certs/www.tekstlab.uio.no.crt", 41 | "organization": { 42 | "name": "Text Laboratory, University of Oslo", 43 | "display_name": [("Text Laboratory, University of Oslo","en")], 44 | "url": "https://www.hf.uio.no/iln/om/organisasjon/tekstlab/", 45 | }, 46 | "contact_person": [{ 47 | "given_name": "Anders", 48 | "sur_name": "Nøklestad", 49 | "email_address": ["anders.noklestad@iln.uio.no"], 50 | "contact_type": "technical", 51 | }, 52 | ], 53 | "name_form": NAME_FORMAT_URI 54 | } 55 | 56 | cnf = saml2.config.Config().load(CONFIG, metadata_construction=True) 57 | eid = saml2.metadata.entity_descriptor(cnf) 58 | saml2.validate.valid_instance(eid) 59 | print saml2.metadata.metadata_tostring_fix(eid, {"xs": "http://www.w3.org/2001/XMLSchema"}, None) 60 | -------------------------------------------------------------------------------- /script/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. 3 | 4 | APP_PATH = File.expand_path('../../config/application', __FILE__) 5 | require File.expand_path('../../config/boot', __FILE__) 6 | 7 | require 'rails/commands/server' 8 | module Rails 9 | class Server 10 | def default_options 11 | super.merge({ 12 | :Port => 61054 13 | }) 14 | end 15 | end 16 | end 17 | 18 | require 'rails/commands' 19 | -------------------------------------------------------------------------------- /test/dummy/Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | # Add your own tasks in files placed in lib/tasks ending in .rake, 3 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 4 | 5 | require File.expand_path('../config/application', __FILE__) 6 | 7 | Dummy::Application.load_tasks 8 | -------------------------------------------------------------------------------- /test/dummy/app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, 5 | // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // the compiled file. 9 | // 10 | // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD 11 | // GO AFTER THE REQUIRES BELOW. 12 | // 13 | //= require jquery 14 | //= require jquery_ujs 15 | // 16 | //= require rglossa/application 17 | // 18 | //= require_tree . 19 | -------------------------------------------------------------------------------- /test/dummy/app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, 6 | * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the top of the 9 | * compiled file, but it's generally better to create a new file per style scope. 10 | * 11 | *= require_self 12 | *= require rglossa/application 13 | *= require_tree . 14 | */ 15 | -------------------------------------------------------------------------------- /test/dummy/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | protect_from_forgery 3 | end 4 | -------------------------------------------------------------------------------- /test/dummy/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /test/dummy/app/mailers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/test/dummy/app/mailers/.gitkeep -------------------------------------------------------------------------------- /test/dummy/app/models/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/test/dummy/app/models/.gitkeep -------------------------------------------------------------------------------- /test/dummy/app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dummy 5 | <%= stylesheet_link_tag "application", :media => "all" %> 6 | <%= javascript_include_tag "application" %> 7 | <%= csrf_meta_tags %> 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/dummy/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Dummy::Application 5 | -------------------------------------------------------------------------------- /test/dummy/config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | require 'rails/all' 4 | 5 | Bundler.require 6 | require "rglossa" 7 | 8 | module Dummy 9 | class Application < Rails::Application 10 | # Settings in config/environments/* take precedence over those specified here. 11 | # Application configuration should go into files in config/initializers 12 | # -- all .rb files in that directory are automatically loaded. 13 | 14 | # Custom directories with classes and modules you want to be autoloadable. 15 | # config.autoload_paths += %W(#{config.root}/extras) 16 | 17 | # Only load the plugins named here, in the order given (default is alphabetical). 18 | # :all can be used as a placeholder for all plugins not explicitly named. 19 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ] 20 | 21 | # Activate observers that should always be running. 22 | # config.active_record.observers = :cacher, :garbage_collector, :forum_observer 23 | 24 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 25 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 26 | # config.time_zone = 'Central Time (US & Canada)' 27 | 28 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 29 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 30 | # config.i18n.default_locale = :de 31 | 32 | # Configure the default encoding used in templates for Ruby 1.9. 33 | config.encoding = "utf-8" 34 | 35 | # Configure sensitive parameters which will be filtered from the log file. 36 | config.filter_parameters += [:password] 37 | 38 | # Enable escaping HTML in JSON. 39 | config.active_support.escape_html_entities_in_json = true 40 | 41 | # Use SQL instead of Active Record's schema dumper when creating the database. 42 | # This is necessary if your schema can't be completely dumped by the schema dumper, 43 | # like if you have constraints or database-specific column types 44 | # config.active_record.schema_format = :sql 45 | 46 | # Enforce whitelist mode for mass assignment. 47 | # This will create an empty whitelist of attributes available for mass-assignment for all models 48 | # in your app. As such, your models will need to explicitly whitelist or blacklist accessible 49 | # parameters by using an attr_accessible or attr_protected declaration. 50 | # AN: Disable for now because it creates probles for Globalize3 51 | # config.active_record.whitelist_attributes = true 52 | config.active_record.whitelist_attributes = false 53 | 54 | # Enable the asset pipeline 55 | config.assets.enabled = true 56 | 57 | # Version of your assets, change this if you want to expire all your assets 58 | config.assets.version = '1.0' 59 | end 60 | end 61 | 62 | -------------------------------------------------------------------------------- /test/dummy/config/boot.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | gemfile = File.expand_path('../../../../Gemfile', __FILE__) 3 | 4 | if File.exist?(gemfile) 5 | ENV['BUNDLE_GEMFILE'] = gemfile 6 | require 'bundler' 7 | Bundler.setup 8 | end 9 | 10 | $:.unshift File.expand_path('../../../../lib', __FILE__) -------------------------------------------------------------------------------- /test/dummy/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the rails application 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the rails application 5 | Dummy::Application.initialize! 6 | -------------------------------------------------------------------------------- /test/dummy/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Dummy::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Log error messages when you accidentally call methods on nil. 10 | config.whiny_nils = true 11 | 12 | # Show full error reports and disable caching 13 | config.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send 17 | config.action_mailer.raise_delivery_errors = false 18 | 19 | # Print deprecation notices to the Rails logger 20 | config.active_support.deprecation = :log 21 | 22 | # Only use best-standards-support built into browsers 23 | config.action_dispatch.best_standards_support = :builtin 24 | 25 | # Raise exception on mass assignment protection for Active Record models 26 | config.active_record.mass_assignment_sanitizer = :strict 27 | 28 | # Log the query plan for queries taking more than this (works 29 | # with SQLite, MySQL, and PostgreSQL) 30 | config.active_record.auto_explain_threshold_in_seconds = 0.5 31 | 32 | # Do not compress assets 33 | config.assets.compress = false 34 | 35 | # Expands the lines which load the assets 36 | config.assets.debug = true 37 | end 38 | 39 | silence_warnings do 40 | require "pry" 41 | IRB = Pry 42 | end 43 | -------------------------------------------------------------------------------- /test/dummy/config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Dummy::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # Code is not reloaded between requests 5 | config.cache_classes = true 6 | 7 | # Full error reports are disabled and caching is turned on 8 | config.consider_all_requests_local = false 9 | config.action_controller.perform_caching = true 10 | 11 | # Disable Rails's static asset server (Apache or nginx will already do this) 12 | config.serve_static_assets = false 13 | 14 | # Compress JavaScripts and CSS 15 | config.assets.compress = true 16 | 17 | # Don't fallback to assets pipeline if a precompiled asset is missed 18 | config.assets.compile = false 19 | 20 | # Generate digests for assets URLs 21 | config.assets.digest = true 22 | 23 | # Defaults to nil and saved in location specified by config.assets.prefix 24 | # config.assets.manifest = YOUR_PATH 25 | 26 | # Specifies the header that your server uses for sending files 27 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache 28 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx 29 | 30 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 31 | # config.force_ssl = true 32 | 33 | # See everything in the log (default is :info) 34 | # config.log_level = :debug 35 | 36 | # Prepend all log lines with the following tags 37 | # config.log_tags = [ :subdomain, :uuid ] 38 | 39 | # Use a different logger for distributed setups 40 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) 41 | 42 | # Use a different cache store in production 43 | # config.cache_store = :mem_cache_store 44 | 45 | # Enable serving of images, stylesheets, and JavaScripts from an asset server 46 | # config.action_controller.asset_host = "http://assets.example.com" 47 | 48 | # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added) 49 | # config.assets.precompile += %w( search.js ) 50 | 51 | # Disable delivery errors, bad email addresses will be ignored 52 | # config.action_mailer.raise_delivery_errors = false 53 | 54 | # Enable threaded mode 55 | # config.threadsafe! 56 | 57 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 58 | # the I18n.default_locale when a translation can not be found) 59 | config.i18n.fallbacks = true 60 | 61 | # Send deprecation notices to registered listeners 62 | config.active_support.deprecation = :notify 63 | 64 | # Log the query plan for queries taking more than this (works 65 | # with SQLite, MySQL, and PostgreSQL) 66 | # config.active_record.auto_explain_threshold_in_seconds = 0.5 67 | end 68 | -------------------------------------------------------------------------------- /test/dummy/config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Dummy::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Configure static asset server for tests with Cache-Control for performance 11 | config.serve_static_assets = true 12 | config.static_cache_control = "public, max-age=3600" 13 | 14 | # Log error messages when you accidentally call methods on nil 15 | config.whiny_nils = true 16 | 17 | # Show full error reports and disable caching 18 | config.consider_all_requests_local = true 19 | config.action_controller.perform_caching = false 20 | 21 | # Raise exceptions instead of rendering exception templates 22 | config.action_dispatch.show_exceptions = false 23 | 24 | # Disable request forgery protection in test environment 25 | config.action_controller.allow_forgery_protection = false 26 | 27 | # Tell Action Mailer not to deliver emails to the real world. 28 | # The :test delivery method accumulates sent emails in the 29 | # ActionMailer::Base.deliveries array. 30 | config.action_mailer.delivery_method = :test 31 | 32 | # Raise exception on mass assignment protection for Active Record models 33 | config.active_record.mass_assignment_sanitizer = :strict 34 | 35 | # Print deprecation notices to the stderr 36 | config.active_support.deprecation = :stderr 37 | end 38 | -------------------------------------------------------------------------------- /test/dummy/config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /test/dummy/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format 4 | # (all these examples are active by default): 5 | #ActiveSupport::Inflector.inflections do |inflect| 6 | # inflect.plural /^(ox)$/i, '\1en' 7 | # inflect.singular /^(ox)en/i, '\1' 8 | # inflect.irregular 'person', 'people' 9 | # inflect.uncountable %w( fish sheep ) 10 | #end 11 | # 12 | # These inflection rules are supported but not enabled by default: 13 | # ActiveSupport::Inflector.inflections do |inflect| 14 | # inflect.acronym 'RESTful' 15 | # end 16 | -------------------------------------------------------------------------------- /test/dummy/config/initializers/konacha.rb: -------------------------------------------------------------------------------- 1 | if defined?(Konacha) 2 | require 'capybara/poltergeist' 3 | Konacha.configure do |config| 4 | config.spec_dir = 'spec/javascripts' 5 | config.driver = :poltergeist 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /test/dummy/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | # Mime::Type.register_alias "text/html", :iphone 6 | 7 | Mime::Type.register "application/x-clarin-fcs-kwic+xml", :fcskwic 8 | -------------------------------------------------------------------------------- /test/dummy/config/initializers/secret_token.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | # Make sure the secret is at least 30 characters and all random, 6 | # no regular words or you'll be exposed to dictionary attacks. 7 | Dummy::Application.config.secret_token = 'b8e27f6c6ceaa3feabd69e90520a31d330ff9f5f2585b64610e21c7eaf87c7c0feb3c9ac6046813d6414dbb8b9d74172d5c983d0e9366160cc4cdb1812437099' 8 | -------------------------------------------------------------------------------- /test/dummy/config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Dummy::Application.config.session_store :cookie_store, key: '_dummy_session' 4 | 5 | # Use the database for sessions instead of the cookie-based default, 6 | # which shouldn't be used to store highly confidential information 7 | # (create the session table with "rails generate session_migration") 8 | # Dummy::Application.config.session_store :active_record_store 9 | -------------------------------------------------------------------------------- /test/dummy/config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | # 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | 11 | # Disable root element in JSON by default. 12 | ActiveSupport.on_load(:active_record) do 13 | self.include_root_in_json = false 14 | end 15 | -------------------------------------------------------------------------------- /test/dummy/config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Sample localization file for English. Add more files in this directory for other locales. 2 | # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. 3 | 4 | en: 5 | hello: "Hello world" 6 | -------------------------------------------------------------------------------- /test/dummy/config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | end 3 | -------------------------------------------------------------------------------- /test/dummy/db/migrate/20130416154321_create_rglossa_corpora.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20091203090812) 2 | class CreateRglossaCorpora < ActiveRecord::Migration 3 | def up 4 | create_table :rglossa_corpora do |t| 5 | t.string :name, null: false 6 | t.string :short_name # optional "code" used by e.g. CWB 7 | 8 | # it might be a good idea to set this if the corpus is very big: 9 | t.integer :default_max_hits 10 | 11 | t.timestamps 12 | end 13 | 14 | Rglossa::Corpus.create_translation_table!(name: :string) 15 | end 16 | 17 | def down 18 | drop_table :rglossa_corpora 19 | Rglossa::Corpus.drop_translation_table! 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /test/dummy/db/migrate/20130416154322_create_rglossa_metadata_categories.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20091205210334) 2 | class CreateRglossaMetadataCategories < ActiveRecord::Migration 3 | def up 4 | create_table :rglossa_metadata_categories do |t| 5 | t.belongs_to :corpus, null: false 6 | t.string :short_name, null: false 7 | t.string :category_type, null: false 8 | t.string :value_type, null: false 9 | 10 | t.timestamps 11 | 12 | Rglossa::MetadataCategory.create_translation_table!(name: :string) 13 | end 14 | 15 | def down 16 | drop_table :rglossa_metadata_categories 17 | Rglossa::MetadataCategory.drop_translation_table! 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /test/dummy/db/migrate/20130416154323_create_rglossa_searches.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20091206173444) 2 | class CreateRglossaSearches < ActiveRecord::Migration 3 | def change 4 | create_table :rglossa_searches do |t| 5 | t.integer :user_id, null: false 6 | t.string :type 7 | t.text :queries, null: false 8 | t.text :search_options 9 | t.text :metadata_value_ids 10 | t.integer :num_hits 11 | 12 | t.timestamps 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /test/dummy/db/migrate/20130416154324_create_rglossa_corpus_texts.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20091209231651) 2 | class CreateRglossaCorpusTexts < ActiveRecord::Migration 3 | def change 4 | create_table :rglossa_corpus_texts do |t| 5 | t.integer :startpos, limit: 8 # limit = 8 means bigint 6 | t.integer :endpos, limit: 8 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /test/dummy/db/migrate/20130416154325_create_rglossa_metadata_values.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20091223175749) 2 | class CreateRglossaMetadataValues < ActiveRecord::Migration 3 | def change 4 | create_table :rglossa_metadata_values do |t| 5 | t.belongs_to :metadata_category, null: false 6 | t.string :type, null: false 7 | t.text :text_value 8 | t.integer :integer_value 9 | t.boolean :boolean_value 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /test/dummy/db/migrate/20130416154326_create_rglossa_deleted_hits.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20100108140812) 2 | class CreateRglossaDeletedHits < ActiveRecord::Migration 3 | def change 4 | create_table :rglossa_deleted_hits do |t| 5 | t.integer :search_id, null: false 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /test/dummy/db/migrate/20130416154327_add_join_table_for_corpus_text_and_metadata_value.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20121110003219) 2 | class AddJoinTableForCorpusTextAndMetadataValue < ActiveRecord::Migration 3 | def change 4 | create_table :rglossa_corpus_texts_metadata_values do |t| 5 | t.belongs_to :rglossa_corpus_text, null: false 6 | t.belongs_to :rglossa_metadata_value, null: false 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /test/dummy/db/migrate/20130416154328_devise_create_rglossa_users.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20130318185404) 2 | class DeviseCreateRglossaUsers < ActiveRecord::Migration 3 | def change 4 | create_table(:rglossa_users) do |t| 5 | ## Database authenticatable 6 | t.string :email, :null => false, :default => "" 7 | t.string :encrypted_password, :null => false, :default => "" 8 | 9 | ## Recoverable 10 | t.string :reset_password_token 11 | t.datetime :reset_password_sent_at 12 | 13 | ## Rememberable 14 | t.datetime :remember_created_at 15 | 16 | ## Trackable 17 | t.integer :sign_in_count, :default => 0 18 | t.datetime :current_sign_in_at 19 | t.datetime :last_sign_in_at 20 | t.string :current_sign_in_ip 21 | t.string :last_sign_in_ip 22 | 23 | ## Confirmable 24 | # t.string :confirmation_token 25 | # t.datetime :confirmed_at 26 | # t.datetime :confirmation_sent_at 27 | # t.string :unconfirmed_email # Only if using reconfirmable 28 | 29 | ## Lockable 30 | # t.integer :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts 31 | # t.string :unlock_token # Only if unlock strategy is :email or :both 32 | # t.datetime :locked_at 33 | 34 | ## Token authenticatable 35 | # t.string :authentication_token 36 | 37 | 38 | t.timestamps 39 | end 40 | 41 | add_index :rglossa_users, :email, :unique => true 42 | add_index :rglossa_users, :reset_password_token, :unique => true 43 | # add_index :rglossa_users, :confirmation_token, :unique => true 44 | # add_index :rglossa_users, :unlock_token, :unique => true 45 | # add_index :rglossa_users, :authentication_token, :unique => true 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /test/dummy/db/migrate/20130423174716_add_corpus_id_to_corpus_text.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20130423174400) 2 | class AddCorpusIdToCorpusText < ActiveRecord::Migration 3 | def change 4 | # Breaks db normalization, but lets us list the texts belonging to a corpus without going 5 | # through corpus->metadata_categories->metadata_values->corpus_texts 6 | add_column :rglossa_corpus_texts, :corpus_id, :integer 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/dummy/db/migrate/20130424025517_add_encoding_to_corpus.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20130424025423) 2 | class AddEncodingToCorpus < ActiveRecord::Migration 3 | def change 4 | add_column :rglossa_corpora, :encoding, :string, default: 'utf-8' 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /test/dummy/db/migrate/20130730095637_add_max_hits_to_search.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20130730095239) 2 | class AddMaxHitsToSearch < ActiveRecord::Migration 3 | def change 4 | add_column :rglossa_searches, :max_hits, :integer 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /test/dummy/db/migrate/20130802121402_remove_default_max_hits_from_corpus.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20130802121247) 2 | class RemoveDefaultMaxHitsFromCorpus < ActiveRecord::Migration 3 | def change 4 | remove_column :rglossa_corpora, :default_max_hits 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /test/dummy/db/migrate/20130803193149_add_config_to_corpus.rglossa.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rglossa (originally 20130803192831) 2 | class AddConfigToCorpus < ActiveRecord::Migration 3 | def change 4 | add_column :rglossa_corpora, :config, :text 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /test/dummy/db/seeds.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | # This file should contain all the record creation needed to seed the database with its default values. 4 | # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). 5 | # 6 | # Examples: 7 | # 8 | # cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }]) 9 | # Mayor.create(:name => 'Daley', :city => cities.first) 10 | 11 | module Rglossa 12 | if Rails.env == 'development' 13 | User.create!(email: 'admin@test.com', password: 'admin123', password_confirmation: 'admin123') 14 | end 15 | 16 | corpus = Corpus.create!( 17 | short_name: 'RUN_EN', 18 | name: 'The Corpus for Bokmål Lexicography') 19 | 20 | title = MetadataCategory.create!( 21 | corpus: corpus, 22 | short_name: 'title', 23 | name: 'Title', 24 | category_type: 'list', 25 | value_type: 'text' 26 | ) 27 | MetadataValues::Text.create( 28 | [ 29 | { metadata_category: title, text: 'Peer Gynt' }, 30 | { metadata_category: title, text: 'Vildanden' }, 31 | { metadata_category: title, text: 'Brand' } 32 | ] 33 | ) 34 | 35 | author = MetadataCategory.create!( 36 | corpus: corpus, 37 | short_name: 'author', 38 | name: 'Author', 39 | category_type: 'list', 40 | value_type: 'text' 41 | ) 42 | MetadataValues::Text.create( 43 | [ 44 | { metadata_category: author, text: 'Henrik Ibsen' }, 45 | { metadata_category: author, text: 'Ingvar Ambjørnsen' }, 46 | { metadata_category: author, text: 'Erlend Loe' } 47 | ] 48 | ) 49 | 50 | publ_year = MetadataCategory.create!( 51 | corpus: corpus, 52 | short_name: 'published', 53 | name: 'Published?', 54 | category_type: 'list', 55 | value_type: 'integer' 56 | ) 57 | 58 | sex = MetadataCategory.create!( 59 | corpus: corpus, 60 | short_name: 'sex', 61 | name: 'Sex', 62 | category_type: 'shortlist', 63 | value_type: 'text' 64 | ) 65 | 66 | MetadataValues::Integer.create!(metadata_category: publ_year, text: 1867) 67 | MetadataValues::Text.create!(metadata_category: sex, text: 'male') 68 | end -------------------------------------------------------------------------------- /test/dummy/lib/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/test/dummy/lib/assets/.gitkeep -------------------------------------------------------------------------------- /test/dummy/log/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/test/dummy/log/.gitkeep -------------------------------------------------------------------------------- /test/dummy/public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 17 | 18 | 19 | 20 | 21 |
    22 |

    The page you were looking for doesn't exist.

    23 |

    You may have mistyped the address or the page may have moved.

    24 |
    25 | 26 | 27 | -------------------------------------------------------------------------------- /test/dummy/public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 17 | 18 | 19 | 20 | 21 |
    22 |

    The change you wanted was rejected.

    23 |

    Maybe you tried to change something you didn't have access to.

    24 |
    25 | 26 | 27 | -------------------------------------------------------------------------------- /test/dummy/public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 17 | 18 | 19 | 20 | 21 |
    22 |

    We're sorry, but something went wrong.

    23 |
    24 | 25 | 26 | -------------------------------------------------------------------------------- /test/dummy/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/test/dummy/public/favicon.ico -------------------------------------------------------------------------------- /test/dummy/script/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. 3 | 4 | APP_PATH = File.expand_path('../../config/application', __FILE__) 5 | require File.expand_path('../../config/boot', __FILE__) 6 | require 'rails/commands' 7 | -------------------------------------------------------------------------------- /test/dummy/test/fixtures/rglossa/users.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html 2 | 3 | # This model initially had no columns defined. If you add columns to the 4 | # model remove the '{}' from the fixture names and add the columns immediately 5 | # below each fixture, per the syntax in the comments below 6 | # 7 | one: {} 8 | # column: value 9 | # 10 | two: {} 11 | # column: value 12 | -------------------------------------------------------------------------------- /test/dummy/test/unit/rglossa/user_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class Rglossa::UserTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/fixtures/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/test/fixtures/.gitkeep -------------------------------------------------------------------------------- /test/functional/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/test/functional/.gitkeep -------------------------------------------------------------------------------- /test/functional/front_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class FrontControllerTest < ActionController::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/integration/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/test/integration/.gitkeep -------------------------------------------------------------------------------- /test/integration/navigation_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class NavigationTest < ActionDispatch::IntegrationTest 4 | fixtures :all 5 | 6 | # test "the truth" do 7 | # assert true 8 | # end 9 | end 10 | 11 | -------------------------------------------------------------------------------- /test/performance/browsing_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require 'rails/performance_test_help' 3 | 4 | class BrowsingTest < ActionDispatch::PerformanceTest 5 | # Refer to the documentation for all available options 6 | # self.profile_options = { :runs => 5, :metrics => [:wall_time, :memory] 7 | # :output => 'tmp/performance', :formats => [:flat] } 8 | 9 | def test_homepage 10 | get '/' 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /test/rglossa_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RglossaTest < ActiveSupport::TestCase 4 | test "truth" do 5 | assert_kind_of Module, Rglossa 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV["RAILS_ENV"] = "test" 2 | require File.expand_path('../../config/environment', __FILE__) 3 | require 'rails/test_help' 4 | 5 | class ActiveSupport::TestCase 6 | # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order. 7 | # 8 | # Note: You'll currently still have to declare fixtures explicitly in integration tests 9 | # -- they do not yet inherit this setting 10 | fixtures :all 11 | 12 | # Add more helper methods to be used by all tests here... 13 | end 14 | -------------------------------------------------------------------------------- /test/unit/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/test/unit/.gitkeep -------------------------------------------------------------------------------- /test/unit/helpers/front_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class FrontHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /vendor/assets/chinese-ime/ime.scss: -------------------------------------------------------------------------------- 1 | /* ime.scss */ 2 | 3 | .chinese-checkbox { 4 | color: #666; 5 | font-size: 14px; 6 | padding: 5px; 7 | display: none !important; 8 | } 9 | 10 | #chinese-ime { 11 | font-family: Arial, Sans-serif; 12 | font-size: 14px; 13 | position: absolute; 14 | background: #fff; 15 | border: 1px solid #aaa; 16 | width: 230px; 17 | padding: 4px; 18 | 19 | .typing { 20 | border: { 21 | right: { 22 | style: solid; 23 | width: 1px; 24 | color: #54BDF0; 25 | } 26 | } 27 | } 28 | ul.options { 29 | margin: 0; 30 | padding: 0; 31 | list-style-type: none; 32 | 33 | li { float: left; padding: 0.2em;} 34 | li.current { background: #eee; } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /vendor/assets/flash/rglossa/speech/Jplayer.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/vendor/assets/flash/rglossa/speech/Jplayer.swf -------------------------------------------------------------------------------- /vendor/assets/images/bootstrap-2.3.1/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/vendor/assets/images/bootstrap-2.3.1/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /vendor/assets/images/bootstrap-2.3.1/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/vendor/assets/images/bootstrap-2.3.1/glyphicons-halflings.png -------------------------------------------------------------------------------- /vendor/assets/images/font/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/vendor/assets/images/font/FontAwesome.otf -------------------------------------------------------------------------------- /vendor/assets/images/font/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/vendor/assets/images/font/fontawesome-webfont.eot -------------------------------------------------------------------------------- /vendor/assets/images/font/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/vendor/assets/images/font/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /vendor/assets/images/font/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/vendor/assets/images/font/fontawesome-webfont.woff -------------------------------------------------------------------------------- /vendor/assets/images/rglossa/spinner-large.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/vendor/assets/images/rglossa/spinner-large.gif -------------------------------------------------------------------------------- /vendor/assets/images/rglossa/spinner-small.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/vendor/assets/images/rglossa/spinner-small.gif -------------------------------------------------------------------------------- /vendor/assets/images/select2-spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/vendor/assets/images/select2-spinner.gif -------------------------------------------------------------------------------- /vendor/assets/images/select2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/vendor/assets/images/select2.png -------------------------------------------------------------------------------- /vendor/assets/images/select2x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/vendor/assets/images/select2x2.png -------------------------------------------------------------------------------- /vendor/assets/javascripts/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/vendor/assets/javascripts/.gitkeep -------------------------------------------------------------------------------- /vendor/assets/javascripts/dialog.jsx: -------------------------------------------------------------------------------- 1 | /** @jsx React.DOM */ 2 | 3 | // React class for Bootstrap dialog 4 | // Modified version of the one from https://gist.github.com/Daniel15/8321579 5 | 6 | var Dialog = React.createClass({ 7 | getInitialState: function() { 8 | return { 9 | className: 'modal fade' 10 | }; 11 | }, 12 | show: function() { 13 | this.setState({ className: 'modal fade show' }); 14 | setTimeout(function() { 15 | this.setState({ className: 'modal fade show in' }); 16 | }.bind(this), 0); 17 | }, 18 | hide: function() { 19 | // Fade out the help dialog, and totally hide it after a set timeout 20 | // (once the fade completes) 21 | this.setState({ className: 'modal fade show' }); 22 | setTimeout(function() { 23 | this.setState({ className: 'modal fade' }); 24 | }.bind(this), 400); 25 | }, 26 | render: function() { 27 | var extraClassName = this.props.extraClassName ? ' ' + this.props.extraClassName : '' 28 | return ( 29 |
    30 |
    31 |
    32 |
    33 | 34 |

    {this.props.title}

    35 |
    36 |
    37 | {this.props.children} 38 |
    39 |
    40 | 41 |
    42 |
    43 |
    44 |
    45 | ); 46 | } 47 | }); -------------------------------------------------------------------------------- /vendor/assets/javascripts/jquery.spin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2011-2013 Felix Gnass 3 | * Licensed under the MIT license 4 | */ 5 | 6 | /* 7 | 8 | Basic Usage: 9 | ============ 10 | 11 | $('#el').spin(); // Creates a default Spinner using the text color of #el. 12 | $('#el').spin({ ... }); // Creates a Spinner using the provided options. 13 | 14 | $('#el').spin(false); // Stops and removes the spinner. 15 | 16 | Using Presets: 17 | ============== 18 | 19 | $('#el').spin('small'); // Creates a 'small' Spinner using the text color of #el. 20 | $('#el').spin('large', '#fff'); // Creates a 'large' white Spinner. 21 | 22 | Adding a custom preset: 23 | ======================= 24 | 25 | $.fn.spin.presets.flower = { 26 | lines: 9 27 | length: 10 28 | width: 20 29 | radius: 0 30 | } 31 | 32 | $('#el').spin('flower', 'red'); 33 | 34 | */ 35 | 36 | (function(factory) { 37 | 38 | if (typeof exports == 'object') { 39 | // CommonJS 40 | factory(require('jquery'), require('spin')) 41 | } 42 | else if (typeof define == 'function' && define.amd) { 43 | // AMD, register as anonymous module 44 | define(['jquery', 'spin'], factory) 45 | } 46 | else { 47 | // Browser globals 48 | if (!window.Spinner) throw new Error('Spin.js not present') 49 | factory(window.jQuery, window.Spinner) 50 | } 51 | 52 | }(function($, Spinner) { 53 | 54 | $.fn.spin = function(opts, color) { 55 | 56 | return this.each(function() { 57 | var $this = $(this), 58 | data = $this.data(); 59 | 60 | if (data.spinner) { 61 | data.spinner.stop(); 62 | delete data.spinner; 63 | } 64 | if (opts !== false) { 65 | opts = $.extend( 66 | { color: color || $this.css('color') }, 67 | $.fn.spin.presets[opts] || opts 68 | ) 69 | data.spinner = new Spinner(opts).spin(this) 70 | } 71 | }) 72 | } 73 | 74 | $.fn.spin.presets = { 75 | tiny: { lines: 8, length: 2, width: 2, radius: 3 }, 76 | small: { lines: 8, length: 4, width: 3, radius: 5 }, 77 | large: { lines: 10, length: 8, width: 4, radius: 8 } 78 | } 79 | 80 | })); 81 | -------------------------------------------------------------------------------- /vendor/assets/stylesheets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/vendor/assets/stylesheets/.gitkeep -------------------------------------------------------------------------------- /vendor/assets/stylesheets/bootstrap-tags.css: -------------------------------------------------------------------------------- 1 | /* bootstrap-tags styles */ 2 | 3 | .tag-list { 4 | width: 280px; 5 | height: 26px; 6 | left:2px; 7 | top:2px; 8 | position:relative; 9 | } 10 | .tag-data { 11 | display:none; 12 | } 13 | .tags-input { 14 | width:100%; 15 | height:18px !important; 16 | margin:0; 17 | padding-bottom:0 !important; 18 | font-size:12px !important; 19 | } 20 | .tags { 21 | width:inherit; 22 | height:0; 23 | position:absolute; 24 | padding:0; 25 | margin:0; 26 | } 27 | .tag { 28 | padding: 1px 3px; 29 | margin:1px; 30 | float:left; 31 | } 32 | .tag a { 33 | color: #bbb; 34 | cursor:pointer; 35 | opacity: .5; 36 | } 37 | ul.tags-suggestion-list { 38 | width:100%; 39 | height:auto; 40 | list-style:none; 41 | margin:0; 42 | position:absolute; 43 | z-index:2; 44 | max-height:160px; 45 | overflow: scroll; 46 | } 47 | li.tags-suggestion { 48 | padding:3px 20px; 49 | height:auto; 50 | } 51 | li.tags-suggestion-highlighted { 52 | color: white; 53 | text-decoration: none; 54 | background-color: #0081C2; 55 | background-image: -moz-linear-gradient(top, #08C, #0077B3); 56 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#08C), to(#0077B3)); 57 | background-image: -webkit-linear-gradient(top, #08C, #0077B3); 58 | background-image: -o-linear-gradient(top, #08C, #0077B3); 59 | background-image: linear-gradient(to bottom, #08C, #0077B3); 60 | background-repeat: repeat-x; 61 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); 62 | } 63 | .fixed-width { 64 | width:800px; 65 | margin:0 auto; 66 | } -------------------------------------------------------------------------------- /vendor/plugins/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textlab/glossa/27904bdc9b3bcbcac9921e23b577b8c72720c068/vendor/plugins/.gitkeep -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | entry: "./app/assets/javascripts/rglossa/entry.js", 3 | output: { 4 | path: "./app/assets/javascripts/rglossa", 5 | filename: "bundle.js" 6 | }, 7 | module: { 8 | loaders: [ 9 | { test: /\.jsx?$/, loader: 'jsx' } 10 | ] 11 | } 12 | }; --------------------------------------------------------------------------------