--- /dev/null
+from django.contrib import admin
+from htsworkflow.frontend.bcmagic.models import KeywordMap
+
+class KeywordMapAdmin(admin.ModelAdmin):
+ list_display = ('keyword','regex', 'url_template')
+
+admin.site.register(KeywordMap, KeywordMapAdmin)
\ No newline at end of file
--- /dev/null
+from django import forms
+
+class BarcodeMagicForm(forms.Form):
+ magic = forms.CharField(label="Barcode Magic", required=False)
+ bcm_mode = forms.CharField(widget=forms.HiddenInput, initial="default")
+
+ class Media:
+ js = ('js/jquery.timers-1.0.0.js',
+ 'js/bcmagic-ext.js')
--- /dev/null
+from django.db import models
+
+class KeywordMap(models.Model):
+ """
+ Mapper object maps keyword|arg1|arg2|...|argN to REST urls
+ """
+ keyword = models.CharField(max_length=64)
+ regex = models.CharField(max_length=1024)
+ url_template = models.TextField()
--- /dev/null
+#from htsworkflow.frontend.samples import bcm_cmds
+
+#BCM_PLUGINS = {'cmd_move_sample': bcm_cmds.cmd_move_sample}
+
+
+def bcm_plugin_processor(keyword, text, bcm_mode):
+ """
+ Fixme should be made generic plugable, but am hard coding values for proof
+ of concept.
+ """
+ d = {}
+
+ if bcm_mode not in BCM_PLUGINS:
+ d['mode'] = 'Error'
+ d['status'] = 'bcm_mode plugin called "%s" was not found' % (bcm_mode)
+ return d
+
+ return BCM_PLUGINS[bcm_mode](keyword, text, bcm_mode)
\ No newline at end of file
--- /dev/null
+from django.conf.urls.defaults import *
+
+urlpatterns = patterns('',
+ (r'^json_test/$', 'htsworkflow.frontend.bcmagic.views.json_test'),
+ (r'^magic/$', 'htsworkflow.frontend.bcmagic.views.magic'),
+ (r'^$', 'htsworkflow.frontend.bcmagic.views.index'),
+)
\ No newline at end of file
--- /dev/null
+
+
+def report_error(message):
+ """
+ Return a dictionary with a command to display 'message'
+ """
+ return {'mode': 'Error', 'status': message}
+
+
+def redirect_to_url(url):
+ """
+ Return a bcm dictionary with a command to redirect to 'url'
+ """
+ return {'mode': 'redirect', 'url': url}
+
+
+def autofill(field, value):
+ """
+ Return a bcm dictionary with a command to automatically fill the
+ corresponding "field" with "value"
+ """
+ return {'mode': 'autofill', 'field': field, 'value': value}
\ No newline at end of file
--- /dev/null
+from django.http import HttpResponse
+from django.template import RequestContext, Template, Context
+from django.shortcuts import render_to_response
+from django.core.exceptions import ObjectDoesNotExist
+
+from htsworkflow.frontend.bcmagic import models
+from htsworkflow.frontend.bcmagic.utils import report_error, redirect_to_url
+from htsworkflow.frontend.bcmagic.plugin import bcm_plugin_processor
+
+import json
+import re
+
+from htsworkflow.frontend.bcmagic import forms
+
+def index(request):
+ """
+ Display a barcode magic input box
+ """
+ form = forms.BarcodeMagicForm()
+
+ return render_to_response('bcmagic/magic.html', {'bcmagic': form},
+ context_instance=RequestContext(request))
+
+
+def __magic_process(text):
+ """
+ Based on scanned text, check to see if there is map object to use
+ for a useful redirect.
+ """
+ # Split text on |
+ split_text = text.split('|')
+
+ # There should always be at least one | in a valid scan.
+ if len(split_text) <= 1:
+ return report_error('Invalid text: %s' % (text))
+
+ # Keyword is the first element in the list
+ keyword = split_text[0]
+
+ # Attempt to find a KeywordMap based on keyword
+ try:
+ keymap = models.KeywordMap.objects.get(keyword=keyword)
+ except ObjectDoesNotExist, e:
+ return report_error('Keyword (%s) is not defined' % (keyword))
+
+ # Remove keyword and only scan the content
+ content = '|'.join(split_text[1:])
+
+ #FIXME: would be faster to cache compiled regex
+ search = re.compile(keymap.regex)
+
+ mo = search.search(content)
+
+ # if the search was invalid
+ if not mo:
+ return report_error('(%s) failed to match (%s)' % (keymap.regex, content))
+
+ t = Template(keymap.url_template)
+ c = Context(mo.groupdict())
+
+ return redirect_to_url(str(t.render(c)))
+
+
+
+
+
+def magic(request):
+ """
+ Let the magic begin
+ """
+ d = {}
+
+ #Retrieve posted text from processing
+ if 'text' in request.POST:
+ text = request.POST['text']
+ else:
+ text = None
+
+ #Retrieve bmc_mode for processing
+ if 'bcm_mode' in request.POST:
+ bcm_mode = request.POST['bcm_mode']
+ else:
+ bcm_mode = None
+
+ ################################
+ # Handle some errors
+ ################################
+
+ # Did not receive text error
+ if text is None or text.strip() == '':
+ d['mode'] = 'Error'
+ d['status'] = 'Did not recieve text'
+ j = json.JSONEncoder()
+ return HttpResponse(j.encode(d), 'text/plain')
+
+ # Did not receive bcm_mode error
+ if bcm_mode is None or bcm_mode.strip() == '':
+ d['mode'] = 'Error'
+ d['status'] = 'Missing bcm_mode information'
+
+
+ ################################
+ # Figure out which mode to use
+ ################################
+ keyword = text.split('|')[0]
+
+ # Handle URL mode by default
+ if keyword == 'url':
+ d['mode'] = 'redirect'
+ d['url'] = text.split('|')[1]
+
+ # Pass off processing to plugins
+ elif bcm_mode != 'default':
+ d = bcm_plugin_processor(keyword, text, bcm_mode)
+
+ # Try keyword mapper
+ else:
+ d = __magic_process(text)
+ j = json.JSONEncoder()
+ return HttpResponse(j.encode(d), 'text/plain')
+
+
+
+def json_test(request):
+ d = {}
+
+ if 'text' in request.POST:
+ text = request.POST['text']
+ else:
+ text = None
+
+ #return HttpResponse(json.write(request.POST.items()), 'text/plain')
+ if text is None or text.strip() == '':
+ d['mode'] = 'Error'
+ d['status'] = 'Did not recieve text'
+ return HttpResponse(json.write(d), 'text/plain')
+
+ if text.split('|')[0] == 'url':
+ d['mode'] = 'redirect'
+ d['url'] = text.split('|')[1]
+ else:
+ d['msg'] = 'Recieved text: %s' % (text)
+ d['mode'] = 'clear'
+
+ j = json.JSONEncoder()
+ return HttpResponse(j.encode(d), 'text/plain')
from htsworkflow.frontend.samples.changelist import ChangeList
from htsworkflow.frontend.samples.models import Library
from htsworkflow.frontend.samples.results import get_flowcell_result_dict, parse_flowcell_id
+from htsworkflow.frontend.bcmagic.forms import BarcodeMagicForm
from htsworkflow.pipelines.runfolder import load_pipeline_run_xml
from htsworkflow.pipelines import runfolder
from htsworkflow.frontend import settings
LANE_LIST = [1,2,3,4,5,6,7,8]
SAMPLES_CONTEXT_DEFAULTS = {
- 'app_name': 'Flowcell/Library Tracker'
+ 'app_name': 'Flowcell/Library Tracker',
+ 'bcmagic': BarcodeMagicForm()
}
def create_library_context(cl):
--- /dev/null
+//-----------------------------------------------
+// Barcode Magic JavaScript
+// Authors: Brandon W. King
+// Feb. 2009
+//-----------------------------------------------
+
+//---------------------------------------
+// BCMagic Core Processing AJAX Callback
+//---------------------------------------
+//var bcmagic_process_callback = function(data, textStatus) {
+var bcmagic_process_callback = function(response, opt) {
+ //FIXME: temp bypass hack
+ var textStatus = 'success';
+ if (textStatus != 'success')
+ {
+ bcmagic_message('AJAX Status: '+textStatus);
+ return;
+ }
+
+ var data = Ext.decode(response.responseText);
+
+ for (key in data)
+ {
+ if (key == 'mode')
+ {
+ if (data['mode'] == 'clear')
+ {
+ bcmagic_status('','');
+ }
+ else if (data['mode'] == 'redirect')
+ {
+ if ('url' in data)
+ {
+ bcmagic_redirect(data['url']);
+ }
+ else
+ {
+ bcmagic_status('Error', 'No redirect URL provided by server');
+ }
+ }
+ else if (data['mode'] == 'autofill')
+ {
+ bcmagic_autofill(data['field'], data['value'])
+ }
+ else {
+ bcmagic_message('Message recieved!');
+ bcmagic_status(data['mode'], data['status']);
+ }
+
+ }
+ if (key == 'msg')
+ {
+ bcmagic_message(data['msg']);
+ }
+ }
+}
+
+var bcmagic_callback = function(data, textStatus)
+{
+ if (textStatus != 'success')
+ bcmagic_message('Failed!');
+ else
+ bcmagic_message('Success!');
+}
+
+var bcmagic_process = function(){
+ var magic = Ext.get("bcmagic_input_field");
+ var text = magic.getValue();
+ magic.dom.value = '';
+ magic.focus();
+
+ //var bcm_mode = $("#id_bcm_mode");
+ //var mode = bcm_mode.attr('value');
+ var mode = 'default';
+
+ // Show what we have captured
+ bcmagic_message('Sent command to server');
+ //$.post('/bcmagic/magic/', {'text': text, 'bcm_mode': mode}, bcmagic_process_callback, 'json');
+ Ext.Ajax.request({
+ url: '/bcmagic/magic/',
+ success: bcmagic_process_callback,
+ failure: function (r, o) { quick_msg('Some AJAX Fail!'); },
+ params: {'text': text, 'bcm_mode': mode}
+ });
+}
+
+var bcmagic_keyhandler = function(e) {
+ //Process upon enter key as input.
+ if (e.which == 13)
+ bcmagic_process();
+}
+
+//---------------------------------------
+// Utility Functions
+//---------------------------------------
+var bcmagic_message = function(text)
+{
+ // Show message
+ //$("#bcm_msg").html(text);
+ quick_msg(text);
+
+ // clear message after 3000ms
+ /*
+ setTimeout(function() {
+ $("#bcm_msg").html('');
+ }, 3000);
+ */
+}
+
+var bcmagic_status = function(state, text)
+{
+ //var msg = $('#bcm_status');
+ if (state.length > 0 || text.length > 0)
+ quick_msg(state+': '+text);
+ //else
+ // msg.html('');
+}
+
+
+var bcmagic_redirect = function(url)
+{
+ bcmagic_message('Redirecting to:' + url);
+ window.location = url;
+}
+
+var bcmagic_autofill = function(field, val)
+{
+ var txtbox = $('#'+field);
+ txtbox.attr('value', val);
+
+ var input_fields = $('form input').not(':hidden').not('[type=submit]');
+
+ // Count the number of text fields which have been filled in.
+ var count = 0;
+ input_fields.each( function(){
+ if(this.value.length > 0){
+ count = count + 1;
+ }
+ });
+
+ // If the number of text fields filled in is equal to the number of input_fields in the form, submit the form!
+ if (count == input_fields.length)
+ {
+ bcmagic_status('Form Full', 'Form is now full and ready to process');
+ form = $('form');
+ form.submit();
+ form.reset();
+
+ }
+ else
+ {
+ bcmagic_status('Form Fill Count', 'Count(' + count +') - Total(' + input_fields.length + ')');
+ }
+}
+
+//---------------------------------------
+// Main Ready Function
+//---------------------------------------
+/*$(document).ready(function() {
+
+ // Grab initial focus on magic text input
+ $("#id_magic").focus();
+
+ // Set some initial text
+ //$("#id_magic").attr('value','Moo cow!');
+
+ // Trigger when enterkey is pressed
+ $("#id_magic").keypress(bcmagic_keyhandler)
+});*/
\ No newline at end of file
// Shifts the remaining toolbar options to the right side.
main_tb.add({ xtype: 'tbfill' });
+
+ //----------------------------------------
+ // ExtJS Barcode Magic Implementation
+ var bcmagic_ext_keyhandler = function(sObj, e){
+ //e.preventDefault();
+ //Process upon enter key as input.
+ if (e.getKey() == e.ENTER)
+ bcmagic_process();
+ }
+
+ var bcmagic_input = new Ext.form.TextField({
+ id: 'bcmagic_input_field',
+ emptyText: 'barcode magic'
+ });
+ bcmagic_input.on('specialkey', bcmagic_ext_keyhandler);
+
+ main_tb.add(bcmagic_input);
+ //--------------------------------------
+
var user_info = Ext.fly('login_info');
var logout_url = user_info.getAttribute('logouturl');
var login_url = user_info.getAttribute('loginurl');
add_buttons_from_html(app_tb, 'app_toolbar_east');
app_tb.doLayout();
-
+ // Focus on barcode magic, because it's awesome and needs attention! ;-)
+ bcmagic_input.focus();
});
\ No newline at end of file
//---------------------------------------
// Main Ready Function
//---------------------------------------
-$(document).ready(function() {
+/*$(document).ready(function() {
// Grab initial focus on magic text input
$("#id_magic").focus();
// Trigger when enterkey is pressed
$("#id_magic").keypress(bcmagic_keyhandler)
-});
\ No newline at end of file
+});*/
\ No newline at end of file
</div>
<!-- Barcode Magic Div -->
+ <!--
<div id="bcmagic_div" class="x-hidden">
- {% include "magic.html" %}
+ {% include "bcmagic/magic.html" %}
</div>
+ -->
{% block east_region %}
<div id="east_region_config" class="x-hidden">{% if east_region_config_div %}{{ east_region_config_div }}{% endif %}</div>
--- /dev/null
+<div id="bcm_msg"></div>
+{{ bcmagic }}<br />
+<div id="bcm_status"></div>
+++ /dev/null
-<div id="bcm_msg"></div>
-{{ bcmagic }}<br />
-<div id="bcm_status"></div>
'htsworkflow.frontend.samples.views.bedfile_fc_cnm_eland_lane_ucsc'),
(r'^results/(?P<fc_id>\w+)/(?P<cnm>C[1-9]-[0-9]+)/bedfile/(?P<lane>[1-8])',
'htsworkflow.frontend.samples.views.bedfile_fc_cnm_eland_lane'),
+ (r'^bcmagic/', include('htsworkflow.frontend.bcmagic.urls')),
# databrowser
#(r'^databrowse/(.*)', databrowse.site.root)