Commit f4b77eb2 authored by Oliver Feldt's avatar Oliver Feldt
Browse files

Late Initial Commit

parents
/.bundle/
/.yardoc
/.sass-cache
/Gemfile.lock
/_yardoc/
/coverage/
/doc/
/pkg/
/spec/reports/
/tmp/
*.bundle
*.so
*.o
*.a
mkmf.log
*.db
source 'https://rubygems.org'
# Specify your gem's dependencies in ccc_roc.gemspec
gemspec
Copyright (c) 2014 Oliver Feldt
MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# CccRoc
TODO: Write a gem description
## Installation
Add this line to your application's Gemfile:
```ruby
gem 'ccc_roc'
```
And then execute:
$ bundle
Or install it yourself as:
$ gem install ccc_roc
## Usage
TODO: Write usage instructions here
## Contributing
1. Fork it ( https://github.com/[my-github-username]/ccc_roc/fork )
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a new Pull Request
require "bundler/gem_tasks"
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'ccc_roc/version'
Gem::Specification.new do |spec|
spec.name = "ccc_roc"
spec.version = CccRoc::VERSION
spec.authors = ["Oliver 'jen' Feldt"]
spec.email = ["jen@hamburg.ccc.de"]
spec.summary = %q{TODO: Write a short summary. Required.}
spec.description = %q{TODO: Write a longer description. Optional.}
spec.homepage = ""
spec.license = "MIT"
spec.files = `git ls-files -z`.split("\x0")
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]
spec.add_development_dependency "bundler", "~> 1.7"
spec.add_development_dependency "rake", "~> 10.0"
# web server
spec.add_runtime_dependency "thin", "~> 1.6.3"
# web framework
spec.add_runtime_dependency "sinatra", "~> 1.4.5"
spec.add_runtime_dependency "sinatra-contrib", "~> 1.4.2"
spec.add_runtime_dependency "sinatra-assetpack", "~> 0.3.3"
spec.add_runtime_dependency 'sinatra-flash', '0.3.0'
# auth
spec.add_runtime_dependency 'warden', '1.2.1'
# views
spec.add_runtime_dependency "slim", "~> 3.0.0"
spec.add_runtime_dependency "sass", "~> 3.4.9"
# models
spec.add_runtime_dependency "data_mapper", "~> 1.2.0"
spec.add_runtime_dependency "dm-sqlite-adapter", "~> 1.2.0"
end
require 'rubygems'
require 'bundler'
ENV['BUNDLE_GEMFILE'] ||= File.join(File.dirname(__FILE__), "Gemfile")
ENV['RACK_ENV'] ||= "testing"
Bundler.require(:default, ENV['RACK_ENV'])
require 'ccc_roc'
run CCC::ROC::Application
$.delete = function(url, data, callback, type){
if ( $.isFunction(data) ){
type = type || callback,
callback = data,
data = {}
}
return $.ajax({
url: url,
type: 'DELETE',
success: callback,
data: data,
contentType: type
});
}
$.put = function(url, data, callback, type){
if ( $.isFunction(data) ){
type = type || callback,
callback = data,
data = {}
}
return $.ajax({
url: url,
type: 'PUT',
success: callback,
data: data,
contentType: type
});
}
jQuery.each( [ "put", "delete" ], function( i, method ) {
jQuery[ method ] = function( url, data, callback, type ) {
if ( jQuery.isFunction( data ) ) {
type = type || callback;
callback = data;
data = undefined;
}
return jQuery.ajax({
url: url,
type: method,
dataType: type,
data: data,
success: callback
});
};
});
$("#search_form").on("submit", function(e) {
var radio_id = $("#radio_id").val();
$.getJSON(
"/radios",
$(this).serialize(),
function (data) {
var radio = data.radio;
var checkouts = data.checkouts;
if (radio.id === null) {
$("#new_radio_form input[name='radio_id']").val(radio.name);
$("#new_radio").modal("show");
} else {
var current_checkout = checkouts[checkouts.length - 1];
if (current_checkout !== undefined) {
$("#radio_form input[name='angel']").val(current_checkout.angel);
}
$("#radio_form input[name='radio_id']").val(radio.name);
$("#radio").modal("show");
}
}
);
e.preventDefault();
});
$("#radio").on("submit", function(e) { e.preventDefault(); });
$("#radio button[name='switch']").on("click", function(e) {
$.post(
"/checkouts",
$("#radio_form").serialize(),
function (data) {
var radio = data.radio;
var angel = data.angel;
if (radio.id !== undefined) {
$("#radio").modal("hide");
$("#radio_id").focus();
var radio_row = $("#radios tr[data-id='" + radio.id + "']");
var current_angel = radio_row.children(".current_angel").html();
if (current_angel !== "") {
radio_row.children(".previous_angel").html(current_angel);
}
radio_row.children(".current_angel").html(angel);
radio_row.data("last_scanned_at", new Date());
radio_row.data("checked_out_at", new Date());
set_time_interval();
radio_row.addClass("info");
radio_row.removeClass("success");
}
},
"json"
);
});
$("#radio button[name='return']").on("click", function(e) {
$.delete(
"/checkouts",
$("#radio_form").serialize(),
function (data) {
var radio = data;
if (radio.id !== undefined) {
$("#radio").modal("hide");
$("#radio_id").focus();
var radio_row = $("#radios tr[data-id='" + radio.id + "']");
radio_row.children(".previous_angel").html(
radio_row.children(".current_angel").html()
);
radio_row.children(".current_angel").html("");
radio_row.data("last_scanned_at", new Date());
set_time_interval();
radio_row.addClass("success");
radio_row.removeClass("info");
}
},
"json"
);
});
$("#new_radio").on("submit", function(e) {
var radio_id = $("#new_radio_form input[name='radio_id']").val();
$.post(
"/radios",
$("#new_radio_form").serialize(),
function (data) {
var radio = data;
if (radio.id !== null) {
$("#new_radio").modal("hide");
}
},
"json"
);
e.preventDefault();
});
$("#radios").on("click", function(e) {
var radio_item = $(e.target).parent();
var radio = {
name: radio_item.data("name"),
angel: radio_item.data("angel")
};
$("#radio_form input[name='radio_id']").val(radio.name);
$("#radio_form input[name='angel']").val(radio.angel);
var switch_button_text = radio.angel === undefined ? "Set Angel" : "Switch Angel";
if (radio.angel === undefined) {
$("#radio_form button[name='return']").addClass("disabled");
} else {
$("#radio_form button[name='return']").removeClass("disabled");
}
$("#radio_form button[name='switch']").html(switch_button_text);
$("#radio_header").html(radio.name);
$("#radio").modal("show");
$.getJSON(
"/checkouts",
{ radio_id: radio.name },
function(data) {
var checkouts = data;
$("#checkouts tbody").empty();
for (var index = 0; index < checkouts.length; index++) {
var angel = checkouts[index].angel;
var checked_in_at = checkouts[index].checked_in_at;
if (checked_in_at === null) { checked_in_at = "Still Out" }
$("#checkouts tbody").append("<tr><td>" + angel + "</td><td>" +checked_in_at + "</td></tr>")
}
}
)
});
$("#radio_form input[name='angel']").on("focus", function() {
$(this).data("value", $(this).val());
$(this).val("");
})
$("#radio_form input[name='angel']").on("blur", function() {
if ($(this).val() === "") {
$(this).val($(this).data("value"));
$(this).data("value", undefined);
}
})
function set_time_interval() {
$("#radios .checked_out_at").each(function(_, item) {
item = $(item);
if (item.parent().data("checked_out_at") !== undefined) {
item.html(moment(item.parent().data("checked_out_at")).fromNow());
}
});
$("#radios .last_scanned_at").each(function(_, item) {
item = $(item);
if (item.parent().data("last_scanned_at") !== undefined) {
item.html(moment(item.parent().data("last_scanned_at")).fromNow());
}
});
}
$(function() {
$("#radio_id").focus();
set_time_interval();
setInterval(set_time_interval, 5000);
});
$('#radio, #new_radio').on('hidden.bs.modal', function (e) {
$("#radio_id").focus();
})
@function twbs-font-path($path) {
@return font-url($path, true);
}
@function twbs-image-path($path) {
@return image-url($path, true);
}
// Mincer asset helper functions
//
// This must be imported into a .css.ejs.scss file.
// Then, <% %>-interpolations will be parsed as strings by Sass, and evaluated by EJS after Sass compilation.
@function twbs-font-path($path) {
// do something like following
// from "path/to/font.ext#suffix" to "<%- asset_path(path/to/font.ext)) + #suffix %>"
// from "path/to/font.ext?#suffix" to "<%- asset_path(path/to/font.ext)) + ?#suffix %>"
// or from "path/to/font.ext" just "<%- asset_path(path/to/font.ext)) %>"
@return "<%- asset_path('#{$path}'.replace(/[#?].*$/, '')) + '#{$path}'.replace(/(^[^#?]*)([#?]?.*$)/, '$2') %>";
}
@function twbs-image-path($file) {
@return "<%- asset_path('#{$file}') %>";
}
@function twbs-font-path($path) {
@return font-path($path);
}
@function twbs-image-path($path) {
@return image-path($path);
}
// Core variables and mixins
@import "bootstrap/variables";
@import "bootstrap/mixins";
// Reset and dependencies
@import "bootstrap/normalize";
@import "bootstrap/print";
@import "bootstrap/glyphicons";
// Core CSS
@import "bootstrap/scaffolding";
@import "bootstrap/type";
@import "bootstrap/code";
@import "bootstrap/grid";
@import "bootstrap/tables";
@import "bootstrap/forms";
@import "bootstrap/buttons";
// Components
@import "bootstrap/component-animations";
@import "bootstrap/dropdowns";
@import "bootstrap/button-groups";
@import "bootstrap/input-groups";
@import "bootstrap/navs";
@import "bootstrap/navbar";
@import "bootstrap/breadcrumbs";
@import "bootstrap/pagination";
@import "bootstrap/pager";
@import "bootstrap/labels";
@import "bootstrap/badges";
@import "bootstrap/jumbotron";
@import "bootstrap/thumbnails";
@import "bootstrap/alerts";
@import "bootstrap/progress-bars";
@import "bootstrap/media";
@import "bootstrap/list-group";
@import "bootstrap/panels";
@import "bootstrap/responsive-embed";
@import "bootstrap/wells";
@import "bootstrap/close";
// Components w/ JavaScript
@import "bootstrap/modals";
@import "bootstrap/tooltip";
@import "bootstrap/popovers";
@import "bootstrap/carousel";
// Utility classes
@import "bootstrap/utilities";
@import "bootstrap/responsive-utilities";
@import bootstrap
body
padding-top: 50px
//
// Alerts
// --------------------------------------------------
// Base styles
// -------------------------
.alert {
padding: $alert-padding;
margin-bottom: $line-height-computed;
border: 1px solid transparent;
border-radius: $alert-border-radius;
// Headings for larger alerts
h4 {
margin-top: 0;
// Specified for the h4 to prevent conflicts of changing $headings-color
color: inherit;
}
// Provide class for links that match alerts
.alert-link {
font-weight: $alert-link-font-weight;
}
// Improve alignment and spacing of inner content
> p,
> ul {
margin-bottom: 0;
}
> p + p {
margin-top: 5px;
}
}
// Dismissible alerts
//
// Expand the right padding and account for the close button's positioning.
.alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0.
.alert-dismissible {
padding-right: ($alert-padding + 20);
// Adjust close link position
.close {
position: relative;
top: -2px;
right: -21px;
color: inherit;
}
}
// Alternate styles
//
// Generate contextual modifier classes for colorizing the alert.
.alert-success {
@include alert-variant($alert-success-bg, $alert-success-border, $alert-success-text);
}
.alert-info {
@include alert-variant($alert-info-bg, $alert-info-border, $alert-info-text);
}
.alert-warning {
@include alert-variant($alert-warning-bg, $alert-warning-border, $alert-warning-text);
}
.alert-danger {
@include alert-variant($alert-danger-bg, $alert-danger-border, $alert-danger-text);
}
//
// Badges
// --------------------------------------------------
// Base class
.badge {
display: inline-block;
min-width: 10px;
padding: 3px 7px;
font-size: $font-size-small;
font-weight: $badge-font-weight;
color: $badge-color;
line-height: $badge-line-height;
vertical-align: baseline;
white-space: nowrap;
text-align: center;
background-color: $badge-bg;
border-radius: $badge-border-radius;
// Empty badges collapse automatically (not available in IE8)
&:empty {
display: none;
}
// Quick fix for badges in buttons
.btn & {
position: relative;
top: -1px;
}
.btn-xs & {
top: 0;
padding: 1px 5px;
}
// [converter] extracted a& to a.badge
// Account for badges in navs
.list-group-item.active > &,
.nav-pills > .active > a > & {
color: $badge-active-color;
background-color: $badge-active-bg;
}
.list-group-item > & {
float: right;
}
.list-group-item > & + & {
margin-right: 5px;
}
.nav-pills > li > a > & {
margin-left: 3px;
}
}
// Hover state, but only for links
a.badge {
&:hover,
&:focus {
color: $badge-link-hover-color;
text-decoration: none;
cursor: pointer;
}
}
//
// Breadcrumbs
// --------------------------------------------------
.breadcrumb {
padding: $breadcrumb-padding-vertical $breadcrumb-padding-horizontal;
margin-bottom: $line-height-computed;
list-style: none;
background-color: $breadcrumb-bg;
border-radius: $border-radius-base;
> li {
display: inline-block;
+ li:before {
content: "#{$breadcrumb-separator}\00a0"; // Unicode space added since inline-block means non-collapsing white-space
padding: 0 5px;
color: $breadcrumb-color;
}
}