Переглянути джерело

HUE-1805 [spark] Second version with REST Job Server

Async query execution
Select context automatically or create/pick one
Create context
Delete contexts
Upload jar

Todo:
save a script
support result different than a map
add history in navigator
add link to job to open them with their result
parameted editor
consolidate menu bar
default classpath to empty
lot of UX

In Job Server:
more infor from API (to be continued)
Romain Rigaux 12 роки тому
батько
коміт
07f87d87b1
40 змінених файлів з 2312 додано та 7216 видалено
  1. 2 2
      apps/beeswax/src/beeswax/models.py
  2. 9 1
      apps/beeswax/src/beeswax/templates/layout.mako
  3. 1 0
      apps/spark/src/spark/__init__.py
  4. 262 233
      apps/spark/src/spark/api.py
  5. 25 13
      apps/spark/src/spark/conf.py
  6. 113 0
      apps/spark/src/spark/design.py
  7. 30 0
      apps/spark/src/spark/forms.py
  8. 109 0
      apps/spark/src/spark/job_server_api.py
  9. 0 461
      apps/spark/src/spark/locale/de/LC_MESSAGES/django.po
  10. 0 383
      apps/spark/src/spark/locale/en/LC_MESSAGES/django.po
  11. 0 382
      apps/spark/src/spark/locale/en_US.pot
  12. 0 461
      apps/spark/src/spark/locale/es/LC_MESSAGES/django.po
  13. 0 461
      apps/spark/src/spark/locale/fr/LC_MESSAGES/django.po
  14. 0 461
      apps/spark/src/spark/locale/ja/LC_MESSAGES/django.po
  15. 0 461
      apps/spark/src/spark/locale/ko/LC_MESSAGES/django.po
  16. 0 461
      apps/spark/src/spark/locale/pt/LC_MESSAGES/django.po
  17. 0 461
      apps/spark/src/spark/locale/pt_BR/LC_MESSAGES/django.po
  18. 0 461
      apps/spark/src/spark/locale/zh_CN/LC_MESSAGES/django.po
  19. 0 0
      apps/spark/src/spark/management/__init__.py
  20. 0 0
      apps/spark/src/spark/management/commands/__init__.py
  21. 0 87
      apps/spark/src/spark/migrations/0001_initial.py
  22. 0 0
      apps/spark/src/spark/migrations/__init__.py
  23. 0 122
      apps/spark/src/spark/models.py
  24. 2 1
      apps/spark/src/spark/settings.py
  25. 0 1041
      apps/spark/src/spark/templates/app.mako
  26. 56 0
      apps/spark/src/spark/templates/common.mako
  27. 659 0
      apps/spark/src/spark/templates/editor.mako
  28. 181 0
      apps/spark/src/spark/templates/list_contexts.mako
  29. 114 0
      apps/spark/src/spark/templates/list_jars.mako
  30. 123 0
      apps/spark/src/spark/templates/list_jobs.mako
  31. 0 154
      apps/spark/src/spark/tests.py
  32. 30 12
      apps/spark/src/spark/urls.py
  33. 116 184
      apps/spark/src/spark/views.py
  34. 0 148
      apps/spark/static/css/spark.css
  35. BIN
      apps/spark/static/help/images/23888161.png
  36. 3 121
      apps/spark/static/help/index.html
  37. 181 0
      apps/spark/static/js/autocomplete.utils.js
  38. 0 606
      apps/spark/static/js/spark.ko.js
  39. 296 0
      apps/spark/static/js/spark.vm.js
  40. 0 38
      apps/spark/static/js/utils.js

+ 2 - 2
apps/beeswax/src/beeswax/models.py

@@ -48,7 +48,7 @@ MYSQL = 'mysql'
 POSTGRESQL = 'postgresql'
 SQLITE = 'sqlite'
 ORACLE = 'oracle'
-QUERY_TYPES = (HQL, IMPALA, RDBMS) = range(3)
+QUERY_TYPES = (HQL, IMPALA, RDBMS, SPARK) = range(4)
 
 
 class QueryHistory(models.Model):
@@ -212,7 +212,7 @@ class SavedQuery(models.Model):
   DEFAULT_NEW_DESIGN_NAME = _('My saved query')
   AUTO_DESIGN_SUFFIX = _(' (new)')
   TYPES = QUERY_TYPES
-  TYPES_MAPPING = {'beeswax': HQL, 'hql': HQL, 'impala': IMPALA, 'rdbms': RDBMS}
+  TYPES_MAPPING = {'beeswax': HQL, 'hql': HQL, 'impala': IMPALA, 'rdbms': RDBMS, 'spark': SPARK}
 
   type = models.IntegerField(null=False)
   owner = models.ForeignKey(User, db_index=True)

+ 9 - 1
apps/beeswax/src/beeswax/templates/layout.mako

@@ -37,10 +37,13 @@ def is_selected(section, matcher):
                 <a href="/${app_name}">
                 % if app_name == 'impala':
                   <img src="/impala/static/art/icon_impala_24.png" />
-                  Impala Editor
+                  ${ current_app.nice_name }
                 % elif app_name == 'rdbms':
                   <img src="/rdbms/static/art/icon_rdbms_24.png" />
                   DB Query
+                % elif app_name == 'spark':
+                  <img src="/spark/static/art/icon_spark_24.png" />
+                  Spark Editor                  
                 % else:
                   <img src="/beeswax/static/art/icon_beeswax_24.png" />
                   Hive Editor
@@ -48,6 +51,11 @@ def is_selected(section, matcher):
                 </a>
               </li>
               <li class="${is_selected(section, 'query')}"><a href="${ url(app_name + ':execute_query') }">${_('Query Editor')}</a></li>
+              % if app_name == 'spark':
+                <li class="class=${is_selected(section, 'jobs')}"><a href="${ url('spark:list_jobs') }">${_('Jobs')}</a></li>
+                <li class="class=${is_selected(section, 'contexts')}"><a href="${ url('spark:list_contexts') }">${_('Contexts')}</a></li>
+                <li class="class=${is_selected(section, 'jars')}"><a href="${ url('spark:list_jars') }">${_('Jars')}</a></li>
+              % endif              
               <li class="${is_selected(section, 'my queries')}"><a href="${ url(app_name + ':my_queries') }">${_('My Queries')}</a></li>
               <li class="${is_selected(section, 'saved queries')}"><a href="${ url(app_name + ':list_designs') }">${_('Saved Queries')}</a></li>
               <li class="${is_selected(section, 'history')}"><a href="${ url(app_name + ':list_query_history') }">${_('History')}</a></li>

+ 1 - 0
apps/spark/src/spark/__init__.py

@@ -1,3 +1,4 @@
+#!/usr/bin/env python
 # Licensed to Cloudera, Inc. under one
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information

+ 262 - 233
apps/spark/src/spark/api.py

@@ -15,263 +15,292 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import datetime
 import json
 import logging
-import re
-import time
 
-from django.core.urlresolvers import reverse
-from django.utils.html import escape
+from django.http import HttpResponse, Http404
 from django.utils.translation import ugettext as _
 
-from spark.conf import SPARK_HOME, SPARK_MASTER
-from desktop.lib.view_util import format_duration_in_millis
-from filebrowser.views import location_to_url
-from jobbrowser.views import job_single_logs
-from liboozie.oozie_api import get_oozie
-from oozie.models import Workflow, Shell
-from oozie.views.editor import _submit_workflow
+from desktop.context_processors import get_app_name
+from desktop.lib.exceptions import StructuredException
+
+from beeswax import models as beeswax_models
+from beeswax.forms import SaveForm
+from beeswax.views import authorized_get_history, safe_get_design
+
+from spark import conf
+from spark.design import SparkDesign
+from spark.views import save_design
+from spark.job_server_api import get_api
+from spark.forms import SparkForm, UploadApp
+import urllib
+
 
 LOG = logging.getLogger(__name__)
 
 
-def get(fs, jt, user):
-  return OozieSparkApi(fs, jt, user)
+class ResultEncoder(json.JSONEncoder):
+  def default(self, obj):
+    if isinstance(obj, datetime.datetime):
+      return obj.strftime('%Y-%m-%d %H:%M:%S %Z')
+    return super(ResultEncoder, self).default(obj)
 
 
-class OozieSparkApi:
-  """
-  Oozie submission.
-  """
-  WORKFLOW_NAME = 'spark-app-hue-script'
-  RE_LOG_END = re.compile('(<<< Invocation of Shell command completed <<<|<<< Invocation of Main class completed <<<)')
-  RE_LOG_START_RUNNING = re.compile('>>> Invoking Shell command line now >>(.+?)(Exit code of the Shell|<<< Invocation of Shell command completed <<<|<<< Invocation of Main class completed)', re.M | re.DOTALL)
-  RE_LOG_START_FINISHED = re.compile('(>>> Invoking Shell command line now >>)', re.M | re.DOTALL)
-  MAX_DASHBOARD_JOBS = 100
+def error_handler(view_fn):
+  def decorator(*args, **kwargs):
+    try:
+      return view_fn(*args, **kwargs)
+    except Http404, e:
+      raise e
+    except Exception, e:
+      response = {
+        'error': str(e)
+      }
+      return HttpResponse(json.dumps(response), mimetype="application/json", status=500)
+  return decorator
 
-  def __init__(self, fs, jt, user):
-    self.fs = fs
-    self.jt = jt
-    self.user = user
 
-  def submit(self, spark_script, params):
-    mapping = {
-      'oozie.use.system.libpath': 'false',
-    }
+def jars(request):
+  api = get_api(request.user)
+  response = {
+    'jars': api.jars()
+  }
 
-    workflow = None
+  return HttpResponse(json.dumps(response), mimetype="application/json")
+
+
+def contexts(request):
+  api = get_api(request.user)
+  response = {
+    'contexts': api.contexts()
+  }
+
+  return HttpResponse(json.dumps(response), mimetype="application/json")
+
+
+def create_context(request):
+  if request.method != 'POST':
+    raise StructuredException(code="INVALID_REQUEST_ERROR", message=_('Requires a POST'))
+  response = {}
+
+  name = request.POST.get('name', '')
+  memPerNode = request.POST.get('memPerNode', '512m')
+  numCores = request.POST.get('numCores', '1')
+
+  api = get_api(request.user)
+  try:
+    response = api.create_context(name, memPerNode=memPerNode, numCores=numCores)
+  except Exception, e:
+    if e.message != 'No JSON object could be decoded':
+      response = json.loads(e.message)
+    else:
+      response = {'status': 'OK'}
+  response['name'] = name
+
+  return HttpResponse(json.dumps(response), mimetype="application/json")
+
+
+def delete_context(request):
+  if request.method != 'DELETE':
+    raise StructuredException(code="INVALID_REQUEST_ERROR", message=_('Requires a DELETE'))
+  response = {}
+
+  name = request.POST.get('name', '')
+
+  api = get_api(request.user)
+  try:
+    response = api.delete_context(name)
+  except Exception, e:
+    if e.message != 'No JSON object could be decoded':
+      response = json.loads(e.message)
+    else:
+      response = {'status': 'OK'}
+  response['name'] = name
+
+  return HttpResponse(json.dumps(response), mimetype="application/json")
+
+
+def job(request, job_id):
+  api = get_api(request.user)
+
+  response = {
+    'results': api.job(job_id)
+  }
+
+  return HttpResponse(json.dumps(response), mimetype="application/json")
+
+
+
+@error_handler
+def execute(request, design_id=None):
+  response = {'status': -1, 'message': ''}
+
+  if request.method != 'POST':
+    response['message'] = _('A POST request is required.')
+
+  app_name = get_app_name(request)
+  query_type = beeswax_models.SavedQuery.TYPES_MAPPING[app_name]
+  design = safe_get_design(request, query_type, design_id)
+
+  try:
+    form = get_query_form(request)
+
+    if form.is_valid():
+      #design = save_design(request, SaveForm(), form, query_type, design)
+
+#      query = SQLdesign(form, query_type=query_type)
+#      query_server = dbms.get_query_server_config(request.POST.get('server'))
+#      db = dbms.get(request.user, query_server)
+#      query_history = db.execute_query(query, design)
+#      query_history.last_state = beeswax_models.QueryHistory.STATE.expired.index
+#      query_history.save()
 
-    try:
-      workflow = self._create_workflow(spark_script, params)
-      oozie_wf = _submit_workflow(self.user, self.fs, self.jt, workflow, mapping)
-    finally:
-      if workflow:
-        workflow.delete()
-
-    return oozie_wf
-
-  def _create_workflow(self, spark_script, params):
-    workflow = Workflow.objects.new_workflow(self.user)
-    workflow.name = OozieSparkApi.WORKFLOW_NAME
-    workflow.is_history = True
-    workflow.save()
-    Workflow.objects.initialize(workflow, self.fs)
-
-    spark_script_path = workflow.deployment_dir + '/spark.script'
-    spark_launcher_path = workflow.deployment_dir + '/spark.sh'
-    self.fs.do_as_user(self.user.username, self.fs.create, spark_script_path, data=spark_script.dict['script'])
-    self.fs.do_as_user(self.user.username, self.fs.create, spark_launcher_path, data="""
-#!/usr/bin/env bash
-
-WORKSPACE=`pwd`
-cd %(spark_home)s
-%(spark_master)s %(spark_shell)s $WORKSPACE/spark.script
-    """ % {
-        'spark_home': SPARK_HOME.get(),
-        'spark_master': 'MASTER=%s' % SPARK_MASTER.get() if SPARK_MASTER.get() != '' else '',
-        'spark_shell': 'pyspark' if spark_script.dict['language'] == 'python' else 'spark-shell <'
-    })
-
-    files = ['spark.script', 'spark.sh']
-    archives = []
-
-    popup_params = json.loads(params)
-    popup_params_names = [param['name'] for param in popup_params]
-    spark_params = self._build_parameters(popup_params)
-    script_params = [param for param in spark_script.dict['parameters'] if param['name'] not in popup_params_names]
-
-    spark_params += self._build_parameters(script_params)
-
-    job_properties = [{"name": prop['name'], "value": prop['value']} for prop in spark_script.dict['hadoopProperties']]
-
-    for resource in spark_script.dict['resources']:
-      if resource['type'] == 'file':
-        files.append(resource['value'])
-      if resource['type'] == 'archive':
-        archives.append({"dummy": "", "name": resource['value']})
-
-    action = Shell.objects.create(
-        name='spark',
-        command='spark.sh',
-        workflow=workflow,
-        node_type='shell',
-        params=json.dumps(spark_params),
-        files=json.dumps(files),
-        archives=json.dumps(archives),
-        job_properties=json.dumps(job_properties),
-    )
-
-    action.add_node(workflow.end)
-
-    start_link = workflow.start.get_link()
-    start_link.child = action
-    start_link.save()
-
-    return workflow
-
-  def _build_parameters(self, params):
-    spark_params = []
-
-    return spark_params
-
-  def stop(self, job_id):
-    return get_oozie(self.user).job_control(job_id, 'kill')
-
-  def get_jobs(self):
-    kwargs = {'cnt': OozieSparkApi.MAX_DASHBOARD_JOBS,}
-    kwargs['user'] = self.user.username
-    kwargs['name'] = OozieSparkApi.WORKFLOW_NAME
-
-    return get_oozie(self.user).get_workflows(**kwargs).jobs
-
-  def get_log(self, request, oozie_workflow):
-    logs = {}
-
-    for action in oozie_workflow.get_working_actions():
       try:
-        if action.externalId:
-          data = job_single_logs(request, **{'job': action.externalId})
-          if data:
-            matched_logs = self._match_logs(data)
-            logs[action.name] = self._make_links(matched_logs)
+        api = get_api(request.user)
+
+        results = api.submit_job(
+            form.cleaned_data['appName'],
+            form.cleaned_data['classPath'],
+            data=form.cleaned_data['query'],
+            context=None if form.cleaned_data['autoContext'] else form.cleaned_data['context'],
+            sync=False
+        )
+        response['status'] = 0
+        response['results'] = results
+        #response['design'] = design.id
       except Exception, e:
-        LOG.error('An error happen while watching the demo running: %(error)s' % {'error': e})
-
-    workflow_actions = []
-
-    # Only one Shell action
-    for action in oozie_workflow.get_working_actions():
-      progress = get_progress(oozie_workflow, logs.get(action.name, ''))
-      appendable = {
-        'name': action.name,
-        'status': action.status,
-        'logs': logs.get(action.name, ''),
-        'progress': progress,
-        'progressPercent': '%d%%' % progress,
-        'absoluteUrl': oozie_workflow.get_absolute_url(),
-      }
-      workflow_actions.append(appendable)
+        response['status'] = -1
+        response['message'] = str(e)
+
+    else:
+      response['message'] = _('There was an error with your query: %s' % form.errors)
+      response['errors'] = form.errors
+  except RuntimeError, e:
+    response['message']= str(e)
 
-    return logs, workflow_actions
+  return HttpResponse(json.dumps(response, cls=ResultEncoder), mimetype="application/json")
 
-  def _match_logs(self, data):
-    """Difficult to match multi lines of text"""
-    logs = data['logs'][1]
 
-    if OozieSparkApi.RE_LOG_END.search(logs):
-      return re.search(OozieSparkApi.RE_LOG_START_RUNNING, logs).group(1).strip()
+@error_handler
+def fetch_results(request, id, first_row=0):
+  """
+  Returns the results of the QueryHistory with the given id.
+
+  The query results MUST be ready.
+
+  If ``first_row`` is 0, restarts (if necessary) the query read.  Otherwise, just
+  spits out a warning if first_row doesn't match the servers conception.
+  Multiple readers will produce a confusing interaction here, and that's known.
+  """
+  first_row = long(first_row)
+  results = type('Result', (object,), {
+                'rows': 0,
+                'columns': [],
+                'has_more': False,
+                'start_row': 0,
+            })
+  fetch_error = False
+  error_message = ''
+
+  query_history = authorized_get_history(request, id, must_exist=True)
+  query_server = query_history.get_query_server_config()
+  design = SQLdesign.loads(query_history.design.data)
+  db = dbms.get(request.user, query_server)
+
+  try:
+    database = design.query.get('database', 'default')
+    db.use(database)
+    datatable = db.execute_and_wait(design)
+    results = db.client.create_result(datatable)
+    status = 0
+  except Exception, e:
+    fetch_error = True
+    error_message = str(e)
+    status = -1
+
+  response = {
+    'status': status,
+    'message': fetch_error and error_message or '',
+    'results': results_to_dict(results)
+  }
+  return HttpResponse(json.dumps(response), mimetype="application/json")
+
+
+@error_handler
+def save_query(request, design_id=None):
+  response = {'status': -1, 'message': ''}
+
+  if request.method != 'POST':
+    response['message'] = _('A POST request is required.')
+
+  app_name = get_app_name(request)
+  query_type = beeswax_models.SavedQuery.TYPES_MAPPING[app_name]
+  design = safe_get_design(request, query_type, design_id)
+
+  try:
+    save_form = SaveForm(request.POST.copy())
+    query_form = get_query_form(request, design_id)
+
+    if query_form.is_valid() and save_form.is_valid():
+      design = save_design(request, save_form, query_form, query_type, design, True)
+      response['design_id'] = design.id
+      response['status'] = 0
     else:
-      group = re.search(OozieSparkApi.RE_LOG_START_FINISHED, logs)
-      i = logs.index(group.group(1)) + len(group.group(1))
-      return logs[i:].strip()
-
-  @classmethod
-  def _make_links(cls, log):
-    escaped_logs = escape(log)
-    hdfs_links = re.sub('((?<= |;)/|hdfs://)[^ <&\t;,\n]+', OozieSparkApi._make_hdfs_link, escaped_logs)
-    return re.sub('(job_[0-9_]+(/|\.)?)', OozieSparkApi._make_mr_link, hdfs_links)
-
-  @classmethod
-  def _make_hdfs_link(self, match):
-    try:
-      return '<a href="%s" target="_blank">%s</a>' % (location_to_url(match.group(0), strict=False), match.group(0))
-    except:
-      return match.group(0)
+      response['errors'] = query_form.errors
+  except RuntimeError, e:
+    response['message'] = str(e)
+
+  return HttpResponse(json.dumps(response), mimetype="application/json")
+
+
+@error_handler
+def fetch_saved_query(request, design_id):
+  response = {'status': -1, 'message': ''}
+
+  if request.method != 'GET':
+    response['message'] = _('A GET request is required.')
+
+  app_name = get_app_name(request)
+  query_type = beeswax_models.SavedQuery.TYPES_MAPPING[app_name]
+  design = safe_get_design(request, query_type, design_id)
+
+  response['design'] = design_to_dict(design)
+  return HttpResponse(json.dumps(response), mimetype="application/json")
+
+
+def results_to_dict(results):
+  data = {}
+  rows = []
+  for row in results.rows():
+    rows.append(dict(zip(results.columns, row)))
+  data['rows'] = rows
+  data['start_row'] = results.start_row
+  data['has_more'] = results.has_more
+  data['columns'] = results.columns
+  return data
+
+
+def design_to_dict(design):
+  sql_design = SQLdesign.loads(design.data)
+  return {
+    'id': design.id,
+    'query': sql_design.sql_query,
+    'name': design.name,
+    'desc': design.desc,
+    'server': sql_design.server,
+    'database': sql_design.database
+  }
 
-  @classmethod
-  def _make_mr_link(self, match):
-    try:
-      return '<a href="%s" target="_blank">%s</a>' % (reverse('jobbrowser.views.single_job', kwargs={'job': match.group(0)}), match.group(0))
-    except:
-      return match.group(0)
-
-  def massaged_jobs_for_json(self, request, oozie_jobs, hue_jobs):
-    jobs = []
-    hue_jobs = dict([(script.dict.get('job_id'), script) for script in hue_jobs if script.dict.get('job_id')])
-
-    for job in oozie_jobs:
-      if job.is_running():
-        job = get_oozie(self.user).get_job(job.id)
-        get_copy = request.GET.copy() # Hacky, would need to refactor JobBrowser get logs
-        get_copy['format'] = 'python'
-        request.GET = get_copy
-        try:
-          logs, workflow_action = self.get_log(request, job)
-          progress = workflow_action[0]['progress']
-        except Exception:
-          progress = 0
-      else:
-        progress = 100
-
-      hue_pig = hue_jobs.get(job.id) and hue_jobs.get(job.id) or None
-
-      massaged_job = {
-        'id': job.id,
-        'lastModTime': hasattr(job, 'lastModTime') and job.lastModTime and format_time(job.lastModTime) or None,
-        'kickoffTime': hasattr(job, 'kickoffTime') and job.kickoffTime or None,
-        'timeOut': hasattr(job, 'timeOut') and job.timeOut or None,
-        'endTime': job.endTime and format_time(job.endTime) or None,
-        'status': job.status,
-        'isRunning': job.is_running(),
-        'duration': job.endTime and job.startTime and format_duration_in_millis(( time.mktime(job.endTime) - time.mktime(job.startTime) ) * 1000) or None,
-        'appName': hue_pig and hue_pig.dict['name'] or _('Unsaved script'),
-        'scriptId': hue_pig and hue_pig.id or -1,
-        'scriptContent': hue_pig and hue_pig.dict['script'] or '',
-        'type': hue_pig and hue_pig.dict['type'] or '',
-        'progress': progress,
-        'progressPercent': '%d%%' % progress,
-        'user': job.user,
-        'absoluteUrl': job.get_absolute_url(),
-        'canEdit': has_job_edition_permission(job, self.user),
-        'killUrl': reverse('oozie:manage_oozie_jobs', kwargs={'job_id':job.id, 'action':'kill'}),
-        'watchUrl': reverse('spark:watch', kwargs={'job_id': job.id}) + '?format=python',
-        'created': hasattr(job, 'createdTime') and job.createdTime and job.createdTime and ((job.type == 'Bundle' and job.createdTime) or format_time(job.createdTime)),
-        'startTime': hasattr(job, 'startTime') and format_time(job.startTime) or None,
-        'run': hasattr(job, 'run') and job.run or 0,
-        'frequency': hasattr(job, 'frequency') and job.frequency or None,
-        'timeUnit': hasattr(job, 'timeUnit') and job.timeUnit or None,
-        }
-      jobs.append(massaged_job)
-
-    return jobs
-
-def get_progress(job, log):
-  if job.status in ('SUCCEEDED', 'KILLED', 'FAILED'):
-    return 100
-  else:
-    try:
-      return int(re.findall("MapReduceLauncher  - (1?\d?\d)% complete", log)[-1])
-    except:
-      return 0
 
+def get_query_form(request):
+  api = get_api(request.user)
 
-def format_time(st_time):
-  if st_time is None:
-    return '-'
-  else:
-    return time.strftime("%a, %d %b %Y %H:%M:%S", st_time)
+  app_names = api.jars()
 
+  if not app_names:
+    raise RuntimeError(_("Server specified a jar name."))
 
-def has_job_edition_permission(oozie_job, user):
-  return user.is_superuser or oozie_job.user == user.username
+  form = SparkForm(request.POST, app_names=app_names)
 
+  return form

+ 25 - 13
apps/spark/src/spark/conf.py

@@ -15,29 +15,41 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import sys
 
-from django.utils.translation import ugettext as _, ugettext_lazy as _t
+from django.utils.translation import ugettext_lazy as _t
 
-from desktop.lib.conf import Config, validate_path
+from desktop.lib.conf import Config
+from spark.settings import NICE_NAME
 
 
-SPARK_MASTER = Config(
-  key="spark_master",
-  help=_t("Address of the Spark master, e.g spark://localhost:7077. If empty use the current configuration. "
-          "Can be overriden in the script too."),
-  default=""
+JOB_SERVER_URL = Config(
+  key="server_url",
+  help=_t("URL of the Spark Job Server."),
+  default="http://localhost:8090/"
 )
 
-SPARK_HOME = Config(
-  key="spark_home",
-  help=_t("Local path to Spark Home on all the nodes of the cluster."),
-  default="/usr/lib/spark"
-)
+
+
+def get_spark_status(user):
+  from spark.job_server_api import get_api
+  status = None
+
+  try:
+    if not 'test' in sys.argv: # Avoid tests hanging
+      status = str(get_api(user).get_status())
+  except:
+    pass
+
+  return status
 
 
 def config_validator(user):
   res = []
 
-  res.extend(validate_path(SPARK_HOME, is_dir=True))
+  status = get_spark_status(user)
+
+  if status:
+    res.append((NICE_NAME, _("The app won't work without a running Job Server")))
 
   return res

+ 113 - 0
apps/spark/src/spark/design.py

@@ -0,0 +1,113 @@
+#!/usr/bin/env python
+# Licensed to Cloudera, Inc. under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json
+import logging
+
+import django.http
+from django.utils.translation import ugettext as _
+
+from beeswax.design import normalize_form_dict, denormalize_form_dict, strip_trailing_semicolon,\
+                           split_statements
+
+
+LOG = logging.getLogger(__name__)
+
+SERIALIZATION_VERSION = "0.0.1"
+
+
+class SparkDesign(object):
+  """
+  Represents an SQL design, with methods to perform (de)serialization.
+  """
+  _QUERY_ATTRS = [ 'query', 'type', 'database', 'server' ]
+
+  def __init__(self, form=None, query_type=None):
+    """Initialize the design from a valid form data."""
+    if form is not None:
+      self._data_dict = dict(query = normalize_form_dict(form, SparkDesign._QUERY_ATTRS))
+      if query_type is not None:
+        self._data_dict['query']['type'] = query_type
+
+  def dumps(self):
+    """Returns the serialized form of the design in a string"""
+    dic = self._data_dict.copy()
+    dic['VERSION'] = SERIALIZATION_VERSION
+    return json.dumps(dic)
+
+  @property
+  def sql_query(self):
+    return self._data_dict['query']['query']
+
+  @property
+  def query(self):
+    return self._data_dict['query'].copy()
+
+  @property
+  def server(self):
+    return self._data_dict['query']['server']
+
+  @property
+  def database(self):
+    return self._data_dict['query']['database']
+
+  def get_query_dict(self):
+    # We construct the mform to use its structure and prefix. We don't actually bind data to the forms.
+    from beeswax.forms import QueryForm
+    mform = QueryForm()
+    mform.bind()
+
+    res = django.http.QueryDict('', mutable=True)
+    res.update(denormalize_form_dict(
+                self._data_dict['query'], mform.query, SparkDesign._QUERY_ATTRS))
+    return res
+
+  def get_query(self):
+    return self._data_dict["query"]
+
+  @property
+  def statement_count(self):
+    return len(self.statements)
+
+  def get_query_statement(self, n=0):
+    return self.statements[n]
+
+  @property
+  def statements(self):
+    sql_query = strip_trailing_semicolon(self.sql_query)
+    return [strip_trailing_semicolon(statement.strip()) for statement in split_statements(sql_query)]
+
+  @staticmethod
+  def loads(data):
+    """Returns SQLdesign from the serialized form"""
+    dic = json.loads(data)
+    dic = dict(map(lambda k: (str(k), dic.get(k)), dic.keys()))
+    if dic['VERSION'] != SERIALIZATION_VERSION:
+      LOG.error('Design version mismatch. Found %s; expect %s' % (dic['VERSION'], SERIALIZATION_VERSION))
+
+    # Convert to latest version
+    del dic['VERSION']
+    if 'type' not in dic['query'] or dic['query']['type'] is None:
+      dic['query']['type'] = 0
+    if 'server' not in dic['query']:
+      raise RuntimeError(_('No server!'))
+    if 'database' not in dic['query']:
+      raise RuntimeError(_('No database!'))
+
+    design = SparkDesign()
+    design._data_dict = dic
+    return design

+ 30 - 0
apps/spark/src/spark/forms.py

@@ -14,3 +14,33 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+
+from django import forms
+from django.utils.translation import ugettext_lazy as _t
+
+
+class SparkForm(forms.Form):
+  query = forms.CharField(label=_t("Script parameters"),
+                          required=False)
+  classPath = forms.CharField(label=_t("Class path"),
+                          required=True,
+                          widget=forms.Textarea(attrs={'class': 'beeswax_query'}))
+  appName = forms.ChoiceField(required=True,
+                             label='',
+                             choices=(('default', 'default'),),
+                             initial=0,
+                             widget=forms.widgets.Select(attrs={'class': 'input-medium'}))
+  autoContext = forms.BooleanField(required=False,
+                                   initial=True)
+  context = forms.CharField(required=False)
+
+
+  def __init__(self, *args, **kwargs):
+    app_names = kwargs.pop('app_names')
+    super(SparkForm, self).__init__(*args, **kwargs)
+    self.fields['appName'].choices = ((key, key) for key in app_names)
+
+
+class UploadApp(forms.Form):
+  app_name = forms.CharField()
+  jar_file = forms.FileField()

+ 109 - 0
apps/spark/src/spark/job_server_api.py

@@ -0,0 +1,109 @@
+#!/usr/bin/env python
+# Licensed to Cloudera, Inc. under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging
+import posixpath
+import threading
+
+from desktop.lib.rest.http_client import HttpClient
+from desktop.lib.rest.resource import Resource
+
+from spark.conf import JOB_SERVER_URL
+
+
+LOG = logging.getLogger(__name__)
+DEFAULT_USER = 'hue'
+
+_API_VERSION = 'v1'
+_JSON_CONTENT_TYPE = 'application/json'
+
+_api_cache = None
+_api_cache_lock = threading.Lock()
+
+
+def get_api(user):
+  global _api_cache
+  if _api_cache is None:
+    _api_cache_lock.acquire()
+    try:
+      if _api_cache is None:
+        _api_cache = JobServerApi(JOB_SERVER_URL.get())
+    finally:
+      _api_cache_lock.release()
+  _api_cache.setuser(user)
+  return _api_cache
+
+
+class JobServerApi(object):
+  def __init__(self, oozie_url):
+    self._url = posixpath.join(oozie_url)
+    self._client = HttpClient(self._url, logger=LOG)
+    self._root = Resource(self._client)
+    self._security_enabled = False
+    # To store user info
+    self._thread_local = threading.local()
+
+  def __str__(self):
+    return "JobServerApi at %s" % (self._url,)
+
+  @property
+  def url(self):
+    return self._url
+
+  @property
+  def security_enabled(self):
+    return self._security_enabled
+
+  @property
+  def user(self):
+    return self._thread_local.user
+
+  def setuser(self, user):
+    if hasattr(user, 'username'):
+      self._thread_local.user = user.username
+    else:
+      self._thread_local.user = user
+
+  def get_status(self, **kwargs):
+    return self._root.get('', params=kwargs, headers={'Accept': _JSON_CONTENT_TYPE})
+
+  def submit_job(self, appName, classPath, data, context=None, sync=False):
+    params = {'appName': appName, 'classPath': classPath, 'sync': sync}
+    if context:
+      params['context'] = context
+    return self._root.post('jobs' % params, params=params, data=data, contenttype='application/octet-stream')
+
+  def job(self, job_id):
+    return self._root.get('jobs/%s' % job_id, headers={'Accept': _JSON_CONTENT_TYPE})
+
+  def jobs(self, **kwargs):
+    return self._root.get('jobs', params=kwargs, headers={'Accept': _JSON_CONTENT_TYPE})
+
+  def create_context(self, name, **kwargs):
+    return self._root.post('contexts/%s' % name, params=kwargs, contenttype='application/octet-stream')
+
+  def contexts(self, **kwargs):
+    return self._root.get('contexts', params=kwargs, headers={'Accept': _JSON_CONTENT_TYPE})
+
+  def delete_context(self, name, **kwargs):
+    return self._root.delete('contexts/%s' % name)
+
+  def upload_jar(self, app_name, data):
+    return self._root.post('jars/%s' % app_name, data=data, contenttype='application/octet-stream')
+
+  def jars(self, **kwargs):
+    return self._root.get('jars', params=kwargs, headers={'Accept': _JSON_CONTENT_TYPE})

+ 0 - 461
apps/spark/src/spark/locale/de/LC_MESSAGES/django.po

@@ -1,461 +0,0 @@
-# German translations for Hue.
-# Copyright (C) 2012 Cloudera
-# This file is distributed under the same license as the Hue project.
-# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: 0PROJEKTVERSION\n"
-"Report-Msgid-Bugs-To: EMAIL@ADRESSE\n"
-"POT-Creation-Date: 2013-08-02 20:43-0700\n"
-"PO-Revision-Date: 2012-07-30 18:50-0700\n"
-"Last-Translator: VOLLSTÄNDIGER NAME <EMAIL@ADRESSE>\n"
-"Language-Team: de <LL@li.org>\n"
-"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 0.9.6\n"
-
-#: src/pig/api.py:233 src/pig/templates/app.mako:601
-msgid "Unsaved script"
-msgstr "Nicht gespeichertes Skript"
-
-#: src/pig/conf.py:32
-msgid "Location on local filesystem where the examples are stored."
-msgstr "Ordner auf lokalem Dateisystem, in dem die Beispiele gespeichert werden"
-
-#: src/pig/conf.py:38
-msgid "Location on HDFS where the Pig examples are stored."
-msgstr "Ordner auf HDFS, in dem Pig-Beispiele gespeichert werden."
-
-#: src/pig/conf.py:48
-msgid "The app won't work without a running Oozie server"
-msgstr "Die App funktioniert nicht ohne einen aktiven Oozie-Server"
-
-#: src/pig/models.py:33
-msgid "Owner"
-msgstr "Eigentümer"
-
-#: src/pig/models.py:33
-msgid "User who can modify the job."
-msgstr "Benutzer, der den Job ändern kann."
-
-#: src/pig/models.py:34
-msgid "Is a user document, not a document submission."
-msgstr "Ist ein Benutzerdokument, keine Dokumentübermittlung."
-
-#: src/pig/models.py:35
-msgid "If the document is not a submitted job but a real query, script, workflow."
-msgstr "Wenn das Dokument kein übermittelter Job, sondern ein/e reale/r/s Anfrage, Skript oder Workflow ist"
-
-#: src/pig/models.py:44
-#, python-format
-msgid "Only superusers and %s are allowed to modify this document."
-msgstr "Nur Superuser und %s dürfen dieses Dokument verändern."
-
-#: src/pig/views.py:68 src/pig/views.py:93 src/pig/views.py:112
-#: src/pig/views.py:143 src/pig/views.py:179
-msgid "POST request required."
-msgstr "Eine POST-Anforderung ist erforderlich."
-
-#: src/pig/views.py:104
-msgid "Error stopping Pig script."
-msgstr "Fehler beim Anhalten des Pig-Skripts."
-
-#: src/pig/views.py:149
-msgid " (Copy)"
-msgstr " (Kopieren)"
-
-#: src/pig/views.py:227
-msgid "A POST request is required."
-msgstr "Eine POST-Anforderung ist erforderlich."
-
-#: src/pig/management/commands/pig_setup.py:46
-#, python-format
-msgid "Copying examples %(local_dir)s to %(remote_data_dir)s\n"
-msgstr "Kopieren von Beispielen %(local_dir)s nach %(remote_data_dir)s\n"
-
-#: src/pig/management/commands/pig_setup.py:53
-#, python-format
-msgid "Copying data %(local_dir)s to %(remote_data_dir)s\n"
-msgstr "Kopieren von Daten %(local_dir)s nach %(remote_data_dir)s\n"
-
-#: src/pig/templates/app.mako:28 src/pig/templates/app.mako:103
-msgid "Editor"
-msgstr "Editor"
-
-#: src/pig/templates/app.mako:29
-msgid "Scripts"
-msgstr "Skripte"
-
-#: src/pig/templates/app.mako:30
-msgid "Dashboard"
-msgstr "Dashboard"
-
-#: src/pig/templates/app.mako:40
-msgid "Search for script name or content"
-msgstr "Nach Skriptnamen oder -inhalt suchen"
-
-#: src/pig/templates/app.mako:44 src/pig/templates/app.mako:171
-#: src/pig/templates/app.mako:182
-msgid "Run this script"
-msgstr "Dieses Skript ausführen"
-
-#: src/pig/templates/app.mako:44 src/pig/templates/app.mako:118
-msgid "Run"
-msgstr "Ausführen"
-
-#: src/pig/templates/app.mako:45
-msgid "Copy this script"
-msgstr "Dieses Skript kopieren"
-
-#: src/pig/templates/app.mako:45 src/pig/templates/app.mako:137
-msgid "Copy"
-msgstr "Kopieren"
-
-#: src/pig/templates/app.mako:46
-msgid "Delete this script"
-msgstr "Dieses Skript löschen"
-
-#: src/pig/templates/app.mako:46 src/pig/templates/app.mako:142
-msgid "Delete"
-msgstr "Löschen"
-
-#: src/pig/templates/app.mako:50
-msgid "Create a new script"
-msgstr "Neues Skript erstellen"
-
-#: src/pig/templates/app.mako:50
-#, fuzzy
-msgid "New Script"
-msgstr "Neues Skript"
-
-#: src/pig/templates/app.mako:54
-msgid "There are currently no scripts defined. Please add a new script clicking on \"New script\""
-msgstr "Es sind derzeit keine Skripte definiert. Fügen Sie ein neues Skript ein, indem Sie auf \"Neues Skript\" klicken."
-
-#: src/pig/templates/app.mako:61 src/pig/templates/app.mako:218
-#: src/pig/templates/app.mako:267 src/pig/templates/app.mako:394
-#: src/pig/templates/app.mako:421
-msgid "Name"
-msgstr "Name"
-
-#: src/pig/templates/app.mako:62 src/pig/templates/app.mako:147
-msgid "Script"
-msgstr "Skript"
-
-#: src/pig/templates/app.mako:77
-msgid "There are no scripts matching the search criteria."
-msgstr "Es gibt keine Skripte, die den Suchkriterien entsprechen."
-
-#: src/pig/templates/app.mako:105
-msgid "Pig"
-msgstr "Pig"
-
-#: src/pig/templates/app.mako:108
-msgid "Properties"
-msgstr "Eigenschaften"
-
-#: src/pig/templates/app.mako:111
-msgid "Save the script"
-msgstr "Skript speichern"
-
-#: src/pig/templates/app.mako:112 src/pig/templates/app.mako:568
-msgid "Save"
-msgstr "Speichern"
-
-#: src/pig/templates/app.mako:120
-msgid "Run the script"
-msgstr "Skript ausführen"
-
-#: src/pig/templates/app.mako:121
-msgid "Submit"
-msgstr "Übermitteln"
-
-#: src/pig/templates/app.mako:125
-#, fuzzy
-msgid "Stop the script"
-msgstr "Skript stoppen"
-
-#: src/pig/templates/app.mako:126
-msgid "Stop"
-msgstr "Anhalten"
-
-#: src/pig/templates/app.mako:130
-msgid "Show Logs"
-msgstr "Protokolle anzeigen"
-
-#: src/pig/templates/app.mako:131 src/pig/templates/app.mako:481
-msgid "Logs"
-msgstr "Protokolle"
-
-#: src/pig/templates/app.mako:134 src/pig/templates/app.mako:326
-msgid "File"
-msgstr "Datei"
-
-#: src/pig/templates/app.mako:136
-msgid "Copy the script"
-msgstr "Dieses Skript kopieren"
-
-#: src/pig/templates/app.mako:141
-msgid "Delete the script"
-msgstr "Dieses Skript löschen"
-
-#: src/pig/templates/app.mako:146
-msgid "New script"
-msgstr "Neues Skript"
-
-#: src/pig/templates/app.mako:155
-msgid "Press CTRL + Space to autocomplete"
-msgstr "STRG + Leertaste drücken, um automatisch abzuschließen"
-
-#: src/pig/templates/app.mako:156
-msgid "You can execute the current script by pressing CTRL + ENTER or CTRL + . in the editor"
-msgstr "Sie können das aktuelle Skript ausführen, indem Sie im Editor STRG + ENTER oder STRG + . drücken"
-
-#: src/pig/templates/app.mako:166
-#, fuzzy
-msgid "Unsaved"
-msgstr "Ungespeichert"
-
-#: src/pig/templates/app.mako:172 src/pig/templates/app.mako:183
-#: src/pig/templates/app.mako:356
-#, fuzzy
-msgid "Stop this script"
-msgstr "Dieses Skript stoppen"
-
-#: src/pig/templates/app.mako:188 src/pig/templates/app.mako:561
-msgid "Script name"
-msgstr "Skriptname"
-
-#: src/pig/templates/app.mako:195
-msgid "Parameters"
-msgstr "Parameter"
-
-#: src/pig/templates/app.mako:208
-#, fuzzy
-msgid "There are currently no defined parameters."
-msgstr "Derzeit sind keine definierten Parameter vorhanden."
-
-#: src/pig/templates/app.mako:210 src/pig/templates/app.mako:238
-#: src/pig/templates/app.mako:259 src/pig/templates/app.mako:287
-#: src/pig/templates/app.mako:308 src/pig/templates/app.mako:345
-msgid "Add"
-msgstr "Hinzufügen"
-
-#: src/pig/templates/app.mako:219 src/pig/templates/app.mako:268
-#: src/pig/templates/app.mako:317
-msgid "Value"
-msgstr "Wert"
-
-#: src/pig/templates/app.mako:232 src/pig/templates/app.mako:281
-#: src/pig/templates/app.mako:338
-msgid "Remove"
-msgstr "Entfernen"
-
-#: src/pig/templates/app.mako:246
-#, fuzzy
-msgid "Hadoop properties"
-msgstr "Hadoop-Eigenschaften"
-
-#: src/pig/templates/app.mako:257
-#, fuzzy
-msgid "There are currently no defined Hadoop properties."
-msgstr "Derzeit sind keine Hadoop-Eigenschaften definiert."
-
-#: src/pig/templates/app.mako:296
-msgid "Resources"
-msgstr "Ressourcen"
-
-#: src/pig/templates/app.mako:299
-msgid "Path to a HDFS file or zip file to add to the workspace of the running script"
-msgstr "Pfad zu einer HDFS-Datei oder Zip-Datei, die in den Workspace des laufenden Skripts eingefügt werden soll"
-
-#: src/pig/templates/app.mako:306
-#, fuzzy
-msgid "There are currently no defined resources."
-msgstr "Derzeit sind keine definierten Ressourcen vorhanden."
-
-#: src/pig/templates/app.mako:316
-msgid "Type"
-msgstr "Typ"
-
-#: src/pig/templates/app.mako:327
-msgid "Archive"
-msgstr "Archivieren"
-
-#: src/pig/templates/app.mako:363
-msgid "Status:"
-msgstr "Status:"
-
-#: src/pig/templates/app.mako:365
-msgid "Progress:"
-msgstr "Fortschritt:"
-
-#: src/pig/templates/app.mako:365
-msgid "%"
-msgstr "%"
-
-#: src/pig/templates/app.mako:371
-msgid "No available logs."
-msgstr "Keine verfügbaren Protokolle."
-
-#: src/pig/templates/app.mako:385 src/pig/templates/app.mako:873
-msgid "Running"
-msgstr "Aktiv"
-
-#: src/pig/templates/app.mako:389
-msgid "There are currently no running scripts."
-msgstr "Es sind derzeit keine Skripte aktiv."
-
-#: src/pig/templates/app.mako:395
-msgid "Progress"
-msgstr "Fortschritt"
-
-#: src/pig/templates/app.mako:396 src/pig/templates/app.mako:423
-msgid "Created on"
-msgstr "Erstellt am"
-
-#: src/pig/templates/app.mako:412
-msgid "Completed"
-msgstr "Abgeschlossen"
-
-#: src/pig/templates/app.mako:416
-msgid "There are currently no completed scripts."
-msgstr "Es sind derzeit keine fertiggestellten Skripte vorhanden."
-
-#: src/pig/templates/app.mako:422
-msgid "Status"
-msgstr "Status"
-
-#: src/pig/templates/app.mako:435
-msgid "Click to edit"
-msgstr "Zum Bearbeiten klicken"
-
-#: src/pig/templates/app.mako:449
-msgid "Click to view"
-msgstr "Zum Ansehen klicken"
-
-#: src/pig/templates/app.mako:466
-msgid "Confirm Delete"
-msgstr "Löschen bestätigen"
-
-#: src/pig/templates/app.mako:469
-msgid "Are you sure you want to delete this script?"
-msgstr "Möchten Sie dieses Skript wirklich löschen?"
-
-#: src/pig/templates/app.mako:470
-msgid "Are you sure you want to delete these scripts?"
-msgstr "Möchten Sie diese Skripte wirklich löschen?"
-
-#: src/pig/templates/app.mako:473 src/pig/templates/app.mako:507
-#: src/pig/templates/app.mako:518 src/pig/templates/app.mako:547
-msgid "No"
-msgstr "Nein"
-
-#: src/pig/templates/app.mako:474 src/pig/templates/app.mako:508
-#: src/pig/templates/app.mako:519 src/pig/templates/app.mako:548
-msgid "Yes"
-msgstr "Ja"
-
-#: src/pig/templates/app.mako:488
-msgid "Close"
-msgstr "Schließen"
-
-#: src/pig/templates/app.mako:495
-msgid "Run Script"
-msgstr "Skript ausführen"
-
-#: src/pig/templates/app.mako:495 src/pig/templates/app.mako:515
-msgid "?"
-msgstr "?"
-
-#: src/pig/templates/app.mako:498
-msgid "Script variables"
-msgstr "Skriptvariablen"
-
-#: src/pig/templates/app.mako:515
-msgid "Stop Script"
-msgstr "Skript anhalten"
-
-#: src/pig/templates/app.mako:526
-msgid "Choose a file"
-msgstr "Eine Datei auswählen"
-
-#: src/pig/templates/app.mako:539
-msgid "Are you sure?"
-msgstr "Sind Sie sicher?"
-
-#: src/pig/templates/app.mako:543
-msgid "The current script has unsaved changes. Are you sure you want to discard the changes?"
-msgstr "Das aktuelle Skript enthält ungespeicherte Änderungen. Sind Sie sicher, dass Sie die Änderungen rückgängig machen möchten?"
-
-#: src/pig/templates/app.mako:555
-#, fuzzy
-msgid "Save script"
-msgstr "Skript speichern"
-
-#: src/pig/templates/app.mako:559
-msgid "Give a meaningful name to this script."
-msgstr "Geben Sie diesem Skript einen eindeutigen Namen."
-
-#: src/pig/templates/app.mako:567
-msgid "Cancel"
-msgstr "Abbrechen"
-
-#: src/pig/templates/app.mako:597
-#, fuzzy
-msgid "The Pig job could not be killed."
-msgstr "Der Pig-Job konnte nicht beendet werden."
-
-#: src/pig/templates/app.mako:598
-#, fuzzy
-msgid "Run this Pig script."
-msgstr "Dieses Pig-Skript ausführen."
-
-#: src/pig/templates/app.mako:599
-#, fuzzy
-msgid "Stop execution."
-msgstr "Ausführung stoppen."
-
-#: src/pig/templates/app.mako:600
-msgid "Saved"
-msgstr "Gespeichert"
-
-#: src/pig/templates/app.mako:866
-msgid "Saving"
-msgstr "Es wird gespeichert"
-
-#: src/pig/templates/app.mako:877
-msgid "has been saved correctly."
-msgstr "wurde korrekt gespeichert."
-
-#: src/pig/templates/app.mako:881
-msgid "There was an error with your request!"
-msgstr "Bei Ihrer Anfrage ist ein Fehler aufgetreten!"
-
-#: src/pig/templates/app.mako:1141
-msgid "Did you know?"
-msgstr "Wussten Sie schon?"
-
-#: src/pig/templates/app.mako:1148
-msgid "Names and values of Pig parameters and options, e.g."
-msgstr "Namen und Werte von Pig-Parametern und -Optionen, z. B."
-
-#: src/pig/templates/app.mako:1155
-msgid "Names and values of Hadoop properties, e.g."
-msgstr "Namen und Werte von Hadoop-Eigenschaften, z. B."
-
-#: src/pig/templates/app.mako:1162
-msgid "Include files or compressed files"
-msgstr "Dateien oder komprimierte Dateien einfügen"
-
-#: src/pig/templates/app.mako:1171
-msgid "You have unsaved changes in this pig script."
-msgstr "Dieses Pig-Skript enthält nicht gespeicherte Änderungen."
-
-#~ msgid "Actions"
-#~ msgstr "Aktionen"
-#~ msgid "Current Logs"
-#~ msgstr "Aktuelle Protokolle"

+ 0 - 383
apps/spark/src/spark/locale/en/LC_MESSAGES/django.po

@@ -1,383 +0,0 @@
-# English translations for Hue.
-# Copyright (C) 2013 Cloudera, Inc
-# This file is distributed under the same license as the Hue project.
-# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: Hue VERSION\n"
-"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2013-05-10 11:59-0700\n"
-"PO-Revision-Date: 2013-10-28 10:31-0700\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: en <LL@li.org>\n"
-"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 0.9.6\n"
-
-#: src/pig/api.py:182 src/pig/templates/app.mako:455
-msgid "Unsaved script"
-msgstr ""
-
-#: src/pig/conf.py:32
-msgid "Location on local filesystem where the examples are stored."
-msgstr ""
-
-#: src/pig/conf.py:38
-msgid "Location on HDFS where the Pig examples are stored."
-msgstr ""
-
-#: src/pig/conf.py:48
-msgid "The app won't work without a running Oozie server"
-msgstr ""
-
-#: src/pig/models.py:33
-msgid "Owner"
-msgstr ""
-
-#: src/pig/models.py:33
-msgid "User who can modify the job."
-msgstr ""
-
-#: src/pig/models.py:34
-msgid "Is a user document, not a document submission."
-msgstr ""
-
-#: src/pig/models.py:35
-msgid "If the document is not a submitted job but a real query, script, workflow."
-msgstr ""
-
-#: src/pig/models.py:44
-#, python-format
-msgid "Only superusers and %s are allowed to modify this document."
-msgstr ""
-
-#: src/pig/views.py:66 src/pig/views.py:90 src/pig/views.py:109
-#: src/pig/views.py:139 src/pig/views.py:163
-msgid "POST request required."
-msgstr ""
-
-#: src/pig/views.py:101
-msgid "Error stopping Pig script."
-msgstr ""
-
-#: src/pig/views.py:145
-msgid " (Copy)"
-msgstr ""
-
-#: src/pig/views.py:211
-msgid "A POST request is required."
-msgstr ""
-
-#: src/pig/management/commands/pig_setup.py:46
-#, python-format
-msgid "Copying examples %(local_dir)s to %(remote_data_dir)s\n"
-msgstr ""
-
-#: src/pig/management/commands/pig_setup.py:53
-#, python-format
-msgid "Copying data %(local_dir)s to %(remote_data_dir)s\n"
-msgstr ""
-
-#: src/pig/templates/app.mako:23
-msgid "Pig"
-msgstr ""
-
-#: src/pig/templates/app.mako:28 src/pig/templates/app.mako:104
-msgid "Editor"
-msgstr ""
-
-#: src/pig/templates/app.mako:29
-msgid "Scripts"
-msgstr ""
-
-#: src/pig/templates/app.mako:30
-msgid "Dashboard"
-msgstr ""
-
-#: src/pig/templates/app.mako:40
-msgid "Search for script name or content"
-msgstr ""
-
-#: src/pig/templates/app.mako:44
-msgid "Run this script"
-msgstr ""
-
-#: src/pig/templates/app.mako:44 src/pig/templates/app.mako:123
-msgid "Run"
-msgstr ""
-
-#: src/pig/templates/app.mako:45
-msgid "Copy this script"
-msgstr ""
-
-#: src/pig/templates/app.mako:45 src/pig/templates/app.mako:138
-msgid "Copy"
-msgstr ""
-
-#: src/pig/templates/app.mako:46
-msgid "Delete this script"
-msgstr ""
-
-#: src/pig/templates/app.mako:46 src/pig/templates/app.mako:143
-msgid "Delete"
-msgstr ""
-
-#: src/pig/templates/app.mako:50
-msgid "Create a new script"
-msgstr ""
-
-#: src/pig/templates/app.mako:50 src/pig/templates/app.mako:109
-#: src/pig/templates/app.mako:110
-msgid "New script"
-msgstr ""
-
-#: src/pig/templates/app.mako:54
-msgid ""
-"There are currently no scripts defined. Please add a new script clicking "
-"on \"New script\""
-msgstr ""
-
-#: src/pig/templates/app.mako:61 src/pig/templates/app.mako:181
-#: src/pig/templates/app.mako:287 src/pig/templates/app.mako:314
-msgid "Name"
-msgstr ""
-
-#: src/pig/templates/app.mako:62
-msgid "Script"
-msgstr ""
-
-#: src/pig/templates/app.mako:77
-msgid "There are no scripts matching the search criteria."
-msgstr ""
-
-#: src/pig/templates/app.mako:106
-msgid "Edit script"
-msgstr ""
-
-#: src/pig/templates/app.mako:113
-msgid "Properties"
-msgstr ""
-
-#: src/pig/templates/app.mako:115
-msgid "Edit properties"
-msgstr ""
-
-#: src/pig/templates/app.mako:120
-msgid "Actions"
-msgstr ""
-
-#: src/pig/templates/app.mako:122 src/pig/templates/app.mako:127
-msgid "Run the script"
-msgstr ""
-
-#: src/pig/templates/app.mako:128
-msgid "Stop"
-msgstr ""
-
-#: src/pig/templates/app.mako:132
-msgid "Save the script"
-msgstr ""
-
-#: src/pig/templates/app.mako:133
-msgid "Save"
-msgstr ""
-
-#: src/pig/templates/app.mako:137
-msgid "Copy the script"
-msgstr ""
-
-#: src/pig/templates/app.mako:142
-msgid "Delete the script"
-msgstr ""
-
-#: src/pig/templates/app.mako:146 src/pig/templates/app.mako:374
-msgid "Logs"
-msgstr ""
-
-#: src/pig/templates/app.mako:148
-msgid "Show Logs"
-msgstr ""
-
-#: src/pig/templates/app.mako:148
-msgid "Current Logs"
-msgstr ""
-
-#: src/pig/templates/app.mako:157
-msgid "Edit"
-msgstr ""
-
-#: src/pig/templates/app.mako:164
-msgid "Edit properties for"
-msgstr ""
-
-#: src/pig/templates/app.mako:167
-msgid "Script name"
-msgstr ""
-
-#: src/pig/templates/app.mako:172
-msgid "Parameters"
-msgstr ""
-
-#: src/pig/templates/app.mako:174 src/pig/templates/app.mako:196
-#: src/pig/templates/app.mako:205 src/pig/templates/app.mako:241
-msgid "Add"
-msgstr ""
-
-#: src/pig/templates/app.mako:182 src/pig/templates/app.mako:213
-msgid "Value"
-msgstr ""
-
-#: src/pig/templates/app.mako:190 src/pig/templates/app.mako:234
-msgid "Remove"
-msgstr ""
-
-#: src/pig/templates/app.mako:203
-msgid "Resources"
-msgstr ""
-
-#: src/pig/templates/app.mako:212
-msgid "Type"
-msgstr ""
-
-#: src/pig/templates/app.mako:222
-msgid "File"
-msgstr ""
-
-#: src/pig/templates/app.mako:223
-msgid "Archive"
-msgstr ""
-
-#: src/pig/templates/app.mako:251
-msgid "Logs for"
-msgstr ""
-
-#: src/pig/templates/app.mako:256
-msgid "Status:"
-msgstr ""
-
-#: src/pig/templates/app.mako:258
-msgid "Progress:"
-msgstr ""
-
-#: src/pig/templates/app.mako:258
-msgid "%"
-msgstr ""
-
-#: src/pig/templates/app.mako:264
-msgid "No available logs."
-msgstr ""
-
-#: src/pig/templates/app.mako:278 src/pig/templates/app.mako:640
-msgid "Running"
-msgstr ""
-
-#: src/pig/templates/app.mako:282
-msgid "There are currently no running scripts."
-msgstr ""
-
-#: src/pig/templates/app.mako:288
-msgid "Progress"
-msgstr ""
-
-#: src/pig/templates/app.mako:289 src/pig/templates/app.mako:316
-msgid "Created on"
-msgstr ""
-
-#: src/pig/templates/app.mako:305
-msgid "Completed"
-msgstr ""
-
-#: src/pig/templates/app.mako:309
-msgid "There are currently no completed scripts."
-msgstr ""
-
-#: src/pig/templates/app.mako:315
-msgid "Status"
-msgstr ""
-
-#: src/pig/templates/app.mako:328
-msgid "Click to edit"
-msgstr ""
-
-#: src/pig/templates/app.mako:342
-msgid "Click to view"
-msgstr ""
-
-#: src/pig/templates/app.mako:359
-msgid "Confirm Delete"
-msgstr ""
-
-#: src/pig/templates/app.mako:362
-msgid "Are you sure you want to delete this script?"
-msgstr ""
-
-#: src/pig/templates/app.mako:363
-msgid "Are you sure you want to delete these scripts?"
-msgstr ""
-
-#: src/pig/templates/app.mako:366 src/pig/templates/app.mako:400
-#: src/pig/templates/app.mako:411
-msgid "No"
-msgstr ""
-
-#: src/pig/templates/app.mako:367 src/pig/templates/app.mako:401
-#: src/pig/templates/app.mako:412
-msgid "Yes"
-msgstr ""
-
-#: src/pig/templates/app.mako:381
-msgid "Close"
-msgstr ""
-
-#: src/pig/templates/app.mako:388
-msgid "Run Script"
-msgstr ""
-
-#: src/pig/templates/app.mako:388 src/pig/templates/app.mako:408
-msgid "?"
-msgstr ""
-
-#: src/pig/templates/app.mako:391
-msgid "Script variables"
-msgstr ""
-
-#: src/pig/templates/app.mako:408
-msgid "Stop Script"
-msgstr ""
-
-#: src/pig/templates/app.mako:419
-msgid "Choose a file"
-msgstr ""
-
-#: src/pig/templates/app.mako:451
-msgid "The pig job could not be killed."
-msgstr ""
-
-#: src/pig/templates/app.mako:452
-msgid "Run this pig script"
-msgstr ""
-
-#: src/pig/templates/app.mako:453
-msgid "Stop the execution"
-msgstr ""
-
-#: src/pig/templates/app.mako:454
-msgid "Saved"
-msgstr ""
-
-#: src/pig/templates/app.mako:633
-msgid "Saving"
-msgstr ""
-
-#: src/pig/templates/app.mako:644
-msgid "has been saved correctly."
-msgstr ""
-
-#: src/pig/templates/app.mako:648
-msgid "There was an error with your request!"
-msgstr ""
-

+ 0 - 382
apps/spark/src/spark/locale/en_US.pot

@@ -1,382 +0,0 @@
-# Translations template for Hue.
-# Copyright (C) 2013 Cloudera, Inc
-# This file is distributed under the same license as the Hue project.
-# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: Hue VERSION\n"
-"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2013-05-10 11:59-0700\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 0.9.6\n"
-
-#: src/pig/api.py:182 src/pig/templates/app.mako:455
-msgid "Unsaved script"
-msgstr ""
-
-#: src/pig/conf.py:32
-msgid "Location on local filesystem where the examples are stored."
-msgstr ""
-
-#: src/pig/conf.py:38
-msgid "Location on HDFS where the Pig examples are stored."
-msgstr ""
-
-#: src/pig/conf.py:48
-msgid "The app won't work without a running Oozie server"
-msgstr ""
-
-#: src/pig/models.py:33
-msgid "Owner"
-msgstr ""
-
-#: src/pig/models.py:33
-msgid "User who can modify the job."
-msgstr ""
-
-#: src/pig/models.py:34
-msgid "Is a user document, not a document submission."
-msgstr ""
-
-#: src/pig/models.py:35
-msgid "If the document is not a submitted job but a real query, script, workflow."
-msgstr ""
-
-#: src/pig/models.py:44
-#, python-format
-msgid "Only superusers and %s are allowed to modify this document."
-msgstr ""
-
-#: src/pig/views.py:66 src/pig/views.py:90 src/pig/views.py:109
-#: src/pig/views.py:139 src/pig/views.py:163
-msgid "POST request required."
-msgstr ""
-
-#: src/pig/views.py:101
-msgid "Error stopping Pig script."
-msgstr ""
-
-#: src/pig/views.py:145
-msgid " (Copy)"
-msgstr ""
-
-#: src/pig/views.py:211
-msgid "A POST request is required."
-msgstr ""
-
-#: src/pig/management/commands/pig_setup.py:46
-#, python-format
-msgid "Copying examples %(local_dir)s to %(remote_data_dir)s\n"
-msgstr ""
-
-#: src/pig/management/commands/pig_setup.py:53
-#, python-format
-msgid "Copying data %(local_dir)s to %(remote_data_dir)s\n"
-msgstr ""
-
-#: src/pig/templates/app.mako:23
-msgid "Pig"
-msgstr ""
-
-#: src/pig/templates/app.mako:28 src/pig/templates/app.mako:104
-msgid "Editor"
-msgstr ""
-
-#: src/pig/templates/app.mako:29
-msgid "Scripts"
-msgstr ""
-
-#: src/pig/templates/app.mako:30
-msgid "Dashboard"
-msgstr ""
-
-#: src/pig/templates/app.mako:40
-msgid "Search for script name or content"
-msgstr ""
-
-#: src/pig/templates/app.mako:44
-msgid "Run this script"
-msgstr ""
-
-#: src/pig/templates/app.mako:44 src/pig/templates/app.mako:123
-msgid "Run"
-msgstr ""
-
-#: src/pig/templates/app.mako:45
-msgid "Copy this script"
-msgstr ""
-
-#: src/pig/templates/app.mako:45 src/pig/templates/app.mako:138
-msgid "Copy"
-msgstr ""
-
-#: src/pig/templates/app.mako:46
-msgid "Delete this script"
-msgstr ""
-
-#: src/pig/templates/app.mako:46 src/pig/templates/app.mako:143
-msgid "Delete"
-msgstr ""
-
-#: src/pig/templates/app.mako:50
-msgid "Create a new script"
-msgstr ""
-
-#: src/pig/templates/app.mako:50 src/pig/templates/app.mako:109
-#: src/pig/templates/app.mako:110
-msgid "New script"
-msgstr ""
-
-#: src/pig/templates/app.mako:54
-msgid ""
-"There are currently no scripts defined. Please add a new script clicking "
-"on \"New script\""
-msgstr ""
-
-#: src/pig/templates/app.mako:61 src/pig/templates/app.mako:181
-#: src/pig/templates/app.mako:287 src/pig/templates/app.mako:314
-msgid "Name"
-msgstr ""
-
-#: src/pig/templates/app.mako:62
-msgid "Script"
-msgstr ""
-
-#: src/pig/templates/app.mako:77
-msgid "There are no scripts matching the search criteria."
-msgstr ""
-
-#: src/pig/templates/app.mako:106
-msgid "Edit script"
-msgstr ""
-
-#: src/pig/templates/app.mako:113
-msgid "Properties"
-msgstr ""
-
-#: src/pig/templates/app.mako:115
-msgid "Edit properties"
-msgstr ""
-
-#: src/pig/templates/app.mako:120
-msgid "Actions"
-msgstr ""
-
-#: src/pig/templates/app.mako:122 src/pig/templates/app.mako:127
-msgid "Run the script"
-msgstr ""
-
-#: src/pig/templates/app.mako:128
-msgid "Stop"
-msgstr ""
-
-#: src/pig/templates/app.mako:132
-msgid "Save the script"
-msgstr ""
-
-#: src/pig/templates/app.mako:133
-msgid "Save"
-msgstr ""
-
-#: src/pig/templates/app.mako:137
-msgid "Copy the script"
-msgstr ""
-
-#: src/pig/templates/app.mako:142
-msgid "Delete the script"
-msgstr ""
-
-#: src/pig/templates/app.mako:146 src/pig/templates/app.mako:374
-msgid "Logs"
-msgstr ""
-
-#: src/pig/templates/app.mako:148
-msgid "Show Logs"
-msgstr ""
-
-#: src/pig/templates/app.mako:148
-msgid "Current Logs"
-msgstr ""
-
-#: src/pig/templates/app.mako:157
-msgid "Edit"
-msgstr ""
-
-#: src/pig/templates/app.mako:164
-msgid "Edit properties for"
-msgstr ""
-
-#: src/pig/templates/app.mako:167
-msgid "Script name"
-msgstr ""
-
-#: src/pig/templates/app.mako:172
-msgid "Parameters"
-msgstr ""
-
-#: src/pig/templates/app.mako:174 src/pig/templates/app.mako:196
-#: src/pig/templates/app.mako:205 src/pig/templates/app.mako:241
-msgid "Add"
-msgstr ""
-
-#: src/pig/templates/app.mako:182 src/pig/templates/app.mako:213
-msgid "Value"
-msgstr ""
-
-#: src/pig/templates/app.mako:190 src/pig/templates/app.mako:234
-msgid "Remove"
-msgstr ""
-
-#: src/pig/templates/app.mako:203
-msgid "Resources"
-msgstr ""
-
-#: src/pig/templates/app.mako:212
-msgid "Type"
-msgstr ""
-
-#: src/pig/templates/app.mako:222
-msgid "File"
-msgstr ""
-
-#: src/pig/templates/app.mako:223
-msgid "Archive"
-msgstr ""
-
-#: src/pig/templates/app.mako:251
-msgid "Logs for"
-msgstr ""
-
-#: src/pig/templates/app.mako:256
-msgid "Status:"
-msgstr ""
-
-#: src/pig/templates/app.mako:258
-msgid "Progress:"
-msgstr ""
-
-#: src/pig/templates/app.mako:258
-msgid "%"
-msgstr ""
-
-#: src/pig/templates/app.mako:264
-msgid "No available logs."
-msgstr ""
-
-#: src/pig/templates/app.mako:278 src/pig/templates/app.mako:640
-msgid "Running"
-msgstr ""
-
-#: src/pig/templates/app.mako:282
-msgid "There are currently no running scripts."
-msgstr ""
-
-#: src/pig/templates/app.mako:288
-msgid "Progress"
-msgstr ""
-
-#: src/pig/templates/app.mako:289 src/pig/templates/app.mako:316
-msgid "Created on"
-msgstr ""
-
-#: src/pig/templates/app.mako:305
-msgid "Completed"
-msgstr ""
-
-#: src/pig/templates/app.mako:309
-msgid "There are currently no completed scripts."
-msgstr ""
-
-#: src/pig/templates/app.mako:315
-msgid "Status"
-msgstr ""
-
-#: src/pig/templates/app.mako:328
-msgid "Click to edit"
-msgstr ""
-
-#: src/pig/templates/app.mako:342
-msgid "Click to view"
-msgstr ""
-
-#: src/pig/templates/app.mako:359
-msgid "Confirm Delete"
-msgstr ""
-
-#: src/pig/templates/app.mako:362
-msgid "Are you sure you want to delete this script?"
-msgstr ""
-
-#: src/pig/templates/app.mako:363
-msgid "Are you sure you want to delete these scripts?"
-msgstr ""
-
-#: src/pig/templates/app.mako:366 src/pig/templates/app.mako:400
-#: src/pig/templates/app.mako:411
-msgid "No"
-msgstr ""
-
-#: src/pig/templates/app.mako:367 src/pig/templates/app.mako:401
-#: src/pig/templates/app.mako:412
-msgid "Yes"
-msgstr ""
-
-#: src/pig/templates/app.mako:381
-msgid "Close"
-msgstr ""
-
-#: src/pig/templates/app.mako:388
-msgid "Run Script"
-msgstr ""
-
-#: src/pig/templates/app.mako:388 src/pig/templates/app.mako:408
-msgid "?"
-msgstr ""
-
-#: src/pig/templates/app.mako:391
-msgid "Script variables"
-msgstr ""
-
-#: src/pig/templates/app.mako:408
-msgid "Stop Script"
-msgstr ""
-
-#: src/pig/templates/app.mako:419
-msgid "Choose a file"
-msgstr ""
-
-#: src/pig/templates/app.mako:451
-msgid "The pig job could not be killed."
-msgstr ""
-
-#: src/pig/templates/app.mako:452
-msgid "Run this pig script"
-msgstr ""
-
-#: src/pig/templates/app.mako:453
-msgid "Stop the execution"
-msgstr ""
-
-#: src/pig/templates/app.mako:454
-msgid "Saved"
-msgstr ""
-
-#: src/pig/templates/app.mako:633
-msgid "Saving"
-msgstr ""
-
-#: src/pig/templates/app.mako:644
-msgid "has been saved correctly."
-msgstr ""
-
-#: src/pig/templates/app.mako:648
-msgid "There was an error with your request!"
-msgstr ""
-

+ 0 - 461
apps/spark/src/spark/locale/es/LC_MESSAGES/django.po

@@ -1,461 +0,0 @@
-# Spanish translations for Hue.
-# Copyright (C) 2012 Cloudera
-# This file is distributed under the same license as the Hue project.
-# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: VERSIÓN DEL PROYECTO\n"
-"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2013-08-02 20:43-0700\n"
-"PO-Revision-Date: 2012-07-30 18:50-0700\n"
-"Last-Translator: NOMBRE COMPLETO <EMAIL@ADDRESS>\n"
-"Language-Team: es <LL@li.org>\n"
-"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 0.9.6\n"
-
-#: src/pig/api.py:233 src/pig/templates/app.mako:601
-msgid "Unsaved script"
-msgstr "Secuencia de comandos sin guardar"
-
-#: src/pig/conf.py:32
-msgid "Location on local filesystem where the examples are stored."
-msgstr "Ubicación, en el sistema de archivos local, en la que se almacenan los ejemplos."
-
-#: src/pig/conf.py:38
-msgid "Location on HDFS where the Pig examples are stored."
-msgstr "Ubicación, en HDFS, en la que se almacenan los ejemplos de Pig."
-
-#: src/pig/conf.py:48
-msgid "The app won't work without a running Oozie server"
-msgstr "La aplicación no funcionará sin un servidor Oozie en ejecución"
-
-#: src/pig/models.py:33
-msgid "Owner"
-msgstr "Propietario"
-
-#: src/pig/models.py:33
-msgid "User who can modify the job."
-msgstr "El usuario que puede modificar el trabajo."
-
-#: src/pig/models.py:34
-msgid "Is a user document, not a document submission."
-msgstr "Es un documento de usuario, no un envío de documento."
-
-#: src/pig/models.py:35
-msgid "If the document is not a submitted job but a real query, script, workflow."
-msgstr "Si el documento no es un trabajo enviado sino una consulta, una secuencia de comandos o workflow."
-
-#: src/pig/models.py:44
-#, python-format
-msgid "Only superusers and %s are allowed to modify this document."
-msgstr "Este documento solo puede ser modificado por los superusuarios y %s."
-
-#: src/pig/views.py:68 src/pig/views.py:93 src/pig/views.py:112
-#: src/pig/views.py:143 src/pig/views.py:179
-msgid "POST request required."
-msgstr "Se necesita una solicitud POST."
-
-#: src/pig/views.py:104
-msgid "Error stopping Pig script."
-msgstr "Error al detener la secuencia de Pig."
-
-#: src/pig/views.py:149
-msgid " (Copy)"
-msgstr " (Copiar)"
-
-#: src/pig/views.py:227
-msgid "A POST request is required."
-msgstr "Se necesita una solicitud POST."
-
-#: src/pig/management/commands/pig_setup.py:46
-#, python-format
-msgid "Copying examples %(local_dir)s to %(remote_data_dir)s\n"
-msgstr "Copiando ejemplos de %(local_dir)s a %(remote_data_dir)s\n"
-
-#: src/pig/management/commands/pig_setup.py:53
-#, python-format
-msgid "Copying data %(local_dir)s to %(remote_data_dir)s\n"
-msgstr "Copiando datos de %(local_dir)s a %(remote_data_dir)s\n"
-
-#: src/pig/templates/app.mako:28 src/pig/templates/app.mako:103
-msgid "Editor"
-msgstr "Editor"
-
-#: src/pig/templates/app.mako:29
-msgid "Scripts"
-msgstr "Secuencias de comandos"
-
-#: src/pig/templates/app.mako:30
-msgid "Dashboard"
-msgstr "Panel"
-
-#: src/pig/templates/app.mako:40
-msgid "Search for script name or content"
-msgstr "Buscar el nombre o el contenido de la secuencia de comandos"
-
-#: src/pig/templates/app.mako:44 src/pig/templates/app.mako:171
-#: src/pig/templates/app.mako:182
-msgid "Run this script"
-msgstr "Ejecutar esta secuencia de comandos"
-
-#: src/pig/templates/app.mako:44 src/pig/templates/app.mako:118
-msgid "Run"
-msgstr "Ejecutar"
-
-#: src/pig/templates/app.mako:45
-msgid "Copy this script"
-msgstr "Copiar esta secuencia de comandos"
-
-#: src/pig/templates/app.mako:45 src/pig/templates/app.mako:137
-msgid "Copy"
-msgstr "Copiar"
-
-#: src/pig/templates/app.mako:46
-msgid "Delete this script"
-msgstr "Eliminar esta secuencia de comandos"
-
-#: src/pig/templates/app.mako:46 src/pig/templates/app.mako:142
-msgid "Delete"
-msgstr "Eliminar"
-
-#: src/pig/templates/app.mako:50
-msgid "Create a new script"
-msgstr "Crear una nueva secuencia de comandos"
-
-#: src/pig/templates/app.mako:50
-#, fuzzy
-msgid "New Script"
-msgstr "Nueva secuencia de comandos"
-
-#: src/pig/templates/app.mako:54
-msgid "There are currently no scripts defined. Please add a new script clicking on \"New script\""
-msgstr "Actualmente no hay ninguna secuencia de comandos definida. Agregue una nueva haciendo clic en \"Nueva secuencia de comandos\""
-
-#: src/pig/templates/app.mako:61 src/pig/templates/app.mako:218
-#: src/pig/templates/app.mako:267 src/pig/templates/app.mako:394
-#: src/pig/templates/app.mako:421
-msgid "Name"
-msgstr "Nombre"
-
-#: src/pig/templates/app.mako:62 src/pig/templates/app.mako:147
-msgid "Script"
-msgstr "Secuencia de comandos"
-
-#: src/pig/templates/app.mako:77
-msgid "There are no scripts matching the search criteria."
-msgstr "No hay ninguna secuencia de comandos que coincida con los criterios de búsqueda."
-
-#: src/pig/templates/app.mako:105
-msgid "Pig"
-msgstr "Pig"
-
-#: src/pig/templates/app.mako:108
-msgid "Properties"
-msgstr "Propiedades"
-
-#: src/pig/templates/app.mako:111
-msgid "Save the script"
-msgstr "Guardar la secuencia de comandos"
-
-#: src/pig/templates/app.mako:112 src/pig/templates/app.mako:568
-msgid "Save"
-msgstr "Guardar"
-
-#: src/pig/templates/app.mako:120
-msgid "Run the script"
-msgstr "Ejecutar la secuencia de comandos"
-
-#: src/pig/templates/app.mako:121
-msgid "Submit"
-msgstr "Enviar"
-
-#: src/pig/templates/app.mako:125
-#, fuzzy
-msgid "Stop the script"
-msgstr "Detener la secuencia de comandos"
-
-#: src/pig/templates/app.mako:126
-msgid "Stop"
-msgstr "Detener"
-
-#: src/pig/templates/app.mako:130
-msgid "Show Logs"
-msgstr "Mostrar los registros"
-
-#: src/pig/templates/app.mako:131 src/pig/templates/app.mako:481
-msgid "Logs"
-msgstr "Registros"
-
-#: src/pig/templates/app.mako:134 src/pig/templates/app.mako:326
-msgid "File"
-msgstr "Archivo"
-
-#: src/pig/templates/app.mako:136
-msgid "Copy the script"
-msgstr "Copiar esta secuencia de comandos"
-
-#: src/pig/templates/app.mako:141
-msgid "Delete the script"
-msgstr "Eliminar la secuencia de comandos"
-
-#: src/pig/templates/app.mako:146
-msgid "New script"
-msgstr "Nueva secuencia de comandos"
-
-#: src/pig/templates/app.mako:155
-msgid "Press CTRL + Space to autocomplete"
-msgstr "Pulse la tecla CTRL + espacio para autocompletar"
-
-#: src/pig/templates/app.mako:156
-msgid "You can execute the current script by pressing CTRL + ENTER or CTRL + . in the editor"
-msgstr "Para ejecutar la secuencia de comandos actual, pulse CTRL + ENTER or CTRL + . en el editor"
-
-#: src/pig/templates/app.mako:166
-#, fuzzy
-msgid "Unsaved"
-msgstr "Sin guardar"
-
-#: src/pig/templates/app.mako:172 src/pig/templates/app.mako:183
-#: src/pig/templates/app.mako:356
-#, fuzzy
-msgid "Stop this script"
-msgstr "Detener esta secuencia de comandos"
-
-#: src/pig/templates/app.mako:188 src/pig/templates/app.mako:561
-msgid "Script name"
-msgstr "Nombre de la secuencia de comandos"
-
-#: src/pig/templates/app.mako:195
-msgid "Parameters"
-msgstr "Parámetros"
-
-#: src/pig/templates/app.mako:208
-#, fuzzy
-msgid "There are currently no defined parameters."
-msgstr "Actualmente no hay ningún parámetro definido."
-
-#: src/pig/templates/app.mako:210 src/pig/templates/app.mako:238
-#: src/pig/templates/app.mako:259 src/pig/templates/app.mako:287
-#: src/pig/templates/app.mako:308 src/pig/templates/app.mako:345
-msgid "Add"
-msgstr "Agregar"
-
-#: src/pig/templates/app.mako:219 src/pig/templates/app.mako:268
-#: src/pig/templates/app.mako:317
-msgid "Value"
-msgstr "Valor"
-
-#: src/pig/templates/app.mako:232 src/pig/templates/app.mako:281
-#: src/pig/templates/app.mako:338
-msgid "Remove"
-msgstr "Quitar"
-
-#: src/pig/templates/app.mako:246
-#, fuzzy
-msgid "Hadoop properties"
-msgstr "Propiedades de Hadoop"
-
-#: src/pig/templates/app.mako:257
-#, fuzzy
-msgid "There are currently no defined Hadoop properties."
-msgstr "Actualmente no hay ninguna propiedad de Hadoop definida."
-
-#: src/pig/templates/app.mako:296
-msgid "Resources"
-msgstr "Recursos"
-
-#: src/pig/templates/app.mako:299
-msgid "Path to a HDFS file or zip file to add to the workspace of the running script"
-msgstr "Ruta a un archivo HDFS o archivo zip para añadir al espacio de trabajo de la secuencia de comandos en ejecución"
-
-#: src/pig/templates/app.mako:306
-#, fuzzy
-msgid "There are currently no defined resources."
-msgstr "Actualmente no hay ningún recurso definido."
-
-#: src/pig/templates/app.mako:316
-msgid "Type"
-msgstr "Tipo"
-
-#: src/pig/templates/app.mako:327
-msgid "Archive"
-msgstr "Almacenamiento"
-
-#: src/pig/templates/app.mako:363
-msgid "Status:"
-msgstr "Estado:"
-
-#: src/pig/templates/app.mako:365
-msgid "Progress:"
-msgstr "Progreso:"
-
-#: src/pig/templates/app.mako:365
-msgid "%"
-msgstr "%"
-
-#: src/pig/templates/app.mako:371
-msgid "No available logs."
-msgstr "No hay registros disponibles."
-
-#: src/pig/templates/app.mako:385 src/pig/templates/app.mako:873
-msgid "Running"
-msgstr "En ejecución"
-
-#: src/pig/templates/app.mako:389
-msgid "There are currently no running scripts."
-msgstr "Actualmente no hay ninguna secuencia de comandos en ejecución."
-
-#: src/pig/templates/app.mako:395
-msgid "Progress"
-msgstr "Progreso"
-
-#: src/pig/templates/app.mako:396 src/pig/templates/app.mako:423
-msgid "Created on"
-msgstr "Creado el"
-
-#: src/pig/templates/app.mako:412
-msgid "Completed"
-msgstr "Completados"
-
-#: src/pig/templates/app.mako:416
-msgid "There are currently no completed scripts."
-msgstr "Actualmente no hay ninguna secuencia de comandos completada."
-
-#: src/pig/templates/app.mako:422
-msgid "Status"
-msgstr "Estado"
-
-#: src/pig/templates/app.mako:435
-msgid "Click to edit"
-msgstr "Haga clic para editar"
-
-#: src/pig/templates/app.mako:449
-msgid "Click to view"
-msgstr "Haga clic para ver"
-
-#: src/pig/templates/app.mako:466
-msgid "Confirm Delete"
-msgstr "Confirmar eliminación"
-
-#: src/pig/templates/app.mako:469
-msgid "Are you sure you want to delete this script?"
-msgstr "¿Está seguro de que desea eliminar esta secuencia de comandos?"
-
-#: src/pig/templates/app.mako:470
-msgid "Are you sure you want to delete these scripts?"
-msgstr "¿Está seguro de que desea eliminar estas secuencias de comandos?"
-
-#: src/pig/templates/app.mako:473 src/pig/templates/app.mako:507
-#: src/pig/templates/app.mako:518 src/pig/templates/app.mako:547
-msgid "No"
-msgstr "No"
-
-#: src/pig/templates/app.mako:474 src/pig/templates/app.mako:508
-#: src/pig/templates/app.mako:519 src/pig/templates/app.mako:548
-msgid "Yes"
-msgstr "Sí"
-
-#: src/pig/templates/app.mako:488
-msgid "Close"
-msgstr "Cerrar"
-
-#: src/pig/templates/app.mako:495
-msgid "Run Script"
-msgstr "Ejecutar secuencia de comandos"
-
-#: src/pig/templates/app.mako:495 src/pig/templates/app.mako:515
-msgid "?"
-msgstr "?"
-
-#: src/pig/templates/app.mako:498
-msgid "Script variables"
-msgstr "Variables de la secuencia de comandos"
-
-#: src/pig/templates/app.mako:515
-msgid "Stop Script"
-msgstr "Detener secuencia de comandos"
-
-#: src/pig/templates/app.mako:526
-msgid "Choose a file"
-msgstr "Seleccionar un archivo"
-
-#: src/pig/templates/app.mako:539
-msgid "Are you sure?"
-msgstr "¿Está seguro?"
-
-#: src/pig/templates/app.mako:543
-msgid "The current script has unsaved changes. Are you sure you want to discard the changes?"
-msgstr "La secuencia de comandos actual tiene cambios sin guardar. ¿Seguro que desea descartarlos?"
-
-#: src/pig/templates/app.mako:555
-#, fuzzy
-msgid "Save script"
-msgstr "Guardar secuencia de comandos"
-
-#: src/pig/templates/app.mako:559
-msgid "Give a meaningful name to this script."
-msgstr "Dé un nombre significativo a esta secuencia de comandos."
-
-#: src/pig/templates/app.mako:567
-msgid "Cancel"
-msgstr "Cancelar"
-
-#: src/pig/templates/app.mako:597
-#, fuzzy
-msgid "The Pig job could not be killed."
-msgstr "El trabajo pig no se ha podido eliminar."
-
-#: src/pig/templates/app.mako:598
-#, fuzzy
-msgid "Run this Pig script."
-msgstr "Ejecutar esta secuencia de comandos Pig."
-
-#: src/pig/templates/app.mako:599
-#, fuzzy
-msgid "Stop execution."
-msgstr "Detener ejecución."
-
-#: src/pig/templates/app.mako:600
-msgid "Saved"
-msgstr "Guardado"
-
-#: src/pig/templates/app.mako:866
-msgid "Saving"
-msgstr "Guardando"
-
-#: src/pig/templates/app.mako:877
-msgid "has been saved correctly."
-msgstr "se ha guardado correctamente."
-
-#: src/pig/templates/app.mako:881
-msgid "There was an error with your request!"
-msgstr "Se ha producido un error en la solicitud."
-
-#: src/pig/templates/app.mako:1141
-msgid "Did you know?"
-msgstr "¿Lo sabía?"
-
-#: src/pig/templates/app.mako:1148
-msgid "Names and values of Pig parameters and options, e.g."
-msgstr "Nombres y valores de parámetros y opciones Pig, p. ej."
-
-#: src/pig/templates/app.mako:1155
-msgid "Names and values of Hadoop properties, e.g."
-msgstr "Nombres y valores de propiedades de Hadoop, p. ej."
-
-#: src/pig/templates/app.mako:1162
-msgid "Include files or compressed files"
-msgstr "Incluir archivos o archivos comprimidos"
-
-#: src/pig/templates/app.mako:1171
-msgid "You have unsaved changes in this pig script."
-msgstr "Hay cambios sin guardar en esta secuencia de comandos de pig."
-
-#~ msgid "Actions"
-#~ msgstr "Acciones"
-#~ msgid "Current Logs"
-#~ msgstr "Registros actuales"

+ 0 - 461
apps/spark/src/spark/locale/fr/LC_MESSAGES/django.po

@@ -1,461 +0,0 @@
-# French translations for Hue.
-# Copyright (C) 2012 Cloudera
-# This file is distributed under the same license as the Hue project.
-# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: VERSION DU PROJET\n"
-"Report-Msgid-Bugs-To: ADRESSE@MAIL\n"
-"POT-Creation-Date: 2013-08-02 20:43-0700\n"
-"PO-Revision-Date: 2012-07-30 18:50-0700\n"
-"Last-Translator: NOM COMPLET <ADRESSE@MAIL>\n"
-"Language-Team: fr <LL@li.org>\n"
-"Plural-Forms: nplurals=2; plural=(n > 1)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 0.9.6\n"
-
-#: src/pig/api.py:233 src/pig/templates/app.mako:601
-msgid "Unsaved script"
-msgstr "Script non enregistré"
-
-#: src/pig/conf.py:32
-msgid "Location on local filesystem where the examples are stored."
-msgstr "Emplacement sur le système de fichiers local où les exemples sont stockés."
-
-#: src/pig/conf.py:38
-msgid "Location on HDFS where the Pig examples are stored."
-msgstr "Emplacement sur HDFS local où les exemples Pig sont stockés."
-
-#: src/pig/conf.py:48
-msgid "The app won't work without a running Oozie server"
-msgstr "Sans un serveur Oozie en cours d'exécution, l'application ne fonctionnera pas."
-
-#: src/pig/models.py:33
-msgid "Owner"
-msgstr "Propriétaire"
-
-#: src/pig/models.py:33
-msgid "User who can modify the job."
-msgstr "Utilisateur pouvant modifier le job."
-
-#: src/pig/models.py:34
-msgid "Is a user document, not a document submission."
-msgstr "Est un document utilisateur, et non un envoi de document."
-
-#: src/pig/models.py:35
-msgid "If the document is not a submitted job but a real query, script, workflow."
-msgstr "Si le document n'est pas un job envoyé mais une véritable requête, ou script, ou workflow."
-
-#: src/pig/models.py:44
-#, python-format
-msgid "Only superusers and %s are allowed to modify this document."
-msgstr "Seuls les superutilisateurs et %s sont autorisés à modifier ce document."
-
-#: src/pig/views.py:68 src/pig/views.py:93 src/pig/views.py:112
-#: src/pig/views.py:143 src/pig/views.py:179
-msgid "POST request required."
-msgstr "Requête POST requise."
-
-#: src/pig/views.py:104
-msgid "Error stopping Pig script."
-msgstr "Erreur lors de l'arrêt du script Pig."
-
-#: src/pig/views.py:149
-msgid " (Copy)"
-msgstr " (Copier)"
-
-#: src/pig/views.py:227
-msgid "A POST request is required."
-msgstr "Requête POST requise."
-
-#: src/pig/management/commands/pig_setup.py:46
-#, python-format
-msgid "Copying examples %(local_dir)s to %(remote_data_dir)s\n"
-msgstr "Copie des exemples de %(local_dir)s vers %(remote_data_dir)s\n"
-
-#: src/pig/management/commands/pig_setup.py:53
-#, python-format
-msgid "Copying data %(local_dir)s to %(remote_data_dir)s\n"
-msgstr "Copie des données de %(local_dir)s vers %(remote_data_dir)s\n"
-
-#: src/pig/templates/app.mako:28 src/pig/templates/app.mako:103
-msgid "Editor"
-msgstr "Editeur"
-
-#: src/pig/templates/app.mako:29
-msgid "Scripts"
-msgstr "Scripts"
-
-#: src/pig/templates/app.mako:30
-msgid "Dashboard"
-msgstr "Tableau de bord"
-
-#: src/pig/templates/app.mako:40
-msgid "Search for script name or content"
-msgstr "Rechercher le nom ou le contenu du script"
-
-#: src/pig/templates/app.mako:44 src/pig/templates/app.mako:171
-#: src/pig/templates/app.mako:182
-msgid "Run this script"
-msgstr "Exécuter ce script"
-
-#: src/pig/templates/app.mako:44 src/pig/templates/app.mako:118
-msgid "Run"
-msgstr "Exécuter"
-
-#: src/pig/templates/app.mako:45
-msgid "Copy this script"
-msgstr "Copier ce script"
-
-#: src/pig/templates/app.mako:45 src/pig/templates/app.mako:137
-msgid "Copy"
-msgstr "Copier"
-
-#: src/pig/templates/app.mako:46
-msgid "Delete this script"
-msgstr "Supprimer ce script"
-
-#: src/pig/templates/app.mako:46 src/pig/templates/app.mako:142
-msgid "Delete"
-msgstr "Supprimer"
-
-#: src/pig/templates/app.mako:50
-msgid "Create a new script"
-msgstr "Créer un script"
-
-#: src/pig/templates/app.mako:50
-#, fuzzy
-msgid "New Script"
-msgstr "Nouveau script"
-
-#: src/pig/templates/app.mako:54
-msgid "There are currently no scripts defined. Please add a new script clicking on \"New script\""
-msgstr "Il n'existe actuellement aucun script défini. Veuillez ajouter un nouveau script en cliquant sur \"Nouveau script\""
-
-#: src/pig/templates/app.mako:61 src/pig/templates/app.mako:218
-#: src/pig/templates/app.mako:267 src/pig/templates/app.mako:394
-#: src/pig/templates/app.mako:421
-msgid "Name"
-msgstr "Nom"
-
-#: src/pig/templates/app.mako:62 src/pig/templates/app.mako:147
-msgid "Script"
-msgstr "Script"
-
-#: src/pig/templates/app.mako:77
-msgid "There are no scripts matching the search criteria."
-msgstr "Aucun script ne correspond aux critères de recherche."
-
-#: src/pig/templates/app.mako:105
-msgid "Pig"
-msgstr "Pig"
-
-#: src/pig/templates/app.mako:108
-msgid "Properties"
-msgstr "Propriétés"
-
-#: src/pig/templates/app.mako:111
-msgid "Save the script"
-msgstr "Enregistrer le script"
-
-#: src/pig/templates/app.mako:112 src/pig/templates/app.mako:568
-msgid "Save"
-msgstr "Enregistrer"
-
-#: src/pig/templates/app.mako:120
-msgid "Run the script"
-msgstr "Exécuter le script"
-
-#: src/pig/templates/app.mako:121
-msgid "Submit"
-msgstr "Envoyer"
-
-#: src/pig/templates/app.mako:125
-#, fuzzy
-msgid "Stop the script"
-msgstr "Interrompre le script"
-
-#: src/pig/templates/app.mako:126
-msgid "Stop"
-msgstr "Arrêter"
-
-#: src/pig/templates/app.mako:130
-msgid "Show Logs"
-msgstr "Afficher les journaux"
-
-#: src/pig/templates/app.mako:131 src/pig/templates/app.mako:481
-msgid "Logs"
-msgstr "Journaux"
-
-#: src/pig/templates/app.mako:134 src/pig/templates/app.mako:326
-msgid "File"
-msgstr "Fichier"
-
-#: src/pig/templates/app.mako:136
-msgid "Copy the script"
-msgstr "Copier le script"
-
-#: src/pig/templates/app.mako:141
-msgid "Delete the script"
-msgstr "Supprimer le script"
-
-#: src/pig/templates/app.mako:146
-msgid "New script"
-msgstr "Nouveau script"
-
-#: src/pig/templates/app.mako:155
-msgid "Press CTRL + Space to autocomplete"
-msgstr "Appuyez sur CTRL + Barre d'espace pour lancer le remplissage automatique"
-
-#: src/pig/templates/app.mako:156
-msgid "You can execute the current script by pressing CTRL + ENTER or CTRL + . in the editor"
-msgstr "Vous pouvez exécuter le script actuel en appuyant sur CTRL + ENTREE ou sur CTRL + . dans l'éditeur"
-
-#: src/pig/templates/app.mako:166
-#, fuzzy
-msgid "Unsaved"
-msgstr "Non enregistré"
-
-#: src/pig/templates/app.mako:172 src/pig/templates/app.mako:183
-#: src/pig/templates/app.mako:356
-#, fuzzy
-msgid "Stop this script"
-msgstr "Interrompre ce script"
-
-#: src/pig/templates/app.mako:188 src/pig/templates/app.mako:561
-msgid "Script name"
-msgstr "Nom du script"
-
-#: src/pig/templates/app.mako:195
-msgid "Parameters"
-msgstr "Paramètres"
-
-#: src/pig/templates/app.mako:208
-#, fuzzy
-msgid "There are currently no defined parameters."
-msgstr "Il n'existe actuellement aucun paramètre défini."
-
-#: src/pig/templates/app.mako:210 src/pig/templates/app.mako:238
-#: src/pig/templates/app.mako:259 src/pig/templates/app.mako:287
-#: src/pig/templates/app.mako:308 src/pig/templates/app.mako:345
-msgid "Add"
-msgstr "Ajouter"
-
-#: src/pig/templates/app.mako:219 src/pig/templates/app.mako:268
-#: src/pig/templates/app.mako:317
-msgid "Value"
-msgstr "Valeur"
-
-#: src/pig/templates/app.mako:232 src/pig/templates/app.mako:281
-#: src/pig/templates/app.mako:338
-msgid "Remove"
-msgstr "Supprimer"
-
-#: src/pig/templates/app.mako:246
-#, fuzzy
-msgid "Hadoop properties"
-msgstr "Propriétés de Hadoop"
-
-#: src/pig/templates/app.mako:257
-#, fuzzy
-msgid "There are currently no defined Hadoop properties."
-msgstr "Il n'existe actuellement aucune propriété Hadoop définie."
-
-#: src/pig/templates/app.mako:296
-msgid "Resources"
-msgstr "Ressources"
-
-#: src/pig/templates/app.mako:299
-msgid "Path to a HDFS file or zip file to add to the workspace of the running script"
-msgstr "Chemin d'accès vers un fichier HDFS ou un fichier zip à ajouter à l'espace de travail du script en cours d'exécution"
-
-#: src/pig/templates/app.mako:306
-#, fuzzy
-msgid "There are currently no defined resources."
-msgstr "Il n'existe actuellement aucune ressource définie."
-
-#: src/pig/templates/app.mako:316
-msgid "Type"
-msgstr "Type"
-
-#: src/pig/templates/app.mako:327
-msgid "Archive"
-msgstr "Archive"
-
-#: src/pig/templates/app.mako:363
-msgid "Status:"
-msgstr "Etat :"
-
-#: src/pig/templates/app.mako:365
-msgid "Progress:"
-msgstr "Progression :"
-
-#: src/pig/templates/app.mako:365
-msgid "%"
-msgstr "%"
-
-#: src/pig/templates/app.mako:371
-msgid "No available logs."
-msgstr "Aucun journal disponible."
-
-#: src/pig/templates/app.mako:385 src/pig/templates/app.mako:873
-msgid "Running"
-msgstr "En cours d'exécution"
-
-#: src/pig/templates/app.mako:389
-msgid "There are currently no running scripts."
-msgstr "Il n'existe actuellement aucun script en cours d'exécution."
-
-#: src/pig/templates/app.mako:395
-msgid "Progress"
-msgstr "Progression"
-
-#: src/pig/templates/app.mako:396 src/pig/templates/app.mako:423
-msgid "Created on"
-msgstr "Créé le"
-
-#: src/pig/templates/app.mako:412
-msgid "Completed"
-msgstr "Terminé"
-
-#: src/pig/templates/app.mako:416
-msgid "There are currently no completed scripts."
-msgstr "Il n'existe actuellement aucun script terminé."
-
-#: src/pig/templates/app.mako:422
-msgid "Status"
-msgstr "Etat"
-
-#: src/pig/templates/app.mako:435
-msgid "Click to edit"
-msgstr "Cliquer pour modifier"
-
-#: src/pig/templates/app.mako:449
-msgid "Click to view"
-msgstr "Cliquer pour afficher"
-
-#: src/pig/templates/app.mako:466
-msgid "Confirm Delete"
-msgstr "Confirmer la suppression"
-
-#: src/pig/templates/app.mako:469
-msgid "Are you sure you want to delete this script?"
-msgstr "Voulez-vous vraiment supprimer ce script ?"
-
-#: src/pig/templates/app.mako:470
-msgid "Are you sure you want to delete these scripts?"
-msgstr "Voulez-vous vraiment supprimer ces scripts ?"
-
-#: src/pig/templates/app.mako:473 src/pig/templates/app.mako:507
-#: src/pig/templates/app.mako:518 src/pig/templates/app.mako:547
-msgid "No"
-msgstr "Non"
-
-#: src/pig/templates/app.mako:474 src/pig/templates/app.mako:508
-#: src/pig/templates/app.mako:519 src/pig/templates/app.mako:548
-msgid "Yes"
-msgstr "Oui"
-
-#: src/pig/templates/app.mako:488
-msgid "Close"
-msgstr "Fermer"
-
-#: src/pig/templates/app.mako:495
-msgid "Run Script"
-msgstr "Exécuter le script"
-
-#: src/pig/templates/app.mako:495 src/pig/templates/app.mako:515
-msgid "?"
-msgstr "?"
-
-#: src/pig/templates/app.mako:498
-msgid "Script variables"
-msgstr "Variables de script"
-
-#: src/pig/templates/app.mako:515
-msgid "Stop Script"
-msgstr "Interrompre le script"
-
-#: src/pig/templates/app.mako:526
-msgid "Choose a file"
-msgstr "Choisir un fichier"
-
-#: src/pig/templates/app.mako:539
-msgid "Are you sure?"
-msgstr "Etes-vous sûr ?"
-
-#: src/pig/templates/app.mako:543
-msgid "The current script has unsaved changes. Are you sure you want to discard the changes?"
-msgstr "Le script actuel contient des modifications non enregistrées. Souhaitez vous vraiment ignorer ces modifications ?"
-
-#: src/pig/templates/app.mako:555
-#, fuzzy
-msgid "Save script"
-msgstr "Enregistrer le script"
-
-#: src/pig/templates/app.mako:559
-msgid "Give a meaningful name to this script."
-msgstr "Donner un nom explicite à ce script."
-
-#: src/pig/templates/app.mako:567
-msgid "Cancel"
-msgstr "Annuler"
-
-#: src/pig/templates/app.mako:597
-#, fuzzy
-msgid "The Pig job could not be killed."
-msgstr "Le job Pig n'a pas pu être détruit."
-
-#: src/pig/templates/app.mako:598
-#, fuzzy
-msgid "Run this Pig script."
-msgstr "Exécutez ce script Pig."
-
-#: src/pig/templates/app.mako:599
-#, fuzzy
-msgid "Stop execution."
-msgstr "Interrompez l'exécution."
-
-#: src/pig/templates/app.mako:600
-msgid "Saved"
-msgstr "Enregistré"
-
-#: src/pig/templates/app.mako:866
-msgid "Saving"
-msgstr "Enregistrement"
-
-#: src/pig/templates/app.mako:877
-msgid "has been saved correctly."
-msgstr "a été correctement enregistré."
-
-#: src/pig/templates/app.mako:881
-msgid "There was an error with your request!"
-msgstr "Une erreur est survenue avec votre requête."
-
-#: src/pig/templates/app.mako:1141
-msgid "Did you know?"
-msgstr "Le saviez-vous ?"
-
-#: src/pig/templates/app.mako:1148
-msgid "Names and values of Pig parameters and options, e.g."
-msgstr "Noms et valeurs des paramètres et des options Pig, par ex."
-
-#: src/pig/templates/app.mako:1155
-msgid "Names and values of Hadoop properties, e.g."
-msgstr "Noms et valeurs des propriétés Hadoop, par ex."
-
-#: src/pig/templates/app.mako:1162
-msgid "Include files or compressed files"
-msgstr "Inclure des fichiers ou des fichiers compressés"
-
-#: src/pig/templates/app.mako:1171
-msgid "You have unsaved changes in this pig script."
-msgstr "Ce script Pig contient des modifications non enregistrées."
-
-#~ msgid "Actions"
-#~ msgstr "Actions"
-#~ msgid "Current Logs"
-#~ msgstr "Journaux actuels"

+ 0 - 461
apps/spark/src/spark/locale/ja/LC_MESSAGES/django.po

@@ -1,461 +0,0 @@
-# Japanese translations for Hue.
-# Copyright (C) 2012 Cloudera
-# This file is distributed under the same license as the Hue project.
-# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: PROJECT VERSION\n"
-"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2013-08-02 20:43-0700\n"
-"PO-Revision-Date: 2012-07-30 18:50-0700\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: ja <LL@li.org>\n"
-"Plural-Forms: nplurals=1; plural=0\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 0.9.6\n"
-
-#: src/pig/api.py:233 src/pig/templates/app.mako:601
-msgid "Unsaved script"
-msgstr "未保存のスクリプト"
-
-#: src/pig/conf.py:32
-msgid "Location on local filesystem where the examples are stored."
-msgstr "例が保存されているローカルファイルシステム上の場所です。"
-
-#: src/pig/conf.py:38
-msgid "Location on HDFS where the Pig examples are stored."
-msgstr "Pig の例が保存されている HDFS 上の場所です。"
-
-#: src/pig/conf.py:48
-msgid "The app won't work without a running Oozie server"
-msgstr "実行中の Oozie Server が存在しない場合、アプリが機能しません"
-
-#: src/pig/models.py:33
-msgid "Owner"
-msgstr "所有者"
-
-#: src/pig/models.py:33
-msgid "User who can modify the job."
-msgstr "ジョブを変更できるユーザーです。"
-
-#: src/pig/models.py:34
-msgid "Is a user document, not a document submission."
-msgstr "ユーザードキュメントです。ドキュメントサブミッションではありません。"
-
-#: src/pig/models.py:35
-msgid "If the document is not a submitted job but a real query, script, workflow."
-msgstr "ドキュメントがサブミットしたジョブではなく実際のクエリ、、スクリプト、Workflow である場合。"
-
-#: src/pig/models.py:44
-#, python-format
-msgid "Only superusers and %s are allowed to modify this document."
-msgstr "スーパーユーザーと %s のみが、このドキュメントを変更できます。"
-
-#: src/pig/views.py:68 src/pig/views.py:93 src/pig/views.py:112
-#: src/pig/views.py:143 src/pig/views.py:179
-msgid "POST request required."
-msgstr "POST 要求が必要です。"
-
-#: src/pig/views.py:104
-msgid "Error stopping Pig script."
-msgstr "Pig スクリプトの停止中にエラーが発生しました。"
-
-#: src/pig/views.py:149
-msgid " (Copy)"
-msgstr " (コピー)"
-
-#: src/pig/views.py:227
-msgid "A POST request is required."
-msgstr "POST 要求が必要です。"
-
-#: src/pig/management/commands/pig_setup.py:46
-#, python-format
-msgid "Copying examples %(local_dir)s to %(remote_data_dir)s\n"
-msgstr "例を %(local_dir)s から %(remote_data_dir)s にコピーしています\n"
-
-#: src/pig/management/commands/pig_setup.py:53
-#, python-format
-msgid "Copying data %(local_dir)s to %(remote_data_dir)s\n"
-msgstr "データを %(local_dir)s から %(remote_data_dir)s にコピーしています\n"
-
-#: src/pig/templates/app.mako:28 src/pig/templates/app.mako:103
-msgid "Editor"
-msgstr "エディタ"
-
-#: src/pig/templates/app.mako:29
-msgid "Scripts"
-msgstr "スクリプト"
-
-#: src/pig/templates/app.mako:30
-msgid "Dashboard"
-msgstr "ダッシュボード"
-
-#: src/pig/templates/app.mako:40
-msgid "Search for script name or content"
-msgstr "スクリプト名または内容の検索"
-
-#: src/pig/templates/app.mako:44 src/pig/templates/app.mako:171
-#: src/pig/templates/app.mako:182
-msgid "Run this script"
-msgstr "このスクリプトを実行"
-
-#: src/pig/templates/app.mako:44 src/pig/templates/app.mako:118
-msgid "Run"
-msgstr "実行"
-
-#: src/pig/templates/app.mako:45
-msgid "Copy this script"
-msgstr "このスクリプトをコピー"
-
-#: src/pig/templates/app.mako:45 src/pig/templates/app.mako:137
-msgid "Copy"
-msgstr "コピー"
-
-#: src/pig/templates/app.mako:46
-msgid "Delete this script"
-msgstr "このスクリプトを削除"
-
-#: src/pig/templates/app.mako:46 src/pig/templates/app.mako:142
-msgid "Delete"
-msgstr "削除"
-
-#: src/pig/templates/app.mako:50
-msgid "Create a new script"
-msgstr "新しいスクリプトを作成"
-
-#: src/pig/templates/app.mako:50
-#, fuzzy
-msgid "New Script"
-msgstr "新しいスクリプト"
-
-#: src/pig/templates/app.mako:54
-msgid "There are currently no scripts defined. Please add a new script clicking on \"New script\""
-msgstr "現在、スクリプトは定義されていません。[新しいスクリプト]をクリックして、新しいスクリプトを追加してください。"
-
-#: src/pig/templates/app.mako:61 src/pig/templates/app.mako:218
-#: src/pig/templates/app.mako:267 src/pig/templates/app.mako:394
-#: src/pig/templates/app.mako:421
-msgid "Name"
-msgstr "名前"
-
-#: src/pig/templates/app.mako:62 src/pig/templates/app.mako:147
-msgid "Script"
-msgstr "スクリプト"
-
-#: src/pig/templates/app.mako:77
-msgid "There are no scripts matching the search criteria."
-msgstr "検索条件に一致するスクリプトが存在しません。"
-
-#: src/pig/templates/app.mako:105
-msgid "Pig"
-msgstr "Pig"
-
-#: src/pig/templates/app.mako:108
-msgid "Properties"
-msgstr "プロパティ"
-
-#: src/pig/templates/app.mako:111
-msgid "Save the script"
-msgstr "スクリプトを保存"
-
-#: src/pig/templates/app.mako:112 src/pig/templates/app.mako:568
-msgid "Save"
-msgstr "保存"
-
-#: src/pig/templates/app.mako:120
-msgid "Run the script"
-msgstr "スクリプトを実行"
-
-#: src/pig/templates/app.mako:121
-msgid "Submit"
-msgstr "サブミット"
-
-#: src/pig/templates/app.mako:125
-#, fuzzy
-msgid "Stop the script"
-msgstr "スクリプトを停止"
-
-#: src/pig/templates/app.mako:126
-msgid "Stop"
-msgstr "停止"
-
-#: src/pig/templates/app.mako:130
-msgid "Show Logs"
-msgstr "ログを表示"
-
-#: src/pig/templates/app.mako:131 src/pig/templates/app.mako:481
-msgid "Logs"
-msgstr "ログ"
-
-#: src/pig/templates/app.mako:134 src/pig/templates/app.mako:326
-msgid "File"
-msgstr "ファイル"
-
-#: src/pig/templates/app.mako:136
-msgid "Copy the script"
-msgstr "スクリプトをコピー"
-
-#: src/pig/templates/app.mako:141
-msgid "Delete the script"
-msgstr "スクリプトを削除"
-
-#: src/pig/templates/app.mako:146
-msgid "New script"
-msgstr "新しいスクリプト"
-
-#: src/pig/templates/app.mako:155
-msgid "Press CTRL + Space to autocomplete"
-msgstr "Ctrl キーを押したまま Space キーを押すと、オートコンプリート"
-
-#: src/pig/templates/app.mako:156
-msgid "You can execute the current script by pressing CTRL + ENTER or CTRL + . in the editor"
-msgstr "エディタで Ctrl キーを押したまま ENTER キーを押すか、Ctrl キーを押したまま .(ピリオド)を押すと、現在のスクリプトを実行できます"
-
-#: src/pig/templates/app.mako:166
-#, fuzzy
-msgid "Unsaved"
-msgstr "未保存"
-
-#: src/pig/templates/app.mako:172 src/pig/templates/app.mako:183
-#: src/pig/templates/app.mako:356
-#, fuzzy
-msgid "Stop this script"
-msgstr "このスクリプトを停止"
-
-#: src/pig/templates/app.mako:188 src/pig/templates/app.mako:561
-msgid "Script name"
-msgstr "スクリプト名"
-
-#: src/pig/templates/app.mako:195
-msgid "Parameters"
-msgstr "パラメータ"
-
-#: src/pig/templates/app.mako:208
-#, fuzzy
-msgid "There are currently no defined parameters."
-msgstr "現在、定義されているパラメータはありません。"
-
-#: src/pig/templates/app.mako:210 src/pig/templates/app.mako:238
-#: src/pig/templates/app.mako:259 src/pig/templates/app.mako:287
-#: src/pig/templates/app.mako:308 src/pig/templates/app.mako:345
-msgid "Add"
-msgstr "追加"
-
-#: src/pig/templates/app.mako:219 src/pig/templates/app.mako:268
-#: src/pig/templates/app.mako:317
-msgid "Value"
-msgstr "値"
-
-#: src/pig/templates/app.mako:232 src/pig/templates/app.mako:281
-#: src/pig/templates/app.mako:338
-msgid "Remove"
-msgstr "削除"
-
-#: src/pig/templates/app.mako:246
-#, fuzzy
-msgid "Hadoop properties"
-msgstr "Hadoop プロパティ"
-
-#: src/pig/templates/app.mako:257
-#, fuzzy
-msgid "There are currently no defined Hadoop properties."
-msgstr "現在、定義された Hadoop プロパティはありません。"
-
-#: src/pig/templates/app.mako:296
-msgid "Resources"
-msgstr "リソース"
-
-#: src/pig/templates/app.mako:299
-msgid "Path to a HDFS file or zip file to add to the workspace of the running script"
-msgstr "実行中のスクリプトの Workspace に追加する HDFS ファイルまたは zip ファイルへのパス"
-
-#: src/pig/templates/app.mako:306
-#, fuzzy
-msgid "There are currently no defined resources."
-msgstr "現在、定義されているリソースはありません。"
-
-#: src/pig/templates/app.mako:316
-msgid "Type"
-msgstr "タイプ"
-
-#: src/pig/templates/app.mako:327
-msgid "Archive"
-msgstr "アーカイブ"
-
-#: src/pig/templates/app.mako:363
-msgid "Status:"
-msgstr "ステータス:"
-
-#: src/pig/templates/app.mako:365
-msgid "Progress:"
-msgstr "進行状況:"
-
-#: src/pig/templates/app.mako:365
-msgid "%"
-msgstr "%"
-
-#: src/pig/templates/app.mako:371
-msgid "No available logs."
-msgstr "利用可能なログがありません。"
-
-#: src/pig/templates/app.mako:385 src/pig/templates/app.mako:873
-msgid "Running"
-msgstr "実行中"
-
-#: src/pig/templates/app.mako:389
-msgid "There are currently no running scripts."
-msgstr "現在実行中のスクリプトはありません。"
-
-#: src/pig/templates/app.mako:395
-msgid "Progress"
-msgstr "進行状況"
-
-#: src/pig/templates/app.mako:396 src/pig/templates/app.mako:423
-msgid "Created on"
-msgstr "作成日"
-
-#: src/pig/templates/app.mako:412
-msgid "Completed"
-msgstr "完了"
-
-#: src/pig/templates/app.mako:416
-msgid "There are currently no completed scripts."
-msgstr "現在完了したスクリプトはありません。"
-
-#: src/pig/templates/app.mako:422
-msgid "Status"
-msgstr "ステータス"
-
-#: src/pig/templates/app.mako:435
-msgid "Click to edit"
-msgstr "クリックして編集"
-
-#: src/pig/templates/app.mako:449
-msgid "Click to view"
-msgstr "クリックして表示"
-
-#: src/pig/templates/app.mako:466
-msgid "Confirm Delete"
-msgstr "削除を確認"
-
-#: src/pig/templates/app.mako:469
-msgid "Are you sure you want to delete this script?"
-msgstr "このスクリプトを削除してもよろしいですか?"
-
-#: src/pig/templates/app.mako:470
-msgid "Are you sure you want to delete these scripts?"
-msgstr "これらのスクリプトを削除してもよろしいですか?"
-
-#: src/pig/templates/app.mako:473 src/pig/templates/app.mako:507
-#: src/pig/templates/app.mako:518 src/pig/templates/app.mako:547
-msgid "No"
-msgstr "いいえ"
-
-#: src/pig/templates/app.mako:474 src/pig/templates/app.mako:508
-#: src/pig/templates/app.mako:519 src/pig/templates/app.mako:548
-msgid "Yes"
-msgstr "はい"
-
-#: src/pig/templates/app.mako:488
-msgid "Close"
-msgstr "閉じる"
-
-#: src/pig/templates/app.mako:495
-msgid "Run Script"
-msgstr "スクリプトを実行"
-
-#: src/pig/templates/app.mako:495 src/pig/templates/app.mako:515
-msgid "?"
-msgstr "?"
-
-#: src/pig/templates/app.mako:498
-msgid "Script variables"
-msgstr "スクリプト変数"
-
-#: src/pig/templates/app.mako:515
-msgid "Stop Script"
-msgstr "スクリプトを停止"
-
-#: src/pig/templates/app.mako:526
-msgid "Choose a file"
-msgstr "ファイルを選択"
-
-#: src/pig/templates/app.mako:539
-msgid "Are you sure?"
-msgstr "よろしいですか?"
-
-#: src/pig/templates/app.mako:543
-msgid "The current script has unsaved changes. Are you sure you want to discard the changes?"
-msgstr "現在のスクリプトには、未保存の変更があります。変更を破棄してもよろしいですか?"
-
-#: src/pig/templates/app.mako:555
-#, fuzzy
-msgid "Save script"
-msgstr "スクリプトの保存"
-
-#: src/pig/templates/app.mako:559
-msgid "Give a meaningful name to this script."
-msgstr "このスクリプトに意味のある名前を付けます。"
-
-#: src/pig/templates/app.mako:567
-msgid "Cancel"
-msgstr "キャンセル"
-
-#: src/pig/templates/app.mako:597
-#, fuzzy
-msgid "The Pig job could not be killed."
-msgstr "Pig ジョブを強制終了できませんでした。"
-
-#: src/pig/templates/app.mako:598
-#, fuzzy
-msgid "Run this Pig script."
-msgstr "この Pig スクリプトを実行します。"
-
-#: src/pig/templates/app.mako:599
-#, fuzzy
-msgid "Stop execution."
-msgstr "実行を停止します。"
-
-#: src/pig/templates/app.mako:600
-msgid "Saved"
-msgstr "保存済み"
-
-#: src/pig/templates/app.mako:866
-msgid "Saving"
-msgstr "保存中"
-
-#: src/pig/templates/app.mako:877
-msgid "has been saved correctly."
-msgstr "が正しく保存されました。"
-
-#: src/pig/templates/app.mako:881
-msgid "There was an error with your request!"
-msgstr "要求に関するエラーがあります。"
-
-#: src/pig/templates/app.mako:1141
-msgid "Did you know?"
-msgstr "便利な使い方"
-
-#: src/pig/templates/app.mako:1148
-msgid "Names and values of Pig parameters and options, e.g."
-msgstr "Pig パラメータとオプションの名前と値、例"
-
-#: src/pig/templates/app.mako:1155
-msgid "Names and values of Hadoop properties, e.g."
-msgstr "Hadoop プロパティの名前と値、例"
-
-#: src/pig/templates/app.mako:1162
-msgid "Include files or compressed files"
-msgstr "ファイルまたは圧縮ファイルを含む"
-
-#: src/pig/templates/app.mako:1171
-msgid "You have unsaved changes in this pig script."
-msgstr "この Pig スクリプトには、未保存の変更があります。"
-
-#~ msgid "Actions"
-#~ msgstr "アクション"
-#~ msgid "Current Logs"
-#~ msgstr "現在のログ"

+ 0 - 461
apps/spark/src/spark/locale/ko/LC_MESSAGES/django.po

@@ -1,461 +0,0 @@
-# Korean translations for Hue.
-# Copyright (C) 2012 Cloudera
-# This file is distributed under the same license as the Hue project.
-# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: 프로젝트 버전\n"
-"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2013-08-02 20:43-0700\n"
-"PO-Revision-Date: 2012-07-30 18:50-0700\n"
-"Last-Translator: 전체 이름 <EMAIL@ADDRESS>\n"
-"Language-Team: ko <LL@li.org>\n"
-"Plural-Forms: nplurals=1; plural=0\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 0.9.6\n"
-
-#: src/pig/api.py:233 src/pig/templates/app.mako:601
-msgid "Unsaved script"
-msgstr "저장 안 된 스크립트"
-
-#: src/pig/conf.py:32
-msgid "Location on local filesystem where the examples are stored."
-msgstr "예제가 저장되는 로컬 파일 시스템상의 위치입니다."
-
-#: src/pig/conf.py:38
-msgid "Location on HDFS where the Pig examples are stored."
-msgstr "Pig 예제가 저장되는 HDFS상의 위치입니다."
-
-#: src/pig/conf.py:48
-msgid "The app won't work without a running Oozie server"
-msgstr "Oozie Server를 실행하지 않으면 이 앱을 사용할 수 없습니다."
-
-#: src/pig/models.py:33
-msgid "Owner"
-msgstr "소유자"
-
-#: src/pig/models.py:33
-msgid "User who can modify the job."
-msgstr "Job을 수정할 수 있는 사람입니다."
-
-#: src/pig/models.py:34
-msgid "Is a user document, not a document submission."
-msgstr "문서 제출이 아닌 사용자 문서입니다."
-
-#: src/pig/models.py:35
-msgid "If the document is not a submitted job but a real query, script, workflow."
-msgstr "문서가 제출된 Job이 아니라 실제 쿼리, 스크립트, workflow인 경우"
-
-#: src/pig/models.py:44
-#, python-format
-msgid "Only superusers and %s are allowed to modify this document."
-msgstr "superuser 및 %s만 이 문서를 수정할 수 있습니다."
-
-#: src/pig/views.py:68 src/pig/views.py:93 src/pig/views.py:112
-#: src/pig/views.py:143 src/pig/views.py:179
-msgid "POST request required."
-msgstr "POST 요청이 필요합니다."
-
-#: src/pig/views.py:104
-msgid "Error stopping Pig script."
-msgstr "Pig 스크립트를 중지하는 중 오류가 발생했습니다."
-
-#: src/pig/views.py:149
-msgid " (Copy)"
-msgstr " (복사)"
-
-#: src/pig/views.py:227
-msgid "A POST request is required."
-msgstr "POST 요청이 필요합니다."
-
-#: src/pig/management/commands/pig_setup.py:46
-#, python-format
-msgid "Copying examples %(local_dir)s to %(remote_data_dir)s\n"
-msgstr "예제 %(local_dir)s을(를) %(remote_data_dir)s(으)로 복사\n"
-
-#: src/pig/management/commands/pig_setup.py:53
-#, python-format
-msgid "Copying data %(local_dir)s to %(remote_data_dir)s\n"
-msgstr "데이터 %(local_dir)s을(를) %(remote_data_dir)s(으)로 복사\n"
-
-#: src/pig/templates/app.mako:28 src/pig/templates/app.mako:103
-msgid "Editor"
-msgstr "편집기"
-
-#: src/pig/templates/app.mako:29
-msgid "Scripts"
-msgstr "스크립트"
-
-#: src/pig/templates/app.mako:30
-msgid "Dashboard"
-msgstr "대시보드"
-
-#: src/pig/templates/app.mako:40
-msgid "Search for script name or content"
-msgstr "스크립트 이름 또는 콘텐츠 검색"
-
-#: src/pig/templates/app.mako:44 src/pig/templates/app.mako:171
-#: src/pig/templates/app.mako:182
-msgid "Run this script"
-msgstr "이 스크립트 실행"
-
-#: src/pig/templates/app.mako:44 src/pig/templates/app.mako:118
-msgid "Run"
-msgstr "실행"
-
-#: src/pig/templates/app.mako:45
-msgid "Copy this script"
-msgstr "이 스크립트 복사"
-
-#: src/pig/templates/app.mako:45 src/pig/templates/app.mako:137
-msgid "Copy"
-msgstr "복사"
-
-#: src/pig/templates/app.mako:46
-msgid "Delete this script"
-msgstr "이 스크립트 삭제"
-
-#: src/pig/templates/app.mako:46 src/pig/templates/app.mako:142
-msgid "Delete"
-msgstr "삭제"
-
-#: src/pig/templates/app.mako:50
-msgid "Create a new script"
-msgstr "새 스크립트 생성"
-
-#: src/pig/templates/app.mako:50
-#, fuzzy
-msgid "New Script"
-msgstr "새 스크립트"
-
-#: src/pig/templates/app.mako:54
-msgid "There are currently no scripts defined. Please add a new script clicking on \"New script\""
-msgstr "현재 정의된 스크립트가 없습니다. \"새 스크립트\"를 클릭하여 새 스크립트를 추가하십시오."
-
-#: src/pig/templates/app.mako:61 src/pig/templates/app.mako:218
-#: src/pig/templates/app.mako:267 src/pig/templates/app.mako:394
-#: src/pig/templates/app.mako:421
-msgid "Name"
-msgstr "이름"
-
-#: src/pig/templates/app.mako:62 src/pig/templates/app.mako:147
-msgid "Script"
-msgstr "스크립트"
-
-#: src/pig/templates/app.mako:77
-msgid "There are no scripts matching the search criteria."
-msgstr "검색 기준과 일치하는 스크립트가 없습니다."
-
-#: src/pig/templates/app.mako:105
-msgid "Pig"
-msgstr "Pig"
-
-#: src/pig/templates/app.mako:108
-msgid "Properties"
-msgstr "속성"
-
-#: src/pig/templates/app.mako:111
-msgid "Save the script"
-msgstr "스크립트 저장"
-
-#: src/pig/templates/app.mako:112 src/pig/templates/app.mako:568
-msgid "Save"
-msgstr "저장"
-
-#: src/pig/templates/app.mako:120
-msgid "Run the script"
-msgstr "스크립트 실행"
-
-#: src/pig/templates/app.mako:121
-msgid "Submit"
-msgstr "제출"
-
-#: src/pig/templates/app.mako:125
-#, fuzzy
-msgid "Stop the script"
-msgstr "스크립트 저장"
-
-#: src/pig/templates/app.mako:126
-msgid "Stop"
-msgstr "중지"
-
-#: src/pig/templates/app.mako:130
-msgid "Show Logs"
-msgstr "로그 표시"
-
-#: src/pig/templates/app.mako:131 src/pig/templates/app.mako:481
-msgid "Logs"
-msgstr "로그"
-
-#: src/pig/templates/app.mako:134 src/pig/templates/app.mako:326
-msgid "File"
-msgstr "파일"
-
-#: src/pig/templates/app.mako:136
-msgid "Copy the script"
-msgstr "스크립트 복사"
-
-#: src/pig/templates/app.mako:141
-msgid "Delete the script"
-msgstr "스크립트 삭제"
-
-#: src/pig/templates/app.mako:146
-msgid "New script"
-msgstr "새 스크립트"
-
-#: src/pig/templates/app.mako:155
-msgid "Press CTRL + Space to autocomplete"
-msgstr "자동 완성하려면 CTRL + Space 누르기"
-
-#: src/pig/templates/app.mako:156
-msgid "You can execute the current script by pressing CTRL + ENTER or CTRL + . in the editor"
-msgstr "편집기에서 CTRL + ENTER 또는 CTRL + .을 눌러 현재 스크립트를 실행할 수 있습니다."
-
-#: src/pig/templates/app.mako:166
-#, fuzzy
-msgid "Unsaved"
-msgstr "저장 안 됨"
-
-#: src/pig/templates/app.mako:172 src/pig/templates/app.mako:183
-#: src/pig/templates/app.mako:356
-#, fuzzy
-msgid "Stop this script"
-msgstr "이 스크립트 중지"
-
-#: src/pig/templates/app.mako:188 src/pig/templates/app.mako:561
-msgid "Script name"
-msgstr "스크립트 이름"
-
-#: src/pig/templates/app.mako:195
-msgid "Parameters"
-msgstr "매개변수"
-
-#: src/pig/templates/app.mako:208
-#, fuzzy
-msgid "There are currently no defined parameters."
-msgstr "현재 정의된 매개변수가 없습니다."
-
-#: src/pig/templates/app.mako:210 src/pig/templates/app.mako:238
-#: src/pig/templates/app.mako:259 src/pig/templates/app.mako:287
-#: src/pig/templates/app.mako:308 src/pig/templates/app.mako:345
-msgid "Add"
-msgstr "추가"
-
-#: src/pig/templates/app.mako:219 src/pig/templates/app.mako:268
-#: src/pig/templates/app.mako:317
-msgid "Value"
-msgstr "값"
-
-#: src/pig/templates/app.mako:232 src/pig/templates/app.mako:281
-#: src/pig/templates/app.mako:338
-msgid "Remove"
-msgstr "제거"
-
-#: src/pig/templates/app.mako:246
-#, fuzzy
-msgid "Hadoop properties"
-msgstr "Hadoop 속성"
-
-#: src/pig/templates/app.mako:257
-#, fuzzy
-msgid "There are currently no defined Hadoop properties."
-msgstr "현재 정의된 Hadoop 속성이 없습니다."
-
-#: src/pig/templates/app.mako:296
-msgid "Resources"
-msgstr "리소스"
-
-#: src/pig/templates/app.mako:299
-msgid "Path to a HDFS file or zip file to add to the workspace of the running script"
-msgstr "실행 중인 스크립트의 작업 공간에 추가할 HDFS 파일 또는 Zip 파일의 경로"
-
-#: src/pig/templates/app.mako:306
-#, fuzzy
-msgid "There are currently no defined resources."
-msgstr "현재 정의된 리소스가 없습니다."
-
-#: src/pig/templates/app.mako:316
-msgid "Type"
-msgstr "유형"
-
-#: src/pig/templates/app.mako:327
-msgid "Archive"
-msgstr "아카이브"
-
-#: src/pig/templates/app.mako:363
-msgid "Status:"
-msgstr "상태:"
-
-#: src/pig/templates/app.mako:365
-msgid "Progress:"
-msgstr "진행률:"
-
-#: src/pig/templates/app.mako:365
-msgid "%"
-msgstr "%"
-
-#: src/pig/templates/app.mako:371
-msgid "No available logs."
-msgstr "사용할 수 있는 로그가 없습니다."
-
-#: src/pig/templates/app.mako:385 src/pig/templates/app.mako:873
-msgid "Running"
-msgstr "실행 중"
-
-#: src/pig/templates/app.mako:389
-msgid "There are currently no running scripts."
-msgstr "현재 실행 중인 스크립트가 없습니다."
-
-#: src/pig/templates/app.mako:395
-msgid "Progress"
-msgstr "진행률"
-
-#: src/pig/templates/app.mako:396 src/pig/templates/app.mako:423
-msgid "Created on"
-msgstr "생성 위치"
-
-#: src/pig/templates/app.mako:412
-msgid "Completed"
-msgstr "완료됨"
-
-#: src/pig/templates/app.mako:416
-msgid "There are currently no completed scripts."
-msgstr "현재 완료된 스크립트가 없습니다."
-
-#: src/pig/templates/app.mako:422
-msgid "Status"
-msgstr "상태"
-
-#: src/pig/templates/app.mako:435
-msgid "Click to edit"
-msgstr "편집하려면 클릭"
-
-#: src/pig/templates/app.mako:449
-msgid "Click to view"
-msgstr "보려면 클릭"
-
-#: src/pig/templates/app.mako:466
-msgid "Confirm Delete"
-msgstr "삭제 확인"
-
-#: src/pig/templates/app.mako:469
-msgid "Are you sure you want to delete this script?"
-msgstr "이 스크립트를 삭제하시겠습니까?"
-
-#: src/pig/templates/app.mako:470
-msgid "Are you sure you want to delete these scripts?"
-msgstr "이 스크립트를 삭제하시겠습니까?"
-
-#: src/pig/templates/app.mako:473 src/pig/templates/app.mako:507
-#: src/pig/templates/app.mako:518 src/pig/templates/app.mako:547
-msgid "No"
-msgstr "아니요"
-
-#: src/pig/templates/app.mako:474 src/pig/templates/app.mako:508
-#: src/pig/templates/app.mako:519 src/pig/templates/app.mako:548
-msgid "Yes"
-msgstr "예"
-
-#: src/pig/templates/app.mako:488
-msgid "Close"
-msgstr "닫기"
-
-#: src/pig/templates/app.mako:495
-msgid "Run Script"
-msgstr "스크립트 실행"
-
-#: src/pig/templates/app.mako:495 src/pig/templates/app.mako:515
-msgid "?"
-msgstr "?"
-
-#: src/pig/templates/app.mako:498
-msgid "Script variables"
-msgstr "스크립트 변수"
-
-#: src/pig/templates/app.mako:515
-msgid "Stop Script"
-msgstr "스크립트 중지"
-
-#: src/pig/templates/app.mako:526
-msgid "Choose a file"
-msgstr "파일 선택"
-
-#: src/pig/templates/app.mako:539
-msgid "Are you sure?"
-msgstr "계속하시겠습니까?"
-
-#: src/pig/templates/app.mako:543
-msgid "The current script has unsaved changes. Are you sure you want to discard the changes?"
-msgstr "현재 스크립트의 변경 내용이 저장되지 않았습니다. 변경 내용을 취소하시겠습니까?"
-
-#: src/pig/templates/app.mako:555
-#, fuzzy
-msgid "Save script"
-msgstr "스크립트 저장"
-
-#: src/pig/templates/app.mako:559
-msgid "Give a meaningful name to this script."
-msgstr "이 스크립트에 의미 있는 이름을 지정하십시오."
-
-#: src/pig/templates/app.mako:567
-msgid "Cancel"
-msgstr "취소"
-
-#: src/pig/templates/app.mako:597
-#, fuzzy
-msgid "The Pig job could not be killed."
-msgstr "Pig Job을 중지할 수 없습니다."
-
-#: src/pig/templates/app.mako:598
-#, fuzzy
-msgid "Run this Pig script."
-msgstr "이 Pig 스크립트를 실행합니다."
-
-#: src/pig/templates/app.mako:599
-#, fuzzy
-msgid "Stop execution."
-msgstr "실행을 중지합니다."
-
-#: src/pig/templates/app.mako:600
-msgid "Saved"
-msgstr "저장됨"
-
-#: src/pig/templates/app.mako:866
-msgid "Saving"
-msgstr "저장하는 중"
-
-#: src/pig/templates/app.mako:877
-msgid "has been saved correctly."
-msgstr "저장되었습니다."
-
-#: src/pig/templates/app.mako:881
-msgid "There was an error with your request!"
-msgstr "요청에 오류가 있습니다!"
-
-#: src/pig/templates/app.mako:1141
-msgid "Did you know?"
-msgstr "유용한 정보"
-
-#: src/pig/templates/app.mako:1148
-msgid "Names and values of Pig parameters and options, e.g."
-msgstr "Pig 매개변수 및 옵션 등의 이름과 값입니다."
-
-#: src/pig/templates/app.mako:1155
-msgid "Names and values of Hadoop properties, e.g."
-msgstr "Hadoop 속성 등의 이름 및 값"
-
-#: src/pig/templates/app.mako:1162
-msgid "Include files or compressed files"
-msgstr "파일 또는 압축 파일 포함"
-
-#: src/pig/templates/app.mako:1171
-msgid "You have unsaved changes in this pig script."
-msgstr "이 Pig 스크립트에서 변경 내용을 저장하지 않았습니다."
-
-#~ msgid "Actions"
-#~ msgstr "작업"
-#~ msgid "Current Logs"
-#~ msgstr "현재 로그"

+ 0 - 461
apps/spark/src/spark/locale/pt/LC_MESSAGES/django.po

@@ -1,461 +0,0 @@
-# Portuguese translations for Hue.
-# Copyright (C) 2012 Cloudera
-# This file is distributed under the same license as the Hue project.
-# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: VERSÃO DO PROJECTO\n"
-"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2013-08-02 20:43-0700\n"
-"PO-Revision-Date: 2012-07-30 18:50-0700\n"
-"Last-Translator: NOME COMPLETO <EMAIL@ADDRESS>\n"
-"Language-Team: pt <LL@li.org>\n"
-"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 0.9.6\n"
-
-#: src/pig/api.py:233 src/pig/templates/app.mako:601
-msgid "Unsaved script"
-msgstr "Script não guardado"
-
-#: src/pig/conf.py:32
-msgid "Location on local filesystem where the examples are stored."
-msgstr "Localização no sistema de ficheiros local onde os exemplos são armazenados."
-
-#: src/pig/conf.py:38
-msgid "Location on HDFS where the Pig examples are stored."
-msgstr "Localização no HDFS onde os workflows do Pig estão armazenados."
-
-#: src/pig/conf.py:48
-msgid "The app won't work without a running Oozie server"
-msgstr "A aplicação não funciona sem um servidor Oozie em execução"
-
-#: src/pig/models.py:33
-msgid "Owner"
-msgstr "Proprietário"
-
-#: src/pig/models.py:33
-msgid "User who can modify the job."
-msgstr "Utilizador que pode modificar o trabalho."
-
-#: src/pig/models.py:34
-msgid "Is a user document, not a document submission."
-msgstr "É um documento do utilizador, não um envio de documento."
-
-#: src/pig/models.py:35
-msgid "If the document is not a submitted job but a real query, script, workflow."
-msgstr "Se o documento não é um trabalho enviado mas uma consulta, script, workflow real."
-
-#: src/pig/models.py:44
-#, python-format
-msgid "Only superusers and %s are allowed to modify this document."
-msgstr "Apenas super-utilizadores e %s têm permissão para modificar este documento."
-
-#: src/pig/views.py:68 src/pig/views.py:93 src/pig/views.py:112
-#: src/pig/views.py:143 src/pig/views.py:179
-msgid "POST request required."
-msgstr "É necessário um pedido POST."
-
-#: src/pig/views.py:104
-msgid "Error stopping Pig script."
-msgstr "Erro ao parar o script Pig."
-
-#: src/pig/views.py:149
-msgid " (Copy)"
-msgstr " (Copiar)"
-
-#: src/pig/views.py:227
-msgid "A POST request is required."
-msgstr "É necessário um pedido POST."
-
-#: src/pig/management/commands/pig_setup.py:46
-#, python-format
-msgid "Copying examples %(local_dir)s to %(remote_data_dir)s\n"
-msgstr "Copiar exemplos %(local_dir)s para %(remote_data_dir)s\n"
-
-#: src/pig/management/commands/pig_setup.py:53
-#, python-format
-msgid "Copying data %(local_dir)s to %(remote_data_dir)s\n"
-msgstr "Copiar dados de %(local_dir)s para %(remote_data_dir)s\n"
-
-#: src/pig/templates/app.mako:28 src/pig/templates/app.mako:103
-msgid "Editor"
-msgstr "Editor"
-
-#: src/pig/templates/app.mako:29
-msgid "Scripts"
-msgstr "Scripts"
-
-#: src/pig/templates/app.mako:30
-msgid "Dashboard"
-msgstr "Painel"
-
-#: src/pig/templates/app.mako:40
-msgid "Search for script name or content"
-msgstr "Procurar por nome ou conteúdo do script"
-
-#: src/pig/templates/app.mako:44 src/pig/templates/app.mako:171
-#: src/pig/templates/app.mako:182
-msgid "Run this script"
-msgstr "Executar este script"
-
-#: src/pig/templates/app.mako:44 src/pig/templates/app.mako:118
-msgid "Run"
-msgstr "Executar"
-
-#: src/pig/templates/app.mako:45
-msgid "Copy this script"
-msgstr "Copiar o script"
-
-#: src/pig/templates/app.mako:45 src/pig/templates/app.mako:137
-msgid "Copy"
-msgstr "Copiar"
-
-#: src/pig/templates/app.mako:46
-msgid "Delete this script"
-msgstr "Eliminar este script"
-
-#: src/pig/templates/app.mako:46 src/pig/templates/app.mako:142
-msgid "Delete"
-msgstr "Eliminar"
-
-#: src/pig/templates/app.mako:50
-msgid "Create a new script"
-msgstr "Criar um novo script"
-
-#: src/pig/templates/app.mako:50
-#, fuzzy
-msgid "New Script"
-msgstr "Novo script"
-
-#: src/pig/templates/app.mako:54
-msgid "There are currently no scripts defined. Please add a new script clicking on \"New script\""
-msgstr "De momento, não existem scripts definidos. Adicione um novo script, clicando em \"Novo script\""
-
-#: src/pig/templates/app.mako:61 src/pig/templates/app.mako:218
-#: src/pig/templates/app.mako:267 src/pig/templates/app.mako:394
-#: src/pig/templates/app.mako:421
-msgid "Name"
-msgstr "Nome"
-
-#: src/pig/templates/app.mako:62 src/pig/templates/app.mako:147
-msgid "Script"
-msgstr "Script"
-
-#: src/pig/templates/app.mako:77
-msgid "There are no scripts matching the search criteria."
-msgstr "Não há scripts correspondentes aos critérios de pesquisa."
-
-#: src/pig/templates/app.mako:105
-msgid "Pig"
-msgstr "Pig"
-
-#: src/pig/templates/app.mako:108
-msgid "Properties"
-msgstr "Propriedades"
-
-#: src/pig/templates/app.mako:111
-msgid "Save the script"
-msgstr "Guardar o script"
-
-#: src/pig/templates/app.mako:112 src/pig/templates/app.mako:568
-msgid "Save"
-msgstr "Guardar"
-
-#: src/pig/templates/app.mako:120
-msgid "Run the script"
-msgstr "Executar o script"
-
-#: src/pig/templates/app.mako:121
-msgid "Submit"
-msgstr "Enviar"
-
-#: src/pig/templates/app.mako:125
-#, fuzzy
-msgid "Stop the script"
-msgstr "Parar o script"
-
-#: src/pig/templates/app.mako:126
-msgid "Stop"
-msgstr "Parar"
-
-#: src/pig/templates/app.mako:130
-msgid "Show Logs"
-msgstr "Mostrar registos"
-
-#: src/pig/templates/app.mako:131 src/pig/templates/app.mako:481
-msgid "Logs"
-msgstr "Registos"
-
-#: src/pig/templates/app.mako:134 src/pig/templates/app.mako:326
-msgid "File"
-msgstr "Ficheiro"
-
-#: src/pig/templates/app.mako:136
-msgid "Copy the script"
-msgstr "Copiar o script"
-
-#: src/pig/templates/app.mako:141
-msgid "Delete the script"
-msgstr "Eliminar este script"
-
-#: src/pig/templates/app.mako:146
-msgid "New script"
-msgstr "Novo script"
-
-#: src/pig/templates/app.mako:155
-msgid "Press CTRL + Space to autocomplete"
-msgstr "Pressione CTRL + Espaço para autocompletar."
-
-#: src/pig/templates/app.mako:156
-msgid "You can execute the current script by pressing CTRL + ENTER or CTRL + . in the editor"
-msgstr "Pode executar o script actual premindo CTRL + ENTER ou CTRL + . no editor"
-
-#: src/pig/templates/app.mako:166
-#, fuzzy
-msgid "Unsaved"
-msgstr "Não guardado"
-
-#: src/pig/templates/app.mako:172 src/pig/templates/app.mako:183
-#: src/pig/templates/app.mako:356
-#, fuzzy
-msgid "Stop this script"
-msgstr "Parar este script"
-
-#: src/pig/templates/app.mako:188 src/pig/templates/app.mako:561
-msgid "Script name"
-msgstr "Nome do script"
-
-#: src/pig/templates/app.mako:195
-msgid "Parameters"
-msgstr "Parâmetros"
-
-#: src/pig/templates/app.mako:208
-#, fuzzy
-msgid "There are currently no defined parameters."
-msgstr "De momento, não há nenhum parâmetro definido."
-
-#: src/pig/templates/app.mako:210 src/pig/templates/app.mako:238
-#: src/pig/templates/app.mako:259 src/pig/templates/app.mako:287
-#: src/pig/templates/app.mako:308 src/pig/templates/app.mako:345
-msgid "Add"
-msgstr "Adicionar"
-
-#: src/pig/templates/app.mako:219 src/pig/templates/app.mako:268
-#: src/pig/templates/app.mako:317
-msgid "Value"
-msgstr "Valor"
-
-#: src/pig/templates/app.mako:232 src/pig/templates/app.mako:281
-#: src/pig/templates/app.mako:338
-msgid "Remove"
-msgstr "Remover"
-
-#: src/pig/templates/app.mako:246
-#, fuzzy
-msgid "Hadoop properties"
-msgstr "Propriedades do Hadoop"
-
-#: src/pig/templates/app.mako:257
-#, fuzzy
-msgid "There are currently no defined Hadoop properties."
-msgstr "De momento, não existem propriedades Hadoop definidas."
-
-#: src/pig/templates/app.mako:296
-msgid "Resources"
-msgstr "Recursos"
-
-#: src/pig/templates/app.mako:299
-msgid "Path to a HDFS file or zip file to add to the workspace of the running script"
-msgstr "Caminho para um ficheiro HDFS ou ficheiro zip para adicionar ao espaço de trabalho do script em execução"
-
-#: src/pig/templates/app.mako:306
-#, fuzzy
-msgid "There are currently no defined resources."
-msgstr "De momento, não há nenhum recurso definido."
-
-#: src/pig/templates/app.mako:316
-msgid "Type"
-msgstr "Tipo"
-
-#: src/pig/templates/app.mako:327
-msgid "Archive"
-msgstr "Ficheiro"
-
-#: src/pig/templates/app.mako:363
-msgid "Status:"
-msgstr "Estado:"
-
-#: src/pig/templates/app.mako:365
-msgid "Progress:"
-msgstr "Progresso:"
-
-#: src/pig/templates/app.mako:365
-msgid "%"
-msgstr "%"
-
-#: src/pig/templates/app.mako:371
-msgid "No available logs."
-msgstr "Não existem registos disponíveis."
-
-#: src/pig/templates/app.mako:385 src/pig/templates/app.mako:873
-msgid "Running"
-msgstr "Em execução"
-
-#: src/pig/templates/app.mako:389
-msgid "There are currently no running scripts."
-msgstr "De momento, não existem scripts em execução."
-
-#: src/pig/templates/app.mako:395
-msgid "Progress"
-msgstr "Progresso"
-
-#: src/pig/templates/app.mako:396 src/pig/templates/app.mako:423
-msgid "Created on"
-msgstr "Criado a"
-
-#: src/pig/templates/app.mako:412
-msgid "Completed"
-msgstr "Conclusão"
-
-#: src/pig/templates/app.mako:416
-msgid "There are currently no completed scripts."
-msgstr "De momento, não existem scripts concluídos."
-
-#: src/pig/templates/app.mako:422
-msgid "Status"
-msgstr "Estado"
-
-#: src/pig/templates/app.mako:435
-msgid "Click to edit"
-msgstr "Clique para editar"
-
-#: src/pig/templates/app.mako:449
-msgid "Click to view"
-msgstr "Clique para ver"
-
-#: src/pig/templates/app.mako:466
-msgid "Confirm Delete"
-msgstr "Confirmar eliminação"
-
-#: src/pig/templates/app.mako:469
-msgid "Are you sure you want to delete this script?"
-msgstr "Tem a certeza de que pretende eliminar este script?"
-
-#: src/pig/templates/app.mako:470
-msgid "Are you sure you want to delete these scripts?"
-msgstr "Tem a certeza de que pretende eliminar estes scripts?"
-
-#: src/pig/templates/app.mako:473 src/pig/templates/app.mako:507
-#: src/pig/templates/app.mako:518 src/pig/templates/app.mako:547
-msgid "No"
-msgstr "Não"
-
-#: src/pig/templates/app.mako:474 src/pig/templates/app.mako:508
-#: src/pig/templates/app.mako:519 src/pig/templates/app.mako:548
-msgid "Yes"
-msgstr "Sim"
-
-#: src/pig/templates/app.mako:488
-msgid "Close"
-msgstr "Fechar"
-
-#: src/pig/templates/app.mako:495
-msgid "Run Script"
-msgstr "Executar script"
-
-#: src/pig/templates/app.mako:495 src/pig/templates/app.mako:515
-msgid "?"
-msgstr "?"
-
-#: src/pig/templates/app.mako:498
-msgid "Script variables"
-msgstr "Variáveis do script"
-
-#: src/pig/templates/app.mako:515
-msgid "Stop Script"
-msgstr "Parar o script"
-
-#: src/pig/templates/app.mako:526
-msgid "Choose a file"
-msgstr "Escolha um ficheiro"
-
-#: src/pig/templates/app.mako:539
-msgid "Are you sure?"
-msgstr "Tem a certeza?"
-
-#: src/pig/templates/app.mako:543
-msgid "The current script has unsaved changes. Are you sure you want to discard the changes?"
-msgstr "O script actual tem alterações não guardadas. Tem a certeza de que pretende ignorar as alterações?"
-
-#: src/pig/templates/app.mako:555
-#, fuzzy
-msgid "Save script"
-msgstr "Guardar script"
-
-#: src/pig/templates/app.mako:559
-msgid "Give a meaningful name to this script."
-msgstr "Atribua um nome com sentido a este script."
-
-#: src/pig/templates/app.mako:567
-msgid "Cancel"
-msgstr "Cancelar"
-
-#: src/pig/templates/app.mako:597
-#, fuzzy
-msgid "The Pig job could not be killed."
-msgstr "Não foi possível eliminar este trabalho Pig."
-
-#: src/pig/templates/app.mako:598
-#, fuzzy
-msgid "Run this Pig script."
-msgstr "Executar este script pig."
-
-#: src/pig/templates/app.mako:599
-#, fuzzy
-msgid "Stop execution."
-msgstr "Parar a execução."
-
-#: src/pig/templates/app.mako:600
-msgid "Saved"
-msgstr "Guardado"
-
-#: src/pig/templates/app.mako:866
-msgid "Saving"
-msgstr "A guardar"
-
-#: src/pig/templates/app.mako:877
-msgid "has been saved correctly."
-msgstr "foi guardado correctamente."
-
-#: src/pig/templates/app.mako:881
-msgid "There was an error with your request!"
-msgstr "Ocorreu um problema com o seu pedido!"
-
-#: src/pig/templates/app.mako:1141
-msgid "Did you know?"
-msgstr "Sabia?"
-
-#: src/pig/templates/app.mako:1148
-msgid "Names and values of Pig parameters and options, e.g."
-msgstr "Nomes e valores de parâmetros Pig e opções, por ex."
-
-#: src/pig/templates/app.mako:1155
-msgid "Names and values of Hadoop properties, e.g."
-msgstr "Nomes e valores de propriedades Hadoop, por ex."
-
-#: src/pig/templates/app.mako:1162
-msgid "Include files or compressed files"
-msgstr "Incluir ficheiros ou ficheiros comprimidos"
-
-#: src/pig/templates/app.mako:1171
-msgid "You have unsaved changes in this pig script."
-msgstr "Tem alterações não guardadas neste script pig."
-
-#~ msgid "Actions"
-#~ msgstr "Acções"
-#~ msgid "Current Logs"
-#~ msgstr "Registos actuais"

+ 0 - 461
apps/spark/src/spark/locale/pt_BR/LC_MESSAGES/django.po

@@ -1,461 +0,0 @@
-# Portuguese (Brazil) translations for Hue.
-# Copyright (C) 2012 Cloudera
-# This file is distributed under the same license as the Hue project.
-# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: VERSÃO DO PROJETO\n"
-"Report-Msgid-Bugs-To: ENDEREÇO DE E-MAIL\n"
-"POT-Creation-Date: 2013-08-02 20:43-0700\n"
-"PO-Revision-Date: 2012-07-30 18:50-0700\n"
-"Last-Translator: NOME COMPLETO <ENDEREÇO DE E-MAIL>\n"
-"Language-Team: pt_BR <LL@li.org>\n"
-"Plural-Forms: nplurals=2; plural=(n > 1)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 0.9.6\n"
-
-#: src/pig/api.py:233 src/pig/templates/app.mako:601
-msgid "Unsaved script"
-msgstr "Script não salvo"
-
-#: src/pig/conf.py:32
-msgid "Location on local filesystem where the examples are stored."
-msgstr "Localização no sistema de arquivos local onde os exemplos são armazenados."
-
-#: src/pig/conf.py:38
-msgid "Location on HDFS where the Pig examples are stored."
-msgstr "Localização no HDFS onde os exemplos do Pig são armazenados."
-
-#: src/pig/conf.py:48
-msgid "The app won't work without a running Oozie server"
-msgstr "O aplicativo não funcionará sem um servidor Ooozie em execução"
-
-#: src/pig/models.py:33
-msgid "Owner"
-msgstr "Proprietário"
-
-#: src/pig/models.py:33
-msgid "User who can modify the job."
-msgstr "Usuário que pode modificar o job."
-
-#: src/pig/models.py:34
-msgid "Is a user document, not a document submission."
-msgstr "É um documento de usuário, não um envio de documento."
-
-#: src/pig/models.py:35
-msgid "If the document is not a submitted job but a real query, script, workflow."
-msgstr "Se o documento não for um job enviado, mas uma consulta, um script ou um workflow real."
-
-#: src/pig/models.py:44
-#, python-format
-msgid "Only superusers and %s are allowed to modify this document."
-msgstr "Somente superusuários e %s têm permissão para modificar esse documento."
-
-#: src/pig/views.py:68 src/pig/views.py:93 src/pig/views.py:112
-#: src/pig/views.py:143 src/pig/views.py:179
-msgid "POST request required."
-msgstr "Solicitação POST obrigatória."
-
-#: src/pig/views.py:104
-msgid "Error stopping Pig script."
-msgstr "Erro ao interromper script Pig."
-
-#: src/pig/views.py:149
-msgid " (Copy)"
-msgstr " (Copiar)"
-
-#: src/pig/views.py:227
-msgid "A POST request is required."
-msgstr "É necessária uma solicitação POST."
-
-#: src/pig/management/commands/pig_setup.py:46
-#, python-format
-msgid "Copying examples %(local_dir)s to %(remote_data_dir)s\n"
-msgstr "Copiando exemplos %(local_dir)s para %(remote_data_dir)s\n"
-
-#: src/pig/management/commands/pig_setup.py:53
-#, python-format
-msgid "Copying data %(local_dir)s to %(remote_data_dir)s\n"
-msgstr "Copiando dados de %(local_dir)s para %(remote_data_dir)s\n"
-
-#: src/pig/templates/app.mako:28 src/pig/templates/app.mako:103
-msgid "Editor"
-msgstr "Editor"
-
-#: src/pig/templates/app.mako:29
-msgid "Scripts"
-msgstr "Scripts"
-
-#: src/pig/templates/app.mako:30
-msgid "Dashboard"
-msgstr "Painel"
-
-#: src/pig/templates/app.mako:40
-msgid "Search for script name or content"
-msgstr "Procurar nome ou conteúdo do script"
-
-#: src/pig/templates/app.mako:44 src/pig/templates/app.mako:171
-#: src/pig/templates/app.mako:182
-msgid "Run this script"
-msgstr "Executar este script"
-
-#: src/pig/templates/app.mako:44 src/pig/templates/app.mako:118
-msgid "Run"
-msgstr "Executar"
-
-#: src/pig/templates/app.mako:45
-msgid "Copy this script"
-msgstr "Copiar este script"
-
-#: src/pig/templates/app.mako:45 src/pig/templates/app.mako:137
-msgid "Copy"
-msgstr "Copiar"
-
-#: src/pig/templates/app.mako:46
-msgid "Delete this script"
-msgstr "Excluir este script"
-
-#: src/pig/templates/app.mako:46 src/pig/templates/app.mako:142
-msgid "Delete"
-msgstr "Excluir"
-
-#: src/pig/templates/app.mako:50
-msgid "Create a new script"
-msgstr "Criar um novo script"
-
-#: src/pig/templates/app.mako:50
-#, fuzzy
-msgid "New Script"
-msgstr "Novo script"
-
-#: src/pig/templates/app.mako:54
-msgid "There are currently no scripts defined. Please add a new script clicking on \"New script\""
-msgstr "Não há atualmente nenhum script definido. Adicione um novo script clicando em \"Novo script\""
-
-#: src/pig/templates/app.mako:61 src/pig/templates/app.mako:218
-#: src/pig/templates/app.mako:267 src/pig/templates/app.mako:394
-#: src/pig/templates/app.mako:421
-msgid "Name"
-msgstr "Nome"
-
-#: src/pig/templates/app.mako:62 src/pig/templates/app.mako:147
-msgid "Script"
-msgstr "Script"
-
-#: src/pig/templates/app.mako:77
-msgid "There are no scripts matching the search criteria."
-msgstr "Não há scripts correspondentes aos critérios de pesquisa."
-
-#: src/pig/templates/app.mako:105
-msgid "Pig"
-msgstr "Pig"
-
-#: src/pig/templates/app.mako:108
-msgid "Properties"
-msgstr "Propriedades"
-
-#: src/pig/templates/app.mako:111
-msgid "Save the script"
-msgstr "Salvar o script"
-
-#: src/pig/templates/app.mako:112 src/pig/templates/app.mako:568
-msgid "Save"
-msgstr "Salvar"
-
-#: src/pig/templates/app.mako:120
-msgid "Run the script"
-msgstr "Executar o script"
-
-#: src/pig/templates/app.mako:121
-msgid "Submit"
-msgstr "Enviar"
-
-#: src/pig/templates/app.mako:125
-#, fuzzy
-msgid "Stop the script"
-msgstr "Parar o script"
-
-#: src/pig/templates/app.mako:126
-msgid "Stop"
-msgstr "Interromper"
-
-#: src/pig/templates/app.mako:130
-msgid "Show Logs"
-msgstr "Mostrar registros"
-
-#: src/pig/templates/app.mako:131 src/pig/templates/app.mako:481
-msgid "Logs"
-msgstr "Registros"
-
-#: src/pig/templates/app.mako:134 src/pig/templates/app.mako:326
-msgid "File"
-msgstr "Arquivo"
-
-#: src/pig/templates/app.mako:136
-msgid "Copy the script"
-msgstr "Copiar o script"
-
-#: src/pig/templates/app.mako:141
-msgid "Delete the script"
-msgstr "Excluir o script"
-
-#: src/pig/templates/app.mako:146
-msgid "New script"
-msgstr "Novo script"
-
-#: src/pig/templates/app.mako:155
-msgid "Press CTRL + Space to autocomplete"
-msgstr "Pressione CTRL + Espaço para autocompletar"
-
-#: src/pig/templates/app.mako:156
-msgid "You can execute the current script by pressing CTRL + ENTER or CTRL + . in the editor"
-msgstr "Você pode executar o script atual pressionando CTRL + ENTER ou CTRL + . no editor"
-
-#: src/pig/templates/app.mako:166
-#, fuzzy
-msgid "Unsaved"
-msgstr "Não salvou"
-
-#: src/pig/templates/app.mako:172 src/pig/templates/app.mako:183
-#: src/pig/templates/app.mako:356
-#, fuzzy
-msgid "Stop this script"
-msgstr "Parar este script"
-
-#: src/pig/templates/app.mako:188 src/pig/templates/app.mako:561
-msgid "Script name"
-msgstr "Nome do script"
-
-#: src/pig/templates/app.mako:195
-msgid "Parameters"
-msgstr "Parâmetros"
-
-#: src/pig/templates/app.mako:208
-#, fuzzy
-msgid "There are currently no defined parameters."
-msgstr "Não há atualmente nenhum parâmetro definido."
-
-#: src/pig/templates/app.mako:210 src/pig/templates/app.mako:238
-#: src/pig/templates/app.mako:259 src/pig/templates/app.mako:287
-#: src/pig/templates/app.mako:308 src/pig/templates/app.mako:345
-msgid "Add"
-msgstr "Adicionar"
-
-#: src/pig/templates/app.mako:219 src/pig/templates/app.mako:268
-#: src/pig/templates/app.mako:317
-msgid "Value"
-msgstr "Valor"
-
-#: src/pig/templates/app.mako:232 src/pig/templates/app.mako:281
-#: src/pig/templates/app.mako:338
-msgid "Remove"
-msgstr "Remover"
-
-#: src/pig/templates/app.mako:246
-#, fuzzy
-msgid "Hadoop properties"
-msgstr "Propriedades do Hadoop"
-
-#: src/pig/templates/app.mako:257
-#, fuzzy
-msgid "There are currently no defined Hadoop properties."
-msgstr "Não há, no momento, propriedades definidas do Hadoop."
-
-#: src/pig/templates/app.mako:296
-msgid "Resources"
-msgstr "Recursos"
-
-#: src/pig/templates/app.mako:299
-msgid "Path to a HDFS file or zip file to add to the workspace of the running script"
-msgstr "Caminho para um arquivo HDFS or arquivo zip a adicionar ao espaço de trabalho do script em execução"
-
-#: src/pig/templates/app.mako:306
-#, fuzzy
-msgid "There are currently no defined resources."
-msgstr "Não há atualmente nenhum recurso definido."
-
-#: src/pig/templates/app.mako:316
-msgid "Type"
-msgstr "Tipo"
-
-#: src/pig/templates/app.mako:327
-msgid "Archive"
-msgstr "Arquivo"
-
-#: src/pig/templates/app.mako:363
-msgid "Status:"
-msgstr "Status:"
-
-#: src/pig/templates/app.mako:365
-msgid "Progress:"
-msgstr "Progresso:"
-
-#: src/pig/templates/app.mako:365
-msgid "%"
-msgstr "%"
-
-#: src/pig/templates/app.mako:371
-msgid "No available logs."
-msgstr "Nenhum registro disponível."
-
-#: src/pig/templates/app.mako:385 src/pig/templates/app.mako:873
-msgid "Running"
-msgstr "Execução"
-
-#: src/pig/templates/app.mako:389
-msgid "There are currently no running scripts."
-msgstr "No momento, não existem scripts em execução."
-
-#: src/pig/templates/app.mako:395
-msgid "Progress"
-msgstr "Progresso"
-
-#: src/pig/templates/app.mako:396 src/pig/templates/app.mako:423
-msgid "Created on"
-msgstr "Criado em"
-
-#: src/pig/templates/app.mako:412
-msgid "Completed"
-msgstr "Concluída"
-
-#: src/pig/templates/app.mako:416
-msgid "There are currently no completed scripts."
-msgstr "No momento, não existem scripts concluídos."
-
-#: src/pig/templates/app.mako:422
-msgid "Status"
-msgstr "Status"
-
-#: src/pig/templates/app.mako:435
-msgid "Click to edit"
-msgstr "Clique para editar"
-
-#: src/pig/templates/app.mako:449
-msgid "Click to view"
-msgstr "Clique para visualizar"
-
-#: src/pig/templates/app.mako:466
-msgid "Confirm Delete"
-msgstr "Confirmar exclusão"
-
-#: src/pig/templates/app.mako:469
-msgid "Are you sure you want to delete this script?"
-msgstr "Tem a certeza de que pretende excluir este script?"
-
-#: src/pig/templates/app.mako:470
-msgid "Are you sure you want to delete these scripts?"
-msgstr "Tem a certeza de que pretende excluir estes scripts?"
-
-#: src/pig/templates/app.mako:473 src/pig/templates/app.mako:507
-#: src/pig/templates/app.mako:518 src/pig/templates/app.mako:547
-msgid "No"
-msgstr "Não"
-
-#: src/pig/templates/app.mako:474 src/pig/templates/app.mako:508
-#: src/pig/templates/app.mako:519 src/pig/templates/app.mako:548
-msgid "Yes"
-msgstr "Sim"
-
-#: src/pig/templates/app.mako:488
-msgid "Close"
-msgstr "Fechar"
-
-#: src/pig/templates/app.mako:495
-msgid "Run Script"
-msgstr "Executar script"
-
-#: src/pig/templates/app.mako:495 src/pig/templates/app.mako:515
-msgid "?"
-msgstr "?"
-
-#: src/pig/templates/app.mako:498
-msgid "Script variables"
-msgstr "Variáveis de script"
-
-#: src/pig/templates/app.mako:515
-msgid "Stop Script"
-msgstr "Parar o script"
-
-#: src/pig/templates/app.mako:526
-msgid "Choose a file"
-msgstr "Escolha um arquivo"
-
-#: src/pig/templates/app.mako:539
-msgid "Are you sure?"
-msgstr "Tem certeza?"
-
-#: src/pig/templates/app.mako:543
-msgid "The current script has unsaved changes. Are you sure you want to discard the changes?"
-msgstr "O script atual tem alterações não salvas. Tem certeza de que deseja descartar as alterações?"
-
-#: src/pig/templates/app.mako:555
-#, fuzzy
-msgid "Save script"
-msgstr "Salvar script"
-
-#: src/pig/templates/app.mako:559
-msgid "Give a meaningful name to this script."
-msgstr "Dê um nome significativo ao script."
-
-#: src/pig/templates/app.mako:567
-msgid "Cancel"
-msgstr "Cancelar"
-
-#: src/pig/templates/app.mako:597
-#, fuzzy
-msgid "The Pig job could not be killed."
-msgstr "Não foi possível excluir o trabalho pig."
-
-#: src/pig/templates/app.mako:598
-#, fuzzy
-msgid "Run this Pig script."
-msgstr "Executar este script pig."
-
-#: src/pig/templates/app.mako:599
-#, fuzzy
-msgid "Stop execution."
-msgstr "Pare a execução."
-
-#: src/pig/templates/app.mako:600
-msgid "Saved"
-msgstr "Salvo"
-
-#: src/pig/templates/app.mako:866
-msgid "Saving"
-msgstr "Salvando"
-
-#: src/pig/templates/app.mako:877
-msgid "has been saved correctly."
-msgstr "foi salvo corretamente."
-
-#: src/pig/templates/app.mako:881
-msgid "There was an error with your request!"
-msgstr "Ocorreu um problema com o seu pedido!"
-
-#: src/pig/templates/app.mako:1141
-msgid "Did you know?"
-msgstr "Você sabia?"
-
-#: src/pig/templates/app.mako:1148
-msgid "Names and values of Pig parameters and options, e.g."
-msgstr "Nomes e valores dos parâmetros Pig e opções, por exemplo"
-
-#: src/pig/templates/app.mako:1155
-msgid "Names and values of Hadoop properties, e.g."
-msgstr "Nomes e valores de propriedades Hadoop, por exemplo"
-
-#: src/pig/templates/app.mako:1162
-msgid "Include files or compressed files"
-msgstr "Incluir arquivos ou arquivos compactados"
-
-#: src/pig/templates/app.mako:1171
-msgid "You have unsaved changes in this pig script."
-msgstr "Você tem alterações não salvas neste script pig."
-
-#~ msgid "Actions"
-#~ msgstr "Ações"
-#~ msgid "Current Logs"
-#~ msgstr "Registros atuais"

+ 0 - 461
apps/spark/src/spark/locale/zh_CN/LC_MESSAGES/django.po

@@ -1,461 +0,0 @@
-# Chinese (China) translations for Hue.
-# Copyright (C) 2012 Cloudera
-# This file is distributed under the same license as the Hue project.
-# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: 项目版本\n"
-"Report-Msgid-Bugs-To: 电子邮件地址\n"
-"POT-Creation-Date: 2013-08-02 20:43-0700\n"
-"PO-Revision-Date: 2012-07-30 18:50-0700\n"
-"Last-Translator: 全名 <电子邮件地址>\n"
-"Language-Team: zh_CN <LL@li.org>\n"
-"Plural-Forms: nplurals=1; plural=0\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 0.9.6\n"
-
-#: src/pig/api.py:233 src/pig/templates/app.mako:601
-msgid "Unsaved script"
-msgstr "未保存的脚本"
-
-#: src/pig/conf.py:32
-msgid "Location on local filesystem where the examples are stored."
-msgstr "本地文件系统中存储示例的位置。"
-
-#: src/pig/conf.py:38
-msgid "Location on HDFS where the Pig examples are stored."
-msgstr "HDFS 中存储 Pig 示例的位置。"
-
-#: src/pig/conf.py:48
-msgid "The app won't work without a running Oozie server"
-msgstr "Oozie Server 不运行的情况下应用程序不工作"
-
-#: src/pig/models.py:33
-msgid "Owner"
-msgstr "所有者"
-
-#: src/pig/models.py:33
-msgid "User who can modify the job."
-msgstr "可修改作业的用户。"
-
-#: src/pig/models.py:34
-msgid "Is a user document, not a document submission."
-msgstr "为用户文档,而非文档提交。"
-
-#: src/pig/models.py:35
-msgid "If the document is not a submitted job but a real query, script, workflow."
-msgstr "该文档不是已提交的作业,而是真正的查询、脚本、workflow。"
-
-#: src/pig/models.py:44
-#, python-format
-msgid "Only superusers and %s are allowed to modify this document."
-msgstr "只有超级用户和 %s 可修改此文档。"
-
-#: src/pig/views.py:68 src/pig/views.py:93 src/pig/views.py:112
-#: src/pig/views.py:143 src/pig/views.py:179
-msgid "POST request required."
-msgstr "需要 POST 请求。"
-
-#: src/pig/views.py:104
-msgid "Error stopping Pig script."
-msgstr "停止 Pig 脚本时出错。"
-
-#: src/pig/views.py:149
-msgid " (Copy)"
-msgstr " (副本)"
-
-#: src/pig/views.py:227
-msgid "A POST request is required."
-msgstr "需要 POST 请求。"
-
-#: src/pig/management/commands/pig_setup.py:46
-#, python-format
-msgid "Copying examples %(local_dir)s to %(remote_data_dir)s\n"
-msgstr "复制示例 %(local_dir)s 至  %(remote_data_dir)s\n"
-
-#: src/pig/management/commands/pig_setup.py:53
-#, python-format
-msgid "Copying data %(local_dir)s to %(remote_data_dir)s\n"
-msgstr "复制示例 %(local_dir)s 至  %(remote_data_dir)s\n"
-
-#: src/pig/templates/app.mako:28 src/pig/templates/app.mako:103
-msgid "Editor"
-msgstr "编辑器"
-
-#: src/pig/templates/app.mako:29
-msgid "Scripts"
-msgstr "脚本"
-
-#: src/pig/templates/app.mako:30
-msgid "Dashboard"
-msgstr "控制面板"
-
-#: src/pig/templates/app.mako:40
-msgid "Search for script name or content"
-msgstr "搜索脚本名称或内容"
-
-#: src/pig/templates/app.mako:44 src/pig/templates/app.mako:171
-#: src/pig/templates/app.mako:182
-msgid "Run this script"
-msgstr "运行此脚本"
-
-#: src/pig/templates/app.mako:44 src/pig/templates/app.mako:118
-msgid "Run"
-msgstr "运行"
-
-#: src/pig/templates/app.mako:45
-msgid "Copy this script"
-msgstr "复制此脚本"
-
-#: src/pig/templates/app.mako:45 src/pig/templates/app.mako:137
-msgid "Copy"
-msgstr "复制"
-
-#: src/pig/templates/app.mako:46
-msgid "Delete this script"
-msgstr "删除此脚本"
-
-#: src/pig/templates/app.mako:46 src/pig/templates/app.mako:142
-msgid "Delete"
-msgstr "删除"
-
-#: src/pig/templates/app.mako:50
-msgid "Create a new script"
-msgstr "创建新脚本"
-
-#: src/pig/templates/app.mako:50
-#, fuzzy
-msgid "New Script"
-msgstr "新脚本"
-
-#: src/pig/templates/app.mako:54
-msgid "There are currently no scripts defined. Please add a new script clicking on \"New script\""
-msgstr "当前未定义脚本。请通过单击“新脚本”添加新脚本"
-
-#: src/pig/templates/app.mako:61 src/pig/templates/app.mako:218
-#: src/pig/templates/app.mako:267 src/pig/templates/app.mako:394
-#: src/pig/templates/app.mako:421
-msgid "Name"
-msgstr "名称"
-
-#: src/pig/templates/app.mako:62 src/pig/templates/app.mako:147
-msgid "Script"
-msgstr "脚本"
-
-#: src/pig/templates/app.mako:77
-msgid "There are no scripts matching the search criteria."
-msgstr "没有符合搜索条件的脚本。"
-
-#: src/pig/templates/app.mako:105
-msgid "Pig"
-msgstr "Pig"
-
-#: src/pig/templates/app.mako:108
-msgid "Properties"
-msgstr "属性"
-
-#: src/pig/templates/app.mako:111
-msgid "Save the script"
-msgstr "保存脚本"
-
-#: src/pig/templates/app.mako:112 src/pig/templates/app.mako:568
-msgid "Save"
-msgstr "保存"
-
-#: src/pig/templates/app.mako:120
-msgid "Run the script"
-msgstr "运行脚本"
-
-#: src/pig/templates/app.mako:121
-msgid "Submit"
-msgstr "提交"
-
-#: src/pig/templates/app.mako:125
-#, fuzzy
-msgid "Stop the script"
-msgstr "停止脚本"
-
-#: src/pig/templates/app.mako:126
-msgid "Stop"
-msgstr "停止"
-
-#: src/pig/templates/app.mako:130
-msgid "Show Logs"
-msgstr "显示日志"
-
-#: src/pig/templates/app.mako:131 src/pig/templates/app.mako:481
-msgid "Logs"
-msgstr "日志"
-
-#: src/pig/templates/app.mako:134 src/pig/templates/app.mako:326
-msgid "File"
-msgstr "文件"
-
-#: src/pig/templates/app.mako:136
-msgid "Copy the script"
-msgstr "复制脚本"
-
-#: src/pig/templates/app.mako:141
-msgid "Delete the script"
-msgstr "删除脚本"
-
-#: src/pig/templates/app.mako:146
-msgid "New script"
-msgstr "新脚本"
-
-#: src/pig/templates/app.mako:155
-msgid "Press CTRL + Space to autocomplete"
-msgstr "按 CTRL + 空格键自动完成"
-
-#: src/pig/templates/app.mako:156
-msgid "You can execute the current script by pressing CTRL + ENTER or CTRL + . in the editor"
-msgstr "通过在编辑器中按下 CTRL + ENTER 或 CTRL + .,您可以执行当前脚本。"
-
-#: src/pig/templates/app.mako:166
-#, fuzzy
-msgid "Unsaved"
-msgstr "未保存"
-
-#: src/pig/templates/app.mako:172 src/pig/templates/app.mako:183
-#: src/pig/templates/app.mako:356
-#, fuzzy
-msgid "Stop this script"
-msgstr "停止此脚本"
-
-#: src/pig/templates/app.mako:188 src/pig/templates/app.mako:561
-msgid "Script name"
-msgstr "脚本名称"
-
-#: src/pig/templates/app.mako:195
-msgid "Parameters"
-msgstr "参数"
-
-#: src/pig/templates/app.mako:208
-#, fuzzy
-msgid "There are currently no defined parameters."
-msgstr "当前没有已定义的参数。"
-
-#: src/pig/templates/app.mako:210 src/pig/templates/app.mako:238
-#: src/pig/templates/app.mako:259 src/pig/templates/app.mako:287
-#: src/pig/templates/app.mako:308 src/pig/templates/app.mako:345
-msgid "Add"
-msgstr "添加"
-
-#: src/pig/templates/app.mako:219 src/pig/templates/app.mako:268
-#: src/pig/templates/app.mako:317
-msgid "Value"
-msgstr "值"
-
-#: src/pig/templates/app.mako:232 src/pig/templates/app.mako:281
-#: src/pig/templates/app.mako:338
-msgid "Remove"
-msgstr "删除"
-
-#: src/pig/templates/app.mako:246
-#, fuzzy
-msgid "Hadoop properties"
-msgstr "Hadoop 属性"
-
-#: src/pig/templates/app.mako:257
-#, fuzzy
-msgid "There are currently no defined Hadoop properties."
-msgstr "当前没有已定义的 Hadoop 属性。"
-
-#: src/pig/templates/app.mako:296
-msgid "Resources"
-msgstr "资源"
-
-#: src/pig/templates/app.mako:299
-msgid "Path to a HDFS file or zip file to add to the workspace of the running script"
-msgstr "向正在运行的脚本的工作区添加 HDFS 文件或 zip 文件的路径"
-
-#: src/pig/templates/app.mako:306
-#, fuzzy
-msgid "There are currently no defined resources."
-msgstr "当前没有已定义的资源。"
-
-#: src/pig/templates/app.mako:316
-msgid "Type"
-msgstr "类型"
-
-#: src/pig/templates/app.mako:327
-msgid "Archive"
-msgstr "存档"
-
-#: src/pig/templates/app.mako:363
-msgid "Status:"
-msgstr "状态:"
-
-#: src/pig/templates/app.mako:365
-msgid "Progress:"
-msgstr "进度:"
-
-#: src/pig/templates/app.mako:365
-msgid "%"
-msgstr "%"
-
-#: src/pig/templates/app.mako:371
-msgid "No available logs."
-msgstr "没有可用日志。"
-
-#: src/pig/templates/app.mako:385 src/pig/templates/app.mako:873
-msgid "Running"
-msgstr "正在运行"
-
-#: src/pig/templates/app.mako:389
-msgid "There are currently no running scripts."
-msgstr "当前没有正在运行的脚本。"
-
-#: src/pig/templates/app.mako:395
-msgid "Progress"
-msgstr "进度"
-
-#: src/pig/templates/app.mako:396 src/pig/templates/app.mako:423
-msgid "Created on"
-msgstr "创建日期"
-
-#: src/pig/templates/app.mako:412
-msgid "Completed"
-msgstr "已完成"
-
-#: src/pig/templates/app.mako:416
-msgid "There are currently no completed scripts."
-msgstr "当前没有已完成的脚本。"
-
-#: src/pig/templates/app.mako:422
-msgid "Status"
-msgstr "状态"
-
-#: src/pig/templates/app.mako:435
-msgid "Click to edit"
-msgstr "单击以编辑"
-
-#: src/pig/templates/app.mako:449
-msgid "Click to view"
-msgstr "点击查看"
-
-#: src/pig/templates/app.mako:466
-msgid "Confirm Delete"
-msgstr "确认删除"
-
-#: src/pig/templates/app.mako:469
-msgid "Are you sure you want to delete this script?"
-msgstr "是否确定要删除此脚本?"
-
-#: src/pig/templates/app.mako:470
-msgid "Are you sure you want to delete these scripts?"
-msgstr "是否确定要删除这些脚本?"
-
-#: src/pig/templates/app.mako:473 src/pig/templates/app.mako:507
-#: src/pig/templates/app.mako:518 src/pig/templates/app.mako:547
-msgid "No"
-msgstr "否"
-
-#: src/pig/templates/app.mako:474 src/pig/templates/app.mako:508
-#: src/pig/templates/app.mako:519 src/pig/templates/app.mako:548
-msgid "Yes"
-msgstr "是"
-
-#: src/pig/templates/app.mako:488
-msgid "Close"
-msgstr "关闭"
-
-#: src/pig/templates/app.mako:495
-msgid "Run Script"
-msgstr "运行脚本"
-
-#: src/pig/templates/app.mako:495 src/pig/templates/app.mako:515
-msgid "?"
-msgstr "?"
-
-#: src/pig/templates/app.mako:498
-msgid "Script variables"
-msgstr "脚本变量"
-
-#: src/pig/templates/app.mako:515
-msgid "Stop Script"
-msgstr "停止脚本"
-
-#: src/pig/templates/app.mako:526
-msgid "Choose a file"
-msgstr "选择文件"
-
-#: src/pig/templates/app.mako:539
-msgid "Are you sure?"
-msgstr "您是否确定?"
-
-#: src/pig/templates/app.mako:543
-msgid "The current script has unsaved changes. Are you sure you want to discard the changes?"
-msgstr "当前脚本未保存更改。您是否确定放弃更改?"
-
-#: src/pig/templates/app.mako:555
-#, fuzzy
-msgid "Save script"
-msgstr "保存脚本"
-
-#: src/pig/templates/app.mako:559
-msgid "Give a meaningful name to this script."
-msgstr "为此脚本提供一个有意义的名称。"
-
-#: src/pig/templates/app.mako:567
-msgid "Cancel"
-msgstr "取消"
-
-#: src/pig/templates/app.mako:597
-#, fuzzy
-msgid "The Pig job could not be killed."
-msgstr "无法停止 Pig 作业。"
-
-#: src/pig/templates/app.mako:598
-#, fuzzy
-msgid "Run this Pig script."
-msgstr "运行此 Pig 脚本。"
-
-#: src/pig/templates/app.mako:599
-#, fuzzy
-msgid "Stop execution."
-msgstr "停止执行。"
-
-#: src/pig/templates/app.mako:600
-msgid "Saved"
-msgstr "已保存"
-
-#: src/pig/templates/app.mako:866
-msgid "Saving"
-msgstr "正在保存"
-
-#: src/pig/templates/app.mako:877
-msgid "has been saved correctly."
-msgstr "已正确保存。"
-
-#: src/pig/templates/app.mako:881
-msgid "There was an error with your request!"
-msgstr "您的请求有错误!"
-
-#: src/pig/templates/app.mako:1141
-msgid "Did you know?"
-msgstr "您知道吗?"
-
-#: src/pig/templates/app.mako:1148
-msgid "Names and values of Pig parameters and options, e.g."
-msgstr "Pig 参数的名称和数值及选项,例如"
-
-#: src/pig/templates/app.mako:1155
-msgid "Names and values of Hadoop properties, e.g."
-msgstr "Hadoop 属性的名称和数值,例如"
-
-#: src/pig/templates/app.mako:1162
-msgid "Include files or compressed files"
-msgstr "包含文件或压缩文件"
-
-#: src/pig/templates/app.mako:1171
-msgid "You have unsaved changes in this pig script."
-msgstr "您尚未保存此 pig 脚本中的更改。"
-
-#~ msgid "Actions"
-#~ msgstr "操作"
-#~ msgid "Current Logs"
-#~ msgstr "当前日志"

+ 0 - 0
apps/spark/src/spark/management/__init__.py


+ 0 - 0
apps/spark/src/spark/management/commands/__init__.py


+ 0 - 87
apps/spark/src/spark/migrations/0001_initial.py

@@ -1,87 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'SparkScript'
-        db.create_table('spark_sparkscript', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('data', self.gf('django.db.models.fields.TextField')(default='{"name": "", "parameters": [], "script": "", "hadoopProperties": [], "type": "python", "properties": [], "resources": [], "job_id": null}')),
-        ))
-        db.send_create_signal('spark', ['SparkScript'])
-
-
-    def backwards(self, orm):
-        # Deleting model 'SparkScript'
-        db.delete_table('spark_sparkscript')
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'desktop.document': {
-            'Meta': {'object_name': 'Document'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'description': ('django.db.models.fields.TextField', [], {'default': "''"}),
-            'extra': ('django.db.models.fields.TextField', [], {'default': "''"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {'default': "''"}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'doc_owner'", 'to': "orm['auth.User']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['desktop.DocumentTag']", 'db_index': 'True', 'symmetrical': 'False'}),
-            'version': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'})
-        },
-        'desktop.documenttag': {
-            'Meta': {'object_name': 'DocumentTag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'tag': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        },
-        'spark.sparkscript': {
-            'Meta': {'object_name': 'SparkScript'},
-            'data': ('django.db.models.fields.TextField', [], {'default': '\'{"name": "", "parameters": [], "script": "", "hadoopProperties": [], "type": "python", "properties": [], "resources": [], "job_id": null}\''}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        }
-    }
-
-    complete_apps = ['spark']

+ 0 - 0
apps/spark/src/spark/migrations/__init__.py


+ 0 - 122
apps/spark/src/spark/models.py

@@ -14,125 +14,3 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-
-
-import json
-import posixpath
-
-from django.db import models
-from django.contrib.auth.models import User
-from django.contrib.contenttypes import generic
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext as _, ugettext_lazy as _t
-
-from desktop.lib.exceptions_renderable import PopupException
-from desktop.models import Document as Doc
-from hadoop.fs.hadoopfs import Hdfs
-
-
-class SparkScript(models.Model):
-  _ATTRIBUTES = ['script', 'name', 'properties', 'job_id', 'parameters', 'resources', 'hadoopProperties', 'language']
-
-  data = models.TextField(default=json.dumps({
-      'script': '',
-      'name': '',
-      'properties': [],
-      'job_id': None,
-      'parameters': [],
-      'resources': [],
-      'hadoopProperties': [],
-      'language': 'python',
-  }))
-
-  doc = generic.GenericRelation(Doc, related_name='spark_doc')
-
-  def update_from_dict(self, attrs):
-    data_dict = self.dict
-
-    for attr in SparkScript._ATTRIBUTES:
-      if attrs.get(attr) is not None:
-        data_dict[attr] = attrs[attr]
-
-    if 'name' in attrs:
-      self.doc.update(name=attrs['name'])
-
-    self.data = json.dumps(data_dict)
-
-  @property
-  def dict(self):
-    return json.loads(self.data)
-
-  def get_absolute_url(self):
-    return reverse('spark:index') + '#edit/%s' % self.id
-
-
-def create_or_update_script(id, name, script, user, parameters, resources, hadoopProperties, language, is_design=True):
-  try:
-    spark_script = SparkScript.objects.get(id=id)
-    spark_script.doc.get().can_read_or_exception(user)
-  except SparkScript.DoesNotExist:
-    spark_script = SparkScript.objects.create()
-    Doc.objects.link(spark_script, owner=user, name=name)
-    if not is_design:
-      spark_script.doc.get().add_to_history()
-
-  spark_script.update_from_dict({
-      'name': name,
-      'script': script,
-      'parameters': parameters,
-      'resources': resources,
-      'hadoopProperties': hadoopProperties,
-      'language': language,
-  })
-
-  return spark_script
-
-
-def get_scripts(user, is_design=None):
-  scripts = []
-  data = Doc.objects.available(SparkScript, user)
-
-  if is_design is not None:
-    data = [job for job in data if not job.doc.get().is_historic()]
-
-  for script in data:
-    data = script.dict
-    massaged_script = {
-      'id': script.id,
-      'name': data['name'],
-      'script': data['script'],
-      'parameters': data['parameters'],
-      'resources': data['resources'],
-      'hadoopProperties': data.get('hadoopProperties', []),
-      'language': data['language'],
-      'isDesign': not script.doc.get().is_historic(),
-    }
-    scripts.append(massaged_script)
-
-  return scripts
-
-
-def get_workflow_output(oozie_workflow, fs):
-  # TODO: guess from the Input(s):/Output(s)
-  output = None
-
-  if 'workflowRoot' in oozie_workflow.conf_dict:
-    output = oozie_workflow.conf_dict.get('workflowRoot')
-    if output and not fs.exists(output):
-      output = None
-
-  return output
-
-
-def hdfs_link(url):
-  if url:
-    path = Hdfs.urlsplit(url)[2]
-    if path:
-      if path.startswith(posixpath.sep):
-        return "/filebrowser/view" + path
-      else:
-        return "/filebrowser/home_relative_view/" + path
-    else:
-      return url
-  else:
-    return url

+ 2 - 1
apps/spark/src/spark/settings.py

@@ -13,9 +13,10 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+
 DJANGO_APPS = ['spark']
 NICE_NAME = 'Spark Editor'
-MENU_INDEX = 12
+MENU_INDEX = 11
 ICON = '/spark/static/art/icon_spark_24.png'
 
 REQUIRES_HADOOP = False

+ 0 - 1041
apps/spark/src/spark/templates/app.mako

@@ -1,1041 +0,0 @@
-## Licensed to Cloudera, Inc. under one
-## or more contributor license agreements.  See the NOTICE file
-## distributed with this work for additional information
-## regarding copyright ownership.  Cloudera, Inc. licenses this file
-## to you under the Apache License, Version 2.0 (the
-## "License"); you may not use this file except in compliance
-## with the License.  You may obtain a copy of the License at
-##
-##     http://www.apache.org/licenses/LICENSE-2.0
-##
-## Unless required by applicable law or agreed to in writing, software
-## distributed under the License is distributed on an "AS IS" BASIS,
-## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-## See the License for the specific language governing permissions and
-## limitations under the License.
-<%!
-  from desktop.views import commonheader, commonfooter
-  from django.utils.translation import ugettext as _
-%>
-
-<%namespace name="actionbar" file="actionbar.mako" />
-
-${ commonheader(None, "spark", user) | n,unicode }
-
-<div class="navbar navbar-inverse navbar-fixed-top">
-    <div class="navbar-inner">
-      <div class="container-fluid">
-        <div class="nav-collapse">
-          <ul class="nav">
-            <li class="currentApp">
-              <a href="/${app_name}">
-                <img src="/spark/static/art/icon_spark_24.png" />
-                ${ _('Spark Editor') }
-              </a>
-            </li>
-            <li class="active"><a href="#editor" data-bind="css: { unsaved: isDirty }">${ _('Editor') }</a></li>
-            <li><a href="#scripts">${ _('Scripts') }</a></li>
-            <li><a href="#dashboard">${ _('Dashboard') }</a></li>
-          </ul>
-        </div>
-      </div>
-    </div>
-</div>
-
-<div class="container-fluid">
-  <div id="scripts" class="row-fluid mainSection hide">
-    <div class="card card-small">
-      <%actionbar:render>
-        <%def name="search()">
-            <input id="filter" type="text" class="input-xlarge search-query" placeholder="${_('Search for script name or content')}">
-        </%def>
-
-        <%def name="actions()">
-            <button class="btn fileToolbarBtn" title="${_('Run this script')}" data-bind="enable: selectedScripts().length == 1, click: listRunScript, visible: scripts().length > 0"><i class="fa fa-play"></i> ${_('Run')}</button>
-            <button class="btn fileToolbarBtn" title="${_('Copy this script')}" data-bind="enable: selectedScripts().length == 1, click: listCopyScript, visible: scripts().length > 0"><i class="fa fa-files-o"></i> ${_('Copy')}</button>
-            <button class="btn fileToolbarBtn" title="${_('Delete this script')}" data-bind="enable: selectedScripts().length > 0, click: listConfirmDeleteScripts, visible: scripts().length > 0"><i class="fa fa-trash-o"></i> ${_('Delete')}</button>
-        </%def>
-
-        <%def name="creation()">
-            <button class="btn fileToolbarBtn" title="${_('Create a new script')}" data-bind="click: confirmNewScript"><i class="fa fa-plus-circle"></i> ${_('New Script')}</button>
-        </%def>
-      </%actionbar:render>
-      <div class="alert alert-info" data-bind="visible: scripts().length == 0">
-        ${_('There are currently no scripts defined. Please add a new script clicking on "New script"')}
-      </div>
-
-      <table class="table table-striped table-condensed tablescroller-disable" data-bind="visible: scripts().length > 0">
-        <thead>
-        <tr>
-          <th width="1%"><div data-bind="click: selectAll, css: {hueCheckbox: true, 'fa': true, 'fa-check': allSelected}"></div></th>
-          <th width="20%">${_('Name')}</th>
-          <th width="79%">${_('Script')}</th>
-        </tr>
-        </thead>
-        <tbody id="scriptTable" data-bind="template: {name: 'scriptTemplate', foreach: filteredScripts}">
-
-        </tbody>
-        <tfoot>
-        <tr data-bind="visible: isLoading()">
-          <td colspan="3" class="left">
-            <img src="/static/art/spinner.gif" />
-          </td>
-        </tr>
-        <tr data-bind="visible: filteredScripts().length == 0 && !isLoading()">
-          <td colspan="3">
-            <div class="alert">
-                ${_('There are no scripts matching the search criteria.')}
-            </div>
-          </td>
-        </tr>
-        </tfoot>
-      </table>
-
-      <script id="scriptTemplate" type="text/html">
-        <tr style="cursor: pointer" data-bind="event: { mouseover: toggleHover, mouseout: toggleHover}">
-          <td class="center" data-bind="click: handleSelect" style="cursor: default">
-            <div data-bind="css: {hueCheckbox: true, 'fa': true, 'fa-check': selected}"></div>
-          </td>
-          <td data-bind="click: $root.confirmViewScript">
-            <strong><a href="#" data-bind="click: $root.confirmViewScript, text: name"></a></strong>
-          </td>
-          <td data-bind="click: $root.confirmViewScript">
-            <span data-bind="text: scriptSumup"></span>
-          </td>
-        </tr>
-      </script>
-    </div>
-  </div>
-
-  <div id="editor" class="row-fluid mainSection hide">
-    <div class="span2">
-      <div class="sidebar-nav" style="padding-top: 0">
-          <ul class="nav nav-list">
-            <li class="nav-header">${_('Editor')}</li>
-            <li data-bind="click: editScript" class="active" data-section="edit">
-              <a href="#"><i class="fa fa-edit"></i> <span data-bind="text: viewModel.currentScript().language" style="text-transform:capitalize"></span></a>
-            </li>
-            <li data-bind="click: editScriptProperties" data-section="properties">
-              <a href="#"><i class="fa fa-reorder"></i> ${ _('Properties') }</a>
-            </li>
-            <li data-bind="click: saveScript">
-              <a href="#" title="${ _('Save the script') }" rel="tooltip" data-placement="right">
-                <i class="fa fa-floppy-o"></i> ${ _('Save') }
-              </a>
-            </li>
-            <li class="nav-header">${_('Run')}</li>
-            <li data-bind="click: runOrShowSubmissionModal, visible: !currentScript().isRunning()">
-              <a href="#" title="${ _('Run the script') }" rel="tooltip" data-placement="right">
-                <i class="fa fa-play"></i> ${ _('Submit') }
-              </a>
-            </li>
-            <li data-bind="click: showStopModal, visible: currentScript().isRunning()">
-              <a href="#" title="${ _('Stop the script') }" rel="tooltip" data-placement="right" class="disabled">
-                <i class="fa fa-ban"></i> ${ _('Stop') }
-              </a>
-            </li>
-            <li data-bind="click: showScriptLogs" data-section="logs">
-              <a href="#" title="${ _('Show Logs') }" rel="tooltip" data-placement="right">
-                <i class="fa fa-tasks"></i> ${ _('Logs') }
-              </a>
-            </li>
-            <li class="nav-header">${_('File')}</li>
-            <li data-bind="click: confirmNewScript">
-              <a href="#" title="${ _('New script') }" rel="tooltip" data-placement="right">
-                <i class="fa fa-plus-circle"></i> ${ _('New') }
-              </a>
-            </li>
-            <li data-bind="visible: currentScript().id() != -1, click: copyScript">
-              <a href="#" title="${ _('Copy the script') }" rel="tooltip" data-placement="right">
-                <i class="fa fa-files-o"></i> ${ _('Copy') }
-              </a>
-            </li>
-            <li data-bind="visible: currentScript().id() != -1, click: confirmDeleteScript">
-              <a href="#" title="${ _('Delete the script') }" rel="tooltip" data-placement="right">
-                <i class="fa fa-trash-o"></i> ${ _('Delete') }
-              </a>
-            </li>
-            <li>
-            <a href="#" id="help">
-              <i class="fa fa-question-circle"></i>
-            </a>
-            <div id="help-content" class="hide">
-              <ul style="text-align: left;">
-                <li>${ _("Press CTRL + Space to autocomplete") }</li>
-                <li>${ _("You can execute the current script by pressing CTRL + ENTER or CTRL + . in the editor") }</li>
-              </ul>
-            </div>
-            </li>
-          </ul>
-      </div>
-    </div>
-
-    <div class="span10">
-      <div class="ribbon-wrapper" data-bind="visible: isDirty">
-        <div class="ribbon">${ _('Unsaved') }</div>
-      </div>
-
-      <div class="card card-small">
-
-      <div id="edit" class="section">
-        <div class="alert alert-info">
-          <a class="mainAction" href="#" title="${ _('Run this script') }" data-bind="click: runOrShowSubmissionModal, visible: !currentScript().isRunning()"><i class="fa fa-play"></i></a>
-          <a class="mainAction" href="#" title="${ _('Stop this script') }" data-bind="click: showStopModal, visible: currentScript().isRunning()"><i class="fa fa-stop"></i></a>
-          <h3><span data-bind="text: currentScript().name"></span></h3>
-        </div>
-        <div class="row-fluid">
-          <div class="span12">
-            <form id="queryForm">
-              <textarea id="scriptEditor" data-bind="text:currentScript().script"></textarea>
-            </form>
-          </div>
-        </div>
-      </div>
-
-      <div id="properties" class="section hide">
-        <div class="alert alert-info">
-          <a class="mainAction" href="#" title="${ _('Run this script') }" data-bind="click: runOrShowSubmissionModal, visible: !currentScript().isRunning()"><i class="fa fa-play"></i></a>
-          <a class="mainAction" href="#" title="${ _('Stop this script') }" data-bind="click: showStopModal, visible: currentScript().isRunning()"><i class="fa fa-stop"></i></a>
-          <h3><span data-bind="text: currentScript().name"></span></h3>
-        </div>
-        <form class="form-inline" style="padding-left: 10px">
-          <label>
-            ${ _('Script name') } &nbsp;
-            <input type="text" id="scriptName" class="input-xlarge" data-bind="value: currentScript().name, valueUpdate:'afterkeydown'" />
-          </label>
-
-          <br/>
-          <br/>
-
-          <h4>${ _('Resources') } &nbsp; <i id="resources-dyk" class="fa fa-question-circle"></i></h4>
-          <div id="resources-dyk-content" class="hide">
-            <ul style="text-align: left;">
-              <li>${ _("Path to a HDFS file or zip file to add to the workspace of the running script") }</li>
-            </ul>
-          </div>
-          <div class="parameterTableCnt">
-            <table class="parameterTable" data-bind="visible: currentScript().resources().length == 0">
-              <tr>
-                <td>
-                  ${ _('There are currently no defined resources.') }
-                  <button class="btn" data-bind="click: currentScript().addResource" style="margin-left: 4px">
-                    <i class="fa fa-plus"></i> ${ _('Add') }
-                  </button>
-                </td>
-              </tr>
-            </table>
-            <table data-bind="css: {'parameterTable': currentScript().resources().length > 0}">
-              <thead data-bind="visible: currentScript().resources().length > 0">
-                <tr>
-                  <th>${ _('Type') }</th>
-                  <th>${ _('Value') }</th>
-                  <th>&nbsp;</th>
-                </tr>
-              </thead>
-              <tbody data-bind="foreach: currentScript().resources">
-                <tr>
-                  <td>
-                    <select type="text" data-bind="value: type" class="input-xlarge">
-                      <option value="file">${ _('File') }</option>
-                      <option value="archive">${ _('Archive') }</option>
-                    </select>
-                  </td>
-                  <td>
-                    <div class="input-append">
-                      <input type="text" data-bind="value: value" class="input-xxlarge" />
-                      <button class="btn fileChooserBtn" data-bind="click: $root.showFileChooser">..</button>
-                    </div>
-                  </td>
-                  <td>
-                    <button data-bind="click: viewModel.currentScript().removeResource" class="btn">
-                    <i class="fa fa-trash-o"></i> ${ _('Remove') }</button>
-                  </td>
-                </tr>
-              </tbody>
-              <tfoot data-bind="visible: currentScript().resources().length > 0">
-                <tr>
-                  <td colspan="3">
-                    <button class="btn" data-bind="click: currentScript().addResource"><i class="fa fa-plus"></i> ${ _('Add') }</button>
-                  </td>
-                </tr>
-              </tfoot>
-            </table>
-          </div>
-        </form>
-      </div>
-
-      <div id="logs" class="section hide">
-          <div class="alert alert-info">
-            <a class="mainAction" href="#" title="${ _('Stop this script') }" data-bind="click: showStopModal, visible: currentScript().isRunning()"><i class="fa fa-stop"></i></a>
-            <h3><span data-bind="text: currentScript().name"></span></h3>
-          </div>
-          <div data-bind="template: {name: 'logTemplate', foreach: currentScript().actions}"></div>
-          <script id="logTemplate" type="text/html">
-            <div data-bind="css:{'alert-modified': name != '', 'alert': name != '', 'alert-success': status == 'SUCCEEDED' || status == 'OK', 'alert-error': status != 'RUNNING' && status != 'SUCCEEDED' && status != 'OK' && status != 'PREP' && status != 'SUSPENDED'}">
-              <div class="pull-right">
-                  ${ _('Status:') } <a data-bind="text: status, visible: absoluteUrl != '', attr: {'href': absoluteUrl}" target="_blank"/> <i class="fa fa-share"></i>
-              </div>
-              <h4>${ _('Progress:') } <span data-bind="text: progress"></span>${ _('%') }</h4>
-              <div data-bind="css: {'progress': name != '', 'progress-striped': name != '', 'active': status == 'RUNNING'}" style="margin-top:10px">
-                <div data-bind="css: {'bar': name != '', 'bar-success': status == 'SUCCEEDED' || status == 'OK', 'bar-warning': status == 'RUNNING' || status == 'PREP', 'bar-danger': status != 'RUNNING' && status != 'SUCCEEDED' && status != 'OK' && status != 'PREP' && status != 'SUSPENDED'}, attr: {'style': 'width:' + progressPercent}"></div>
-              </div>
-            </div>
-          </script>
-          <pre id="withoutLogs">${ _('No available logs.') } <img src="/static/art/spinner.gif"/></pre>
-          <pre id="withLogs" class="hide scroll"></pre>
-        </div>
-      </div>
-      </div>
-  </div>
-
-  <div id="dashboard" class="row-fluid mainSection hide">
-
-    <div class="card card-small">
-      <h2 class="card-heading simple">${ _('Running') }</h2>
-      <div class="card-body">
-        <p>
-        <div class="alert alert-info" data-bind="visible: runningScripts().length == 0" style="margin-bottom:0">
-          ${_('There are currently no running scripts.')}
-        </div>
-        <table class="table table-striped table-condensed datatables tablescroller-disable" data-bind="visible: runningScripts().length > 0">
-          <thead>
-          <tr>
-            <th width="20%">${_('Name')}</th>
-            <th width="40%">${_('Progress')}</th>
-            <th>${_('Created on')}</th>
-            <th width="30">&nbsp;</th>
-          </tr>
-          </thead>
-          <tbody data-bind="template: {name: 'runningTemplate', foreach: runningScripts}">
-
-          </tbody>
-        </table>
-        </p>
-      </div>
-    </div>
-
-    <div class="card card-small">
-      <h2 class="card-heading simple">${ _('Completed') }</h2>
-      <div class="card-body">
-        <p>
-        <div class="alert alert-info" data-bind="visible: completedScripts().length == 0">
-          ${_('There are currently no completed scripts.')}
-        </div>
-        <table class="table table-striped table-condensed datatables tablescroller-disable" data-bind="visible: completedScripts().length > 0">
-          <thead>
-          <tr>
-            <th width="20%">${_('Name')}</th>
-            <th width="40%">${_('Status')}</th>
-            <th>${_('Created on')}</th>
-          </tr>
-          </thead>
-          <tbody data-bind="template: {name: 'completedTemplate', foreach: completedScripts}">
-
-          </tbody>
-        </table>
-        </p>
-      </div>
-    </div>
-
-    <script id="runningTemplate" type="text/html">
-      <tr style="cursor: pointer">
-        <td data-bind="click: $root.viewSubmittedScript" title="${_('Click to edit')}">
-          <strong><a data-bind="text: appName"></a></strong>
-        </td>
-        <td>
-          <div data-bind="css: {'progress': appName != '', 'progress-striped': appName != '', 'active': status == 'RUNNING'}">
-            <div data-bind="css: {'bar': appName != '', 'bar-success': status == 'SUCCEEDED' || status == 'OK', 'bar-warning': status == 'RUNNING' || status == 'PREP' || status == 'SUSPENDED', 'bar-danger': status != 'RUNNING' && status != 'SUCCEEDED' && status != 'OK' && status != 'PREP' && status != 'SUSPENDED'}, attr: {'style': 'width:' + progressPercent}"></div>
-          </div>
-        </td>
-        <td data-bind="text: created"></td>
-        <td data-bind="click: $root.showLogs"><i class="fa fa-tasks"></i></td>
-      </tr>
-    </script>
-
-    <script id="completedTemplate" type="text/html">
-      <tr style="cursor: pointer" data-bind="click: $root.viewSubmittedScript" title="${_('Click to view')}">
-        <td>
-          <strong><a data-bind="text: appName"></a></strong>
-        </td>
-        <td>
-          <span data-bind="attr: {'class': statusClass}, text: status"></span>
-        </td>
-        <td data-bind="text: created"></td>
-      </tr>
-    </script>
-  </div>
-</div>
-
-
-<div id="deleteModal" class="modal hide fade">
-  <div class="modal-header">
-    <a href="#" class="close" data-dismiss="modal">&times;</a>
-    <h3>${_('Confirm Delete')}</h3>
-  </div>
-  <div class="modal-body">
-    <p class="deleteMsg hide single">${_('Are you sure you want to delete this script?')}</p>
-    <p class="deleteMsg hide multiple">${_('Are you sure you want to delete these scripts?')}</p>
-  </div>
-  <div class="modal-footer">
-    <a class="btn" data-dismiss="modal">${_('No')}</a>
-    <a class="btn btn-danger" data-bind="click: deleteScripts">${_('Yes')}</a>
-  </div>
-</div>
-
-<div id="logsModal" class="modal hide fade">
-  <div class="modal-header">
-    <a href="#" class="close" data-dismiss="modal">&times;</a>
-    <h3>${_('Logs')}</h3>
-  </div>
-  <div class="modal-body">
-    <img src="/static/art/spinner.gif" class="hide" />
-    <pre class="scroll hide"></pre>
-  </div>
-  <div class="modal-footer">
-    <a class="btn" data-dismiss="modal">${_('Close')}</a>
-  </div>
-</div>
-
-<div id="submitModal" class="modal hide fade">
-  <div class="modal-header">
-    <a href="#" class="close" data-dismiss="modal">&times;</a>
-    <h3>${_('Run Script')} '<span data-bind="text: currentScript().name"></span>' ${_('?')}</h3>
-  </div>
-  <div class="modal-body" data-bind="visible: submissionVariables().length > 0">
-    <legend style="color:#666">${_('Script variables')}</legend>
-    <div data-bind="foreach: submissionVariables" style="margin-bottom: 20px">
-      <div class="row-fluid">
-        <span data-bind="text: name" class="span3"></span>
-        <input type="text" data-bind="value: value" class="span9" />
-      </div>
-    </div>
-  </div>
-  <div class="modal-footer">
-    <a class="btn" data-dismiss="modal">${_('No')}</a>
-    <a id="runScriptBtn" class="btn btn-danger disable-feedback" data-bind="click: runScript">${_('Yes')}</a>
-  </div>
-</div>
-
-<div id="stopModal" class="modal hide fade">
-  <div class="modal-header">
-    <a href="#" class="close" data-dismiss="modal">&times;</a>
-    <h3>${_('Stop Script')} '<span data-bind="text: currentScript().name"></span>' ${_('?')}</h3>
-  </div>
-  <div class="modal-footer">
-    <a class="btn" data-dismiss="modal">${_('No')}</a>
-    <a id="stopScriptBtn" class="btn btn-danger disable-feedback" data-bind="click: stopScript">${_('Yes')}</a>
-  </div>
-</div>
-
-<div id="chooseFile" class="modal hide fade">
-    <div class="modal-header">
-        <a href="#" class="close" data-dismiss="modal">&times;</a>
-        <h3>${_('Choose a file')}</h3>
-    </div>
-    <div class="modal-body">
-        <div id="filechooser">
-        </div>
-    </div>
-    <div class="modal-footer">
-    </div>
-</div>
-
-<div id="confirmModal" class="modal hide fade">
-  <div class="modal-header">
-    <a href="#" class="close" data-dismiss="modal">&times;</a>
-    <h3>${_('Are you sure?')}</h3>
-  </div>
-  <div class="modal-body">
-    <p>
-      ${_('The current script has unsaved changes. Are you sure you want to discard the changes?')}
-    </p>
-  </div>
-  <div class="modal-footer">
-    <a class="btn" data-dismiss="modal">${_('No')}</a>
-    <a class="btn btn-danger disable-feedback" data-bind="click: confirmScript">${_('Yes')}</a>
-  </div>
-</div>
-
-<div id="nameModal" class="modal hide fade">
-  <div class="modal-header">
-    <a href="#" class="close" data-dismiss="modal">&times;</a>
-    <h3>${_('Save script')}</h3>
-  </div>
-  <div class="modal-body">
-    <p>
-      ${_('Give a meaningful name to this script.')}<br/><br/>
-      <label>
-        ${ _('Script name') } &nbsp;
-        <input type="text" class="input-xlarge" data-bind="value: currentScript().name, valueUpdate:'afterkeydown'" />
-      </label>
-    </p>
-  </div>
-  <div class="modal-footer">
-    <a class="btn" data-dismiss="modal">${_('Cancel')}</a>
-    <button class="btn btn-primary disable-feedback" data-bind="click: saveScript, enable: currentScript().name() != '' && currentScript().name() != $root.LABELS.NEW_SCRIPT_NAME">${_('Save')}</button>
-  </div>
-</div>
-
-<div id="newScriptModal" class="modal hide fade">
-  <div class="modal-header">
-    <a href="#" class="close" data-dismiss="modal">&times;</a>
-    <h3>${_('New script')}</h3>
-  </div>
-  <div class="modal-body">
-    <p>
-      ${_('Please select the language of your script:')}<br/><br/>
-      <label>
-        ${ _('Java') } &nbsp;
-        <input type="radio" checked name="languages" value="java" data-bind="checked: currentScript().language" />
-      </label>
-      <label>
-        ${ _('Scala') } &nbsp;
-        <input type="radio" name="languages" value="scala" data-bind="checked: currentScript().language" />
-      </label>
-      <label>
-        ${ _('Python') } &nbsp;
-        <input type="radio" name="languages" value="python" data-bind="checked: currentScript().language" />
-      </label>
-    </p>
-  </div>
-  <div class="modal-footer">
-    <a class="btn" data-dismiss="modal">${_('Cancel')}</a>
-    <button class="btn btn-primary disable-feedback" data-bind="click: createAndEditScript">${_('Create')}</button>
-  </div>
-</div>
-
-<div class="bottomAlert alert"></div>
-
-<script src="/static/ext/js/knockout-min.js" type="text/javascript" charset="utf-8"></script>
-<script src="/spark/static/js/utils.js" type="text/javascript" charset="utf-8"></script>
-<script src="/spark/static/js/spark.ko.js" type="text/javascript" charset="utf-8"></script>
-<script src="/static/ext/js/routie-0.3.0.min.js" type="text/javascript" charset="utf-8"></script>
-<script src="/static/ext/js/codemirror-3.11.js"></script>
-<script src="/static/js/codemirror-clike.js"></script>
-<script src="/static/js/codemirror-python.js"></script>
-<script src="/static/js/codemirror-show-hint.js"></script>
-<script src="/static/js/codemirror-python-hint.js"></script>
-<script src="/static/js/codemirror-clike-hint.js"></script>
-<script src="/beeswax/static/js/autocomplete.utils.js" type="text/javascript" charset="utf-8"></script>
-
-<link rel="stylesheet" href="/spark/static/css/spark.css">
-<link rel="stylesheet" href="/static/ext/css/codemirror.css">
-
-<style type="text/css">
-  .fileChooserBtn {
-    border-radius: 0 3px 3px 0;
-  }
-</style>
-
-<script type="text/javascript" charset="utf-8">
-  var LABELS = {
-    KILL_ERROR: "${ _('The spark job could not be killed.') }",
-    TOOLTIP_PLAY: "${ _('Run this spark script.') }",
-    TOOLTIP_STOP: "${ _('Stop execution.') }",
-    SAVED: "${ _('Saved') }",
-    NEW_SCRIPT_NAME: "${ _('Unsaved script') }",
-    NEW_SCRIPT_CONTENT: {
-      'python': "Example:\nfrom pyspark import SparkContext\n\nsc = SparkContext('local', 'App Name')\n\n\nwords = sc.textFile('/usr/share/dict/words')\nprint words.filter(lambda w: w.startswith('spar')).take(5)",
-      'java': 'Example:\npublic class JavaWordCount {\n  ...\n}',
-      'scala': 'Example:\nval distFile = sc.textFile("data.txt")\nval linesWithSpark = distFile.filter(line => line.contains("Spark"))\nprintln(linesWithSpark)'
-    },
-    NEW_SCRIPT_PARAMETERS: [],
-    NEW_SCRIPT_RESOURCES: [],
-    NEW_SCRIPT_HADOOP_PROPERTIES: []
-  };
-
-  var appProperties = {
-    labels: LABELS,
-    listScripts: "${ url('spark:scripts') }",
-    saveUrl: "${ url('spark:save') }",
-    runUrl: "${ url('spark:run') }",
-    stopUrl: "${ url('spark:stop') }",
-    copyUrl: "${ url('spark:copy') }",
-    deleteUrl: "${ url('spark:delete') }"
-  }
-
-  var viewModel = new SparkViewModel(appProperties);
-  ko.applyBindings(viewModel);
-
-  var codeMirror;
-
-  $(document).ready(function () {
-    viewModel.updateScripts();
-
-    var USER_HOME = "/user/${ user }/";
-
-    var scriptEditor = $("#scriptEditor")[0];
-
-    var logsAtEnd = true;
-    var forceLogsAtEnd = false;
-
-    function getLanguageHint() {
-      var _hint = null;
-      switch (viewModel.currentScript().language()) {
-        case "java":
-          _hint = CodeMirror.javaHint;
-          break;
-        case "scala":
-          _hint = CodeMirror.scalaHint;
-          break;
-        case "python":
-          _hint = CodeMirror.pythonHint;
-          break;
-      }
-      return _hint;
-    }
-
-    CodeMirror.commands.autocomplete = function (cm) {
-      $(document.body).on("contextmenu", function (e) {
-        e.preventDefault(); // prevents native menu on FF for Mac from being shown
-      });
-      CodeMirror.showHint(cm, getLanguageHint());
-    }
-    codeMirror = CodeMirror(function (elt) {
-      scriptEditor.parentNode.replaceChild(elt, scriptEditor);
-    }, {
-      value: scriptEditor.value,
-      readOnly: false,
-      lineNumbers: true,
-      mode: "text/x-" + viewModel.currentScript().language(),
-      extraKeys: {
-        "Ctrl-Space": "autocomplete",
-        "Ctrl-Enter": function () {
-          if (!viewModel.currentScript().isRunning()) {
-            viewModel.runOrShowSubmissionModal();
-          }
-        },
-        "Ctrl-.": function () {
-          if (!viewModel.currentScript().isRunning()) {
-            viewModel.runOrShowSubmissionModal();
-          }
-        }
-      },
-      onKeyEvent: function (e, s) {
-        if (s.type == "keyup") {
-          if (s.keyCode == 191) {
-            var _line = codeMirror.getLine(codeMirror.getCursor().line);
-            var _partial = _line.substring(0, codeMirror.getCursor().ch);
-            var _path = _partial.substring(_partial.lastIndexOf("'") + 1);
-            if (_path[0] == "/") {
-              if (_path.lastIndexOf("/") != 0) {
-                showHdfsAutocomplete("/filebrowser/view" + _partial.substring(_partial.lastIndexOf("'") + 1) + "?format=json", false);
-              }
-            }
-            else {
-              showHdfsAutocomplete("/filebrowser/view" + USER_HOME + _partial.substring(_partial.lastIndexOf("'") + 1) + "?format=json", false);
-            }
-          }
-        }
-      }
-    });
-
-    function showHdfsAutocomplete(path, showHCatHint) {
-      $.getJSON(path, function (data) {
-        CodeMirror.currentFiles = [];
-        if (data.error == null) {
-          $(data.files).each(function (cnt, item) {
-            if (item.name != ".") {
-              var _ico = "fa-file-o";
-              if (item.type == "dir") {
-                _ico = "fa-folder";
-              }
-              CodeMirror.currentFiles.push('<i class="fa ' + _ico + '"></i> ' + item.name);
-            }
-          });
-          CodeMirror.isPath = true;
-          CodeMirror.isHCatHint = showHCatHint;
-          window.setTimeout(function () {
-            CodeMirror.showHint(codeMirror,  getLanguageHint());
-          }, 100);  // timeout for IE8
-        }
-      });
-    }
-
-    codeMirror.on("focus", function () {
-      if (codeMirror.getValue() == LABELS.NEW_SCRIPT_CONTENT[viewModel.currentScript().language()]) {
-        codeMirror.setValue("");
-      }
-      if (errorWidget != null) {
-        errorWidget.clear();
-        errorWidget = null;
-      }
-    });
-
-    codeMirror.on("blur", function () {
-      $(document.body).off("contextmenu");
-    });
-
-    codeMirror.on("change", function () {
-      if (viewModel.currentScript().script() != codeMirror.getValue()) {
-        viewModel.currentScript().script(codeMirror.getValue());
-        viewModel.isDirty(true);
-      }
-    });
-
-    showMainSection("editor");
-
-    $(document).on("loadEditor", function () {
-      codeMirror.setValue(viewModel.currentScript().script());
-    });
-
-    $(document).on("showEditor", function () {
-      if (viewModel.currentScript().id() != -1) {
-        routie("edit/" + viewModel.currentScript().id());
-      }
-      else {
-        routie("edit");
-      }
-    });
-
-    $(document).on("showProperties", function () {
-      if (viewModel.currentScript().id() != -1) {
-        routie("properties/" + viewModel.currentScript().id());
-      }
-      else {
-        routie("properties");
-      }
-    });
-
-    $(document).on("showLogs", function () {
-      logsAtEnd = true;
-      forceLogsAtEnd = true;
-      if (viewModel.currentScript().id() != -1) {
-        routie("logs/" + viewModel.currentScript().id());
-      }
-      else {
-        routie("logs");
-      }
-    });
-
-    $(document).on("updateTooltips", function () {
-      $("a[rel=tooltip]").tooltip("destroy");
-      $("a[rel=tooltip]").tooltip();
-    });
-
-    $(document).on("saving", function () {
-      showAlert("${_('Saving')} <b>" + viewModel.currentScript().name() + "</b>...");
-    });
-
-    $(document).on("running", function () {
-      $("#runScriptBtn").button("loading");
-      $("#withoutLogs").removeClass("hide");
-      $("#withLogs").addClass("hide").text("");
-      showAlert("${_('Running')} <b>" + viewModel.currentScript().name() + "</b>...");
-    });
-
-    $(document).on("saved", function () {
-      showAlert("<b>" + viewModel.currentScript().name() + "</b> ${_('has been saved correctly.')}");
-    });
-
-    $(document).on("refreshDashboard", function () {
-      refreshDashboard();
-    });
-
-    $(document).on("showDashboard", function () {
-      routie("dashboard");
-    });
-
-    $(document).on("showScripts", function () {
-      routie("scripts");
-    });
-
-    $(document).on("scriptsRefreshed", function () {
-      $("#filter").val("");
-    });
-
-    var logsRefreshInterval;
-    $(document).on("startLogsRefresh", function () {
-      logsAtEnd = true;
-      window.clearInterval(logsRefreshInterval);
-      $("#withLogs").text("");
-      refreshLogs();
-      logsRefreshInterval = window.setInterval(function () {
-        refreshLogs();
-      }, 1000);
-    });
-
-    $(document).on("stopLogsRefresh", function () {
-      window.clearInterval(logsRefreshInterval);
-    });
-
-    $(document).on("clearLogs", function () {
-      $("#withoutLogs").removeClass("hide");
-      $("#withLogs").text("").addClass("hide");
-      logsAtEnd = true;
-      forceLogsAtEnd = true;
-    });
-
-    var _resizeTimeout = -1;
-    $(window).on("resize", function () {
-      window.clearTimeout(_resizeTimeout);
-      _resizeTimeout = window.setTimeout(function () {
-        codeMirror.setSize("100%", $(window).height() - RESIZE_CORRECTION);
-        $("#navigatorFunctions").css("max-height", ($(window).height() - 370) + "px").css("overflow-y", "auto");
-      }, 100);
-    });
-
-    var _filterTimeout = -1;
-    $("#filter").on("keyup", function () {
-      window.clearTimeout(_filterTimeout);
-      _filterTimeout = window.setTimeout(function () {
-        viewModel.filterScripts($("#filter").val());
-      }, 350);
-    });
-
-    viewModel.filterScripts("");
-
-    refreshDashboard();
-
-    var dashboardRefreshInterval = window.setInterval(function () {
-      if (viewModel.runningScripts().length > 0) {
-        refreshDashboard();
-      }
-    }, 3000);
-
-    function refreshDashboard() {
-      $.getJSON("${ url('spark:dashboard') }", function (data) {
-        viewModel.updateDashboard(data);
-      });
-    }
-
-    var errorWidget = null;
-
-    function checkForErrors(newLines) {
-      $(newLines).each(function (cnt, line) {
-        if (line.indexOf(" ERROR ") > -1) {
-          var _lineNo = line.match(/[Ll]ine \d*/) != null ? line.match(/[Ll]ine \d*/)[0].split(" ")[1] * 1 : -1;
-          var _colNo = line.match(/[Cc]olumn \d*/) != null ? line.match(/[Cc]olumn \d*/)[0].split(" ")[1] * 1 : -1;
-          if (_lineNo != -1 && _colNo != -1 && errorWidget == null) {
-            errorWidget = codeMirror.addLineWidget(_lineNo - 1, $("<div>").addClass("editorError").html("<i class='fa fa-exclamation-circle'></i> " + line)[0], {coverGutter: true, noHScroll: true});
-            codeMirror.setSelection({line: _lineNo - 1, ch: _colNo}, {line: _lineNo - 1, ch: _colNo + codeMirror.getLine(_lineNo - 1).substring(_colNo).split(" ")[0].length});
-            $(document).trigger("showEditor");
-          }
-        }
-      });
-    }
-
-    function refreshLogs() {
-      if (viewModel.currentScript().watchUrl() != "") {
-        $.getJSON(viewModel.currentScript().watchUrl(), function (data) {
-          if (data.logs.spark) {
-            if ($("#withLogs").is(":hidden")) {
-              $("#withoutLogs").addClass("hide");
-              $("#withLogs").removeClass("hide");
-              resizeLogs();
-            }
-            var _logsEl = $("#withLogs");
-            var _newLinesCount = _logsEl.html() == "" ? 0 : _logsEl.html().split("<br>").length;
-            var newLines = data.logs.spark.split("\n").slice(_newLinesCount);
-            if (newLines.length > 0){
-              _logsEl.html(_logsEl.html() + newLines.join("<br>") + "<br>");
-              checkForErrors(newLines);
-            }
-            window.setTimeout(function () {
-              resizeLogs();
-              if (logsAtEnd || forceLogsAtEnd) {
-                _logsEl.scrollTop(_logsEl[0].scrollHeight - _logsEl.height());
-                forceLogsAtEnd = false;
-              }
-            }, 100);
-          }
-          if (data.workflow && data.workflow.isRunning) {
-            viewModel.currentScript().actions(data.workflow.actions);
-          }
-          else {
-            viewModel.currentScript().actions(data.workflow.actions);
-            viewModel.currentScript().isRunning(false);
-            $(document).trigger("stopLogsRefresh");
-          }
-        });
-      }
-      else {
-        $(document).trigger("stopLogsRefresh");
-      }
-    }
-
-    $("#withLogs").scroll(function () {
-      logsAtEnd = $(this).scrollTop() + $(this).height() + 20 >= $(this)[0].scrollHeight;
-    });
-
-    function resizeLogs() {
-      $("#withLogs").css("overflow", "auto").height($(window).height() - $("#withLogs").offset().top - 50);
-    }
-
-    $(window).resize(function () {
-      resizeLogs();
-    });
-
-    var RESIZE_CORRECTION = 246;
-
-    function showMainSection(mainSection, includeGA) {
-      window.setTimeout(function () {
-        codeMirror.refresh();
-        codeMirror.setSize("100%", $(window).height() - RESIZE_CORRECTION);
-      }, 100);
-
-      if ($("#" + mainSection).is(":hidden")) {
-        $(".mainSection").hide();
-        $("#" + mainSection).show();
-        highlightMainMenu(mainSection);
-      }
-      if (typeof trackOnGA == 'function' && includeGA == undefined){
-        trackOnGA(mainSection);
-      }
-    }
-
-    function showSection(mainSection, section) {
-      showMainSection(mainSection, false);
-      if ($("#" + section).is(":hidden")) {
-        $(".section").hide();
-        $("#" + section).show();
-        highlightMenu(section);
-      }
-
-      if (typeof trackOnGA == 'function'){
-        trackOnGA(mainSection + "/" + section);
-      }
-    }
-
-    function highlightMainMenu(mainSection) {
-      $(".navbar-fixed-top .nav li").removeClass("active");
-      $("a[href='#" + mainSection + "']").parent().addClass("active");
-    }
-
-    function highlightMenu(section) {
-      $(".nav-list li").removeClass("active");
-      $("li[data-section='" + section + "']").addClass("active");
-    }
-
-    var dashboardLoadedInterval = -1;
-
-    routie({
-      "editor": function () {
-        showMainSection("editor");
-      },
-      "scripts": function () {
-        showMainSection("scripts");
-      },
-      "dashboard": function () {
-        showMainSection("dashboard");
-      },
-
-      "edit": function () {
-        showSection("editor", "edit");
-      },
-      "edit/:scriptId": function (scriptId) {
-        if (scriptId !== "undefined" && scriptId != viewModel.currentScript().id()) {
-          dashboardLoadedInterval = window.setInterval(function () {
-            if (viewModel.isDashboardLoaded) {
-              window.clearInterval(dashboardLoadedInterval);
-              viewModel.loadScript(scriptId);
-              if (viewModel.currentScript().id() == -1) {
-                viewModel.confirmNewScript();
-              }
-              $(document).trigger("loadEditor");
-            }
-          }, 200);
-        }
-        showSection("editor", "edit");
-      },
-      "properties": function () {
-        showSection("editor", "properties");
-      },
-      "properties/:scriptId": function (scriptId) {
-        if (scriptId !== "undefined" && scriptId != viewModel.currentScript().id()) {
-          dashboardLoadedInterval = window.setInterval(function () {
-            if (viewModel.isDashboardLoaded) {
-              window.clearInterval(dashboardLoadedInterval);
-              viewModel.loadScript(scriptId);
-              if (viewModel.currentScript().id() == -1) {
-                viewModel.confirmNewScript();
-              }
-              $(document).trigger("loadEditor");
-            }
-          }, 200);
-        }
-        showSection("editor", "properties");
-      },
-      "logs": function () {
-        showSection("editor", "logs");
-      },
-      "logs/:scriptId": function (scriptId) {
-        if (scriptId !== "undefined" && scriptId != viewModel.currentScript().id()) {
-          dashboardLoadedInterval = window.setInterval(function () {
-            if (viewModel.isDashboardLoaded) {
-              window.clearInterval(dashboardLoadedInterval);
-              viewModel.loadScript(scriptId);
-              $(document).trigger("loadEditor");
-              if (viewModel.currentScript().id() == -1) {
-                viewModel.confirmNewScript();
-              }
-              else {
-                viewModel.currentScript().isRunning(true);
-                var _foundLastRun = null;
-                $.each(viewModel.completedScripts(), function (cnt, pastScript) {
-                  if (pastScript.scriptId == scriptId && _foundLastRun == null) {
-                    _foundLastRun = pastScript;
-                  }
-                });
-                viewModel.currentScript().watchUrl(_foundLastRun != null ? _foundLastRun.watchUrl : "");
-                $(document).trigger("startLogsRefresh");
-                showSection("editor", "logs");
-              }
-            }
-          }, 200)
-        }
-        showSection("editor", "logs");
-      }
-    });
-
-    $("#help").popover({
-      'title': "${_('Did you know?')}",
-      'content': $("#help-content").html(),
-      'trigger': 'hover',
-      'html': true
-    });
-
-    $("#parameters-dyk").popover({
-      'title': "${_('Names and values of Pig parameters and options, e.g.')}",
-      'content': $("#parameters-dyk-content").html(),
-      'trigger': 'hover',
-      'html': true
-    });
-
-    $("#properties-dyk").popover({
-      'title': "${_('Names and values of Hadoop properties, e.g.')}",
-      'content': $("#properties-dyk-content").html(),
-      'trigger': 'hover',
-      'html': true
-    });
-
-    $("#resources-dyk").popover({
-      'title': "${_('Include files or compressed files')}",
-      'content': $("#resources-dyk-content").html(),
-      'trigger': 'hover',
-      'html': true
-    });
-  });
-
-  window.onbeforeunload = function (e) {
-    if (viewModel.isDirty()) {
-      var message = "${ _('You have unsaved changes in this pig script.') }";
-
-      if (!e) e = window.event;
-      e.cancelBubble = true;
-      e.returnValue = message;
-
-      if (e.stopPropagation) {
-        e.stopPropagation();
-        e.preventDefault();
-      }
-      return message;
-    }
-  };
-
-  function showAlert(msg) {
-    $(document).trigger("info", msg);
-  }
-</script>
-
-${ commonfooter(messages) | n,unicode }

+ 56 - 0
apps/spark/src/spark/templates/common.mako

@@ -0,0 +1,56 @@
+## Licensed to Cloudera, Inc. under one
+## or more contributor license agreements.  See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership.  Cloudera, Inc. licenses this file
+## to you under the Apache License, Version 2.0 (the
+## "License"); you may not use this file except in compliance
+## with the License.  You may obtain a copy of the License at
+##
+##     http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+
+<%! from django.utils.translation import ugettext as _ %>
+
+<%!
+def is_selected(section, matcher):
+  if section == matcher:
+    return "active"
+  else:
+    return ""
+%>
+
+<%def name="navbar(section='editor')">
+  <div class="navbar navbar-inverse navbar-fixed-top">
+    <div class="navbar-inner">
+      <div class="container-fluid">
+        <div class="nav-collapse">
+          <ul class="nav">
+            <li class="currentApp">
+              <a href="/spark">
+                <img src="/spark/static/art/icon_spark_24.png" />
+                ${ _('Spark Editor') }
+              </a>
+            </li>
+            <li class="${is_selected(section, 'query')}"><a href="${ url('spark:editor') }">${_('Query Editor')}</a></li>
+            ##<li class="${is_selected(section, 'my queries')}"><a href="${ url(app_name + ':my_queries') }">${_('My Queries')}</a></li>
+            <li class="${is_selected(section, 'queries')}"><a href="${ url('spark:list_designs') }">${_('Queries')}</a></li>
+            <li class="${is_selected(section, 'history')}"><a href="${ url('spark:list_query_history') }">${_('History')}</a></li>
+            <li class="currentApp">
+              <a href="/spark">
+                ${ _('Browser') }
+              </a>
+            </li>
+            <li class="${is_selected(section, 'jobs')}"><a href="${ url('spark:list_jobs') }">${_('Jobs')}</a></li>
+            <li class="${is_selected(section, 'contexts')}"><a href="${ url('spark:list_contexts') }">${_('Contexts')}</a></li>
+            <li class="${is_selected(section, 'jars')}"><a href="${ url('spark:list_jars') }">${_('Jars')}</a></li>
+          </ul>
+        </div>
+      </div>
+    </div>
+  </div>
+</%def>

+ 659 - 0
apps/spark/src/spark/templates/editor.mako

@@ -0,0 +1,659 @@
+## Licensed to Cloudera, Inc. under one
+## or more contributor license agreements.  See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership.  Cloudera, Inc. licenses this file
+## to you under the Apache License, Version 2.0 (the
+## "License"); you may not use this file except in compliance
+## with the License.  You may obtain a copy of the License at
+##
+##     http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+<%!
+  from desktop.views import commonheader, commonfooter
+  from django.utils.translation import ugettext as _
+%>
+
+<%namespace name="common" file="common.mako" />
+
+${ commonheader(_('Query'), app_name, user) | n,unicode }
+
+${ common.navbar('editor') }
+
+<div class="container-fluid">
+  <div class="row-fluid">
+    <div class="card card-small">
+      <ul class="nav nav-pills hueBreadcrumbBar" id="breadcrumbs">
+        <li>
+          <div style="display: inline" class="dropdown">
+            ${_('App name')}&nbsp;
+            <!-- ko if: $root.appNames().length == 0 -->
+            <a class="uploadAppModalBtn" href="javascript:void(0);">
+              ${ _("None, create one?") }
+            </a>
+            <!-- /ko -->​
+            <a data-bind="if: $root.appName" data-toggle="dropdown" href="javascript:void(0);">
+              <strong data-bind="text: $root.appName().nice_name"></strong>
+              <i class="fa fa-caret-down"></i>
+            </a>
+            <ul data-bind="foreach: $root.appNames" class="dropdown-menu">
+              <li data-bind="click: $root.chooseAppName, text: nice_name" class="selectable"></li>
+            </ul>
+          </div>
+        </li>
+        <li>&nbsp;&nbsp;&nbsp;&nbsp;</li>
+        <li>
+            ${_('Class path')}&nbsp;
+            <input type="text" data-bind="value: $root.classPath" class="input-xlarge"></input>
+        </li>
+        <li>&nbsp;&nbsp;&nbsp;&nbsp;</li>
+        <li>
+          <div style="display: inline" class="dropdown">
+            ${_('Context')}&nbsp;
+            <input type="checkbox" data-bind="checked: $root.autoContext" />
+            <span data-bind="visible: $root.autoContext()">
+              ${ _('auto') }
+            </span>
+
+            <span data-bind="visible: ! $root.autoContext()">
+              <!-- ko if: $root.contexts().length == 0 -->
+              <a class="createContextModalBtn" href="javascript:void(0);">
+                ${ _("None, create one?") }
+              </a>
+              <!-- /ko -->
+              <a data-bind="if: $root.context" data-toggle="dropdown" href="javascript:void(0);">
+                <strong data-bind="text: $root.context().nice_name"></strong>
+                <i class="fa fa-caret-down"></i>
+              </a>
+              <ul data-bind="foreach: $root.contexts" class="dropdown-menu">
+                <li data-bind="click: $root.chooseContext, text: nice_name" class="selectable"></li>
+              </ul>
+            </span>
+          </div>
+        </li>
+        <span class="pull-right">
+		  <button type="button" class="btn btn-primary uploadAppModalBtn">${ _('Upload app') }</button>
+		  <button type="button" class="btn btn-primary createContextModalBtn">${ _('Create context') }</button>
+        </span>
+      </ul>
+    </div>
+  </div>
+  <div class="row-fluid">
+    <div class="span10">
+    <div id="query">
+      <div class="card card-small">
+        <div style="margin-bottom: 30px">
+          <h1 class="card-heading simple">
+            ${ _('Script Editor') }
+            % if can_edit_name:
+              :
+              <a href="javascript:void(0);"
+                 id="query-name"
+                 data-type="text"
+                 data-name="name"
+                 data-value="${design.name}"
+                 data-original-title="${ _('Query name') }"
+                 data-placement="right">
+              </a>
+            %endif
+          </h1>
+          % if can_edit_name:
+            <p style="margin-left: 20px">
+              <a href="javascript:void(0);"
+                 id="query-description"
+                 data-type="textarea"
+                 data-name="description"
+                 data-value="${design.desc}"
+                 data-original-title="${ _('Query description') }"
+                 data-placement="right">
+              </a>
+            </p>
+          % endif
+        </div>
+        <div class="card-body">
+          <div class="tab-content">
+            <div id="queryPane">
+
+              <div data-bind="css: {'hide': query.errors().length == 0}" class="hide alert alert-error">
+                <p><strong>${_('Your query has the following error(s):')}</strong></p>
+                <div data-bind="foreach: query.errors">
+                  <p data-bind="text: $data" class="queryErrorMessage"></p>
+                </div>
+              </div>
+
+              <textarea class="hide" tabindex="2" name="query" id="queryField"></textarea>
+
+              <div class="actions">
+                <button data-bind="click: tryExecuteQuery" type="button" id="executeQuery" class="btn btn-primary" tabindex="2">${_('Execute')}</button>
+                <button data-bind="click: trySaveQuery, css: {'hide': !$root.query.id() || $root.query.id() == -1}" type="button" class="btn hide">${_('Save')}</button>
+                <button data-bind="click: trySaveAsQuery" type="button" class="btn">${_('Save as...')}</button>
+                <button data-bind="click: tryExplainQuery" type="button" id="explainQuery" class="btn">${_('Explain')}</button>
+                &nbsp; ${_('or create a')} &nbsp;<a type="button" class="btn" href="${ url('spark:editor') }">${_('New query')}</a>
+                <br /><br />
+            </div>
+
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div data-bind="css: {'hide': rows().length == 0}" class="hide">
+      <div class="card card-small scrollable">
+        <table class="table table-striped table-condensed resultTable" cellpadding="0" cellspacing="0" data-tablescroller-min-height-disable="true" data-tablescroller-enforce-height="true">
+          <thead>
+            <tr>
+              <th>${ _('Key') }</th>
+              <th>${ _('Value') }</th>
+            </tr>
+          </thead>
+        </table>
+      </div>
+    </div>
+
+    <div data-bind="css: {'hide': !resultsEmpty()}" class="hide">
+      <div class="card card-small scrollable">
+        <div class="row-fluid">
+          <div class="span10 offset1 center empty-wrapper">
+            <i class="fa fa-frown-o"></i>
+            <h1>${_('The server returned no results.')}</h1>
+            <br />
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+  <div class="span2" id="navigator">
+      <div class="card card-small">
+        <a href="#" title="${_('Double click on a table name or field to insert it in the editor')}" rel="tooltip" data-placement="left" class="pull-right" style="margin:10px;margin-left: 0"><i class="fa fa-question-circle"></i></a>
+        <a id="refreshNavigator" href="#" title="${_('Manually refresh the table list')}" rel="tooltip" data-placement="left" class="pull-right" style="margin:10px"><i class="fa fa-refresh"></i></a>
+        <h1 class="card-heading simple"><i class="fa fa-compass"></i> ${_('History')}</h1>
+        <div class="card-body">
+          <p>
+            <input id="navigatorSearch" type="text" placeholder="${ _('Table name...') }" style="width:90%"/>
+            <span id="navigatorNoTables">${_('The selected database has no tables.')}</span>
+            <ul id="navigatorTables" class="unstyled"></ul>
+          </p>
+        </div>
+      </div>
+  </div>
+
+  </div>
+</div>
+
+
+<div id="saveAsQueryModal" class="modal hide fade">
+  <div class="modal-header">
+    <a href="#" class="close" data-dismiss="modal">&times;</a>
+    <h3>${_('Save your query')}</h3>
+  </div>
+  <div class="modal-body">
+    <form class="form-horizontal">
+      <div class="control-group" id="saveas-query-name">
+        <label class="control-label">${_('Name')}</label>
+        <div class="controls">
+          <input data-bind="value: $root.query.name" type="text" class="input-xlarge">
+        </div>
+      </div>
+      <div class="control-group">
+        <label class="control-label">${_('Description')}</label>
+        <div class="controls">
+          <input data-bind="value: $root.query.description" type="text" class="input-xlarge">
+        </div>
+      </div>
+    </form>
+  </div>
+  <div class="modal-footer">
+    <button class="btn" data-dismiss="modal">${_('Cancel')}</button>
+    <button data-bind="click: modalSaveAsQuery" class="btn btn-primary">${_('Save')}</button>
+  </div>
+</div>
+
+<div id="uploadAppModal" class="modal hide fade">
+  <form class="form-horizontal" id="uploadAppForm" action="${ url('spark:upload_app') }" method="POST" enctype="multipart/form-data">
+  <div class="modal-header">
+    <a href="#" class="close" data-dismiss="modal">&times;</a>
+    <h3>${_('Upload application')}</h3>
+  </div>
+  <div class="modal-body">
+	    ${ _('One class of the jar should implement SparkJob.') }
+	    <div class="control-group">
+	      <label class="control-label">${ _("Local jar file") }</label>
+	      <div class="controls">
+	        <input type="file" name="jar_file" id="jar_file">
+	      </div>
+	    </div>
+        <div class="control-group">
+          <label class="control-label">${ _("App name") }</label>
+          <div class="controls">
+            <input type="text" name="app_name" id="app_name">
+          </div>
+        </div>
+  </div>
+  <div class="modal-footer">
+    <button class="btn" data-dismiss="modal">${_('Cancel')}</button>
+    <input type="submit" class="btn btn-primary" value="${_('Upload')}"/>
+    ##<button data-bind="click: $('#uploadAppForm').submit()" class="btn btn-primary">${_('Upload')}</button>
+  </div>
+  </form>
+</div>
+
+<div id="createContextModal" class="modal hide fade">
+  <div class="modal-header">
+    <a href="#" class="close" data-dismiss="modal">&times;</a>
+    <h3>${_('Create context')}</h3>
+  </div>
+  <div class="modal-body">
+      <form class="form-horizontal" id="createContextForm">
+        <div class="control-group">
+          <label class="control-label">${ _("Name") }</label>
+          <div class="controls">
+            <input type="text" name="name">
+          </div>
+        </div>
+        <div class="control-group">
+          <label class="control-label">${ _("Num cpu cores") }</label>
+          <div class="controls">
+            <input type="text" name="numCores"value="1">
+          </div>
+        </div>
+        <div class="control-group">
+          <label class="control-label">${ _("Memory per node") }</label>
+          <div class="controls">
+            <input type="text" name="memPerNode" value="512m">
+          </div>
+        </div>
+      </form>
+  </div>
+  <div class="modal-footer">
+    <button class="btn" data-dismiss="modal">${_('Cancel')}</button>
+    <button data-bind="click: createContext" class="btn btn-primary">${_('Create')}</button>
+  </div>
+</div>
+
+
+<style type="text/css">
+  h1 {
+    margin-bottom: 5px;
+  }
+
+  #filechooser {
+    min-height: 100px;
+    overflow-y: auto;
+  }
+
+  .control-group {
+    margin-bottom: 3px!important;
+  }
+
+  .control-group label {
+    float: left;
+    padding-top: 5px;
+    text-align: left;
+    width: 40px;
+  }
+
+  .hueBreadcrumb {
+    padding: 12px 14px;
+  }
+
+  .hueBreadcrumbBar {
+    padding: 0;
+    margin: 12px;
+  }
+
+  .hueBreadcrumbBar a {
+    color: #338BB8 !important;
+    display: inline !important;
+  }
+
+  .divider {
+    color: #CCC;
+  }
+
+  .param {
+    padding: 8px 8px 1px 8px;
+    margin-bottom: 5px;
+    border-bottom: 1px solid #EEE;
+  }
+
+  .remove {
+    float: right;
+  }
+
+  .selectable {
+    display: block;
+    list-style: none;
+    padding: 5px;
+    background: white;
+    cursor: pointer;
+  }
+
+  .selected, .selectable:hover {
+    background: #DDDDDD;
+  }
+
+  .CodeMirror {
+    border: 1px solid #eee;
+    margin-bottom: 20px;
+  }
+
+.CodeMirror.cm-s-default {
+   height:150px;
+}
+
+  .editorError {
+    color: #B94A48;
+    background-color: #F2DEDE;
+    padding: 4px;
+    font-size: 11px;
+  }
+
+  .editable-empty, .editable-empty:hover {
+    color: #666;
+    font-style: normal;
+  }
+
+  .tooltip.left {
+    margin-left: -13px;
+  }
+
+  .scrollable {
+    overflow-x: auto;
+  }
+
+  .resultTable td, .resultTable th {
+    white-space: nowrap;
+  }
+
+  .empty-wrapper {
+    margin-top: 50px;
+    color: #BBB;
+    line-height: 60px;
+  }
+
+  .empty-wrapper i {
+    font-size: 148px;
+  }
+
+  #navigatorTables li {
+    width: 95%;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+  }
+
+  #navigatorSearch, #navigatorNoTables {
+    display: none;
+  }
+
+  #navigator .card {
+    padding-bottom: 30px;
+  }
+
+</style>
+
+<script src="/static/ext/js/knockout-min.js" type="text/javascript" charset="utf-8"></script>
+<script src="/static/ext/js/knockout.mapping-2.3.2.js" type="text/javascript" charset="utf-8"></script>
+<script src="/spark/static/js/spark.vm.js"></script>
+<script src="/static/ext/js/codemirror-3.11.js"></script>
+<link rel="stylesheet" href="/static/ext/css/codemirror.css">
+<script src="/static/ext/js/codemirror-sql.js"></script>
+<script src="/static/js/codemirror-sql-hint.js"></script>
+<script src="/static/js/codemirror-show-hint.js"></script>
+
+<link href="/static/ext/css/bootstrap-editable.css" rel="stylesheet">
+<script src="/static/ext/js/bootstrap-editable.min.js"></script>
+<script src="/static/ext/js/bootstrap-editable.min.js"></script>
+
+<script src="/static/ext/js/jquery/plugins/jquery-fieldselection.js" type="text/javascript"></script>
+<script src="/spark/static/js/autocomplete.utils.js" type="text/javascript" charset="utf-8"></script>
+
+<script type="text/javascript" charset="utf-8">
+  var codeMirror, viewModel;
+
+  var spark_AUTOCOMPLETE_BASE_URL = '/spark/api';
+  var spark_AUTOCOMPLETE_FAILS_SILENTLY_ON = [500, 404]; // error codes from spark/views.py - autocomplete
+  var spark_AUTOCOMPLETE_GLOBAL_CALLBACK = $.noop;
+
+  $(document).ready(function(){
+
+    var queryPlaceholder = "${_('Example: SELECT * FROM tablename, or press CTRL + space')}";
+
+    $("*[rel=tooltip]").tooltip({
+      placement: 'bottom'
+    });
+
+    var queryEditor = $("#queryField")[0];
+
+    var selectedLine = -1;
+    var errorWidget = null;
+
+    $("#help").popover({
+      'title': "${_('Did you know?')}",
+      'content': $("#help-content").html(),
+      'trigger': 'hover',
+      'html': true
+    });
+
+  });
+
+  function modal(el) {
+    var el = $(el);
+    return function() {
+      el.modal('show');
+    };
+  }
+
+  function getHighlightedQuery() {
+    var selection = codeMirror.getSelection();
+    if (selection != "") {
+      return selection;
+    }
+    return null;
+  }
+
+  function tryExecuteQuery() {
+    var query = getHighlightedQuery() || codeMirror.getValue();
+    viewModel.query.query(query);
+    viewModel.executeQuery();
+  }
+
+  function tryExplainQuery() {
+    var query = getHighlightedQuery() || codeMirror.getValue();
+    viewModel.query.query(query);
+    viewModel.explainQuery();
+  }
+
+  function trySaveQuery() {
+    var query = getHighlightedQuery() || codeMirror.getValue();
+    viewModel.query.query(query);
+    if (viewModel.query.id() && viewModel.query.id() != -1) {
+      viewModel.saveQuery();
+    }
+  }
+
+  function trySaveAsQuery() {
+    var query = getHighlightedQuery() || codeMirror.getValue();
+    viewModel.query.query(query);
+    $('#saveAsQueryModal').modal('show');
+  }
+
+  $('.uploadAppModalBtn').click(function(){
+    $('#uploadAppModal').modal('show');
+  });
+  $('.createContextModalBtn').click(function(){
+    $('#createContextModal').modal('show');
+  });
+
+  function modalSaveAsQuery() {
+    if (viewModel.query.query() && viewModel.query.name()) {
+      viewModel.query.id(-1);
+      viewModel.saveQuery();
+      $('#saveas-query-name').removeClass('error');
+      $('#saveAsQueryModal').modal('hide');
+    } else if (viewModel.query.name()) {
+      $.jHueNotify.error("${_('No query provided to save.')}");
+      $('#saveAsQueryModal').modal('hide');
+    } else {
+      $('#saveas-query-name').addClass('error');
+    }
+  }
+
+  function checkLastDatabase(server, database) {
+    var key = "huesparkLastDatabase-" + server;
+    if (database != $.totalStorage(key)) {
+      $.totalStorage(key, database);
+    }
+  }
+
+  function getLastDatabase(server) {
+    var key = "huesparkLastDatabase-" + server;
+    return $.totalStorage(key);
+  }
+
+    var queryEditor = $("#queryField")[0];
+
+    var AUTOCOMPLETE_SET = CodeMirror.sqlHint;
+
+  codeMirror = CodeMirror(function (elt) {
+      queryEditor.parentNode.replaceChild(elt, queryEditor);
+    }, {
+      value: queryEditor.value,
+      readOnly: false,
+      lineNumbers: true,
+      mode: "text/x-sql",
+      extraKeys: {
+        "Ctrl-Space": function () {
+          CodeMirror.fromDot = false;
+          codeMirror.execCommand("autocomplete");
+        },
+        Tab: function (cm) {
+          $("#executeQuery").focus();
+        }
+      },
+      onKeyEvent: function (e, s) {
+        if (s.type == "keyup") {
+          if (s.keyCode == 190) {
+            var _line = codeMirror.getLine(codeMirror.getCursor().line);
+            var _partial = _line.substring(0, codeMirror.getCursor().ch);
+            var _table = _partial.substring(_partial.lastIndexOf(" ") + 1, _partial.length - 1);
+            if (codeMirror.getValue().toUpperCase().indexOf("FROM") > -1) {
+              rdbms_getTableColumns(viewModel.server().name(), viewModel.database(), _table, codeMirror.getValue(),
+	              function (columns) {
+	                var _cols = columns.split(" ");
+	                for (var col in _cols) {
+	                  _cols[col] = "." + _cols[col];
+	                }
+	                CodeMirror.catalogFields = _cols.join(" ");
+	                CodeMirror.fromDot = true;
+	                window.setTimeout(function () {
+	                  codeMirror.execCommand("autocomplete");
+	                }, 100);  // timeout for IE8
+	              });
+            }
+          }
+        }
+      }
+    });
+
+
+  // Knockout
+  viewModel = new sparkViewModel();
+  viewModel.fetchAppNames();
+  viewModel.fetchContexts();
+  ko.applyBindings(viewModel);
+
+
+  // Editables
+  $("#query-name").editable({
+    validate: function (value) {
+      if ($.trim(value) == '') {
+        return "${ _('This field is required.') }";
+      }
+    },
+    success: function(response, newValue) {
+      viewModel.query.name(newValue);
+    },
+    emptytext: "${ _('Query name') }"
+  });
+
+  // Events and datatables
+  $(document).on('saved.query', function() {
+    $.jHueNotify.info("${_('Query saved successfully!')}")
+  });
+
+  var dataTable = null;
+  function cleanResultsTable() {
+    if (dataTable) {
+      dataTable.fnClearTable();
+      dataTable.fnDestroy();
+      viewModel.rows.valueHasMutated();
+      dataTable = null;
+    }
+  }
+
+  function addResults(viewModel, dataTable, index, pageSize) {
+    $.each(viewModel.rows.slice(index, index + pageSize), function(row_index, row) {
+      dataTable.fnAddData(row);
+    });
+  }
+
+  function resultsTable() {
+    if (! dataTable) {
+      dataTable = $(".resultTable").dataTable({
+        "bPaginate": false,
+        "bLengthChange": false,
+        "bInfo": false,
+        "oLanguage": {
+          "sEmptyTable": "${_('No data available')}",
+          "sZeroRecords": "${_('No matching records')}"
+        },
+        "fnDrawCallback": function( oSettings ) {
+          $(".resultTable").jHueTableExtender({
+            hintElement: "#jumpToColumnAlert",
+            fixedHeader: true,
+            firstColumnTooltip: true
+          });
+        }
+      });
+      $(".dataTables_filter").hide();
+      $(".dataTables_wrapper").jHueTableScroller();
+
+      // Automatic results grower
+      var dataTableEl = $(".dataTables_wrapper");
+      var index = 0;
+      var pageSize = 100;
+      dataTableEl.on("scroll", function (e) {
+        if (dataTableEl.scrollTop() + dataTableEl.outerHeight() + 20 > dataTableEl[0].scrollHeight && dataTable) {
+          addResults(viewModel, dataTable, index, pageSize);
+          index += pageSize;
+        }
+      });
+      addResults(viewModel, dataTable, index, pageSize);
+      index += pageSize;
+
+      $(".resultTable").width($(".resultTable").parent().width());
+    }
+  }
+  $(document).on('execute.query', cleanResultsTable);
+  $(document).on('executed.query', resultsTable);
+
+  $(document).on('created.context', function() {
+    $('#createContextModal').modal('hide');
+  });
+
+  // Server error handling.
+  $(document).on('server.error', function(e, data) {
+    $(document).trigger('error', "${_('Server error occured: ')}" + data.error);
+  });
+  $(document).on('server.unmanageable_error', function(e, responseText) {
+    $(document).trigger('error', "${_('Unmanageable server error occured: ')}" + responseText);
+  });
+
+</script>
+
+${ commonfooter(messages) | n,unicode }

+ 181 - 0
apps/spark/src/spark/templates/list_contexts.mako

@@ -0,0 +1,181 @@
+## Licensed to Cloudera, Inc. under one
+## or more contributor license agreements.  See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership.  Cloudera, Inc. licenses this file
+## to you under the Apache License, Version 2.0 (the
+## "License"); you may not use this file except in compliance
+## with the License.  You may obtain a copy of the License at
+##
+##     http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+<%!
+  from desktop.views import commonheader, commonfooter
+  from django.utils.translation import ugettext as _
+%>
+
+<%namespace name="common" file="common.mako" />
+
+${ commonheader(_('Context'), app_name, user) | n,unicode }
+
+${ common.navbar('contexts') }
+
+<div class="container-fluid">
+  <div class="card card-small">
+    <h1 class="card-heading simple">${_('Contexts')}</h1>
+
+    <a href="#" id="deleteContextBtn" title="${_('Delete forever')}" class="btn"><i class="fa fa-bolt"></i> ${_('Delete')}</a>
+
+    <table class="table table-condensed datatables">
+    <thead>
+      <th width="1%"><div class="hueCheckbox selectAll fa" data-selectables="savedCheck"></div></th>
+      <th>${ _('Name') }</th>
+    </thead>
+    <tbody>
+      % for contextz in contexts:
+      <tr>
+        <td data-row-selector-exclude="true">
+          <div class="hueCheckbox savedCheck fa" data-delete-name="${ contextz  }" data-row-selector-exclude="true"></div>
+        </td>
+        <td data-name="${ contextz }">${ contextz }</td>
+      </tr>
+      % endfor
+
+    </tbody>
+  </table>
+    <div class="card-body">
+      <p>
+        ## ${ comps.pagination(page) }
+      </p>
+    </div>
+  </div>
+</div>
+
+<div id="deleteContext" class="modal hide fade">
+  <form id="deleteContextForm" action="${ url('spark:delete_contexts') }" method="POST">
+    <input type="hidden" name="skipTrash" id="skipTrash" value="false"/>
+    <div class="modal-header">
+      <a href="#" class="close" data-dismiss="modal">&times;</a>
+      <h3 id="deleteContextMessage">${_('Confirm action')}</h3>
+    </div>
+    <div class="modal-footer">
+      <input type="button" class="btn" data-dismiss="modal" value="${_('Cancel')}" />
+      <input type="submit" class="btn btn-danger" value="${_('Yes')}"/>
+    </div>
+    <div class="hide">
+      <select name="contexts_selection" data-bind="options: availableSavedQueries, selectedOptions: chosenSavedQueries" multiple="true"></select>
+    </div>
+  </form>
+</div>
+
+<script src="/static/ext/js/knockout-min.js" type="text/javascript" charset="utf-8"></script>
+
+<script type="text/javascript" charset="utf-8">
+  $(document).ready(function () {
+    var viewModel = {
+        availableSavedQueries : ko.observableArray(${ contexts_json | n,unicode }),
+        chosenSavedQueries : ko.observableArray([])
+    };
+
+    ko.applyBindings(viewModel);
+
+    var savedQueries = $(".datatables").dataTable({
+      "sDom":"<'row'r>t<'row'<'span8'i><''p>>",
+      "bPaginate":false,
+      "bLengthChange":false,
+      "bInfo":false,
+      "aaSorting":[
+        [2, 'desc']
+      ],
+      "aoColumns":[
+        null,
+        null
+      ],
+      "oLanguage":{
+        "sEmptyTable":"${_('No data available')}",
+        "sZeroRecords":"${_('No matching records')}",
+      },
+      "bStateSave": true
+    });
+
+    $("#filterInput").keyup(function () {
+      savedQueries.fnFilter($(this).val());
+    });
+
+    $("a[data-row-selector='true']").jHueRowSelector();
+
+    $(".selectAll").click(function () {
+      if ($(this).attr("checked")) {
+        $(this).removeAttr("checked").removeClass("fa-check");
+        $("." + $(this).data("selectables")).removeClass("fa-check").removeAttr("checked");
+      }
+      else {
+        $(this).attr("checked", "checked").addClass("fa-check");
+        $("." + $(this).data("selectables")).addClass("fa-check").attr("checked", "checked");
+      }
+      toggleActions();
+    });
+
+    $(".savedCheck").click(function () {
+      if ($(this).attr("checked")) {
+        $(this).removeClass("fa-check").removeAttr("checked");
+      }
+      else {
+        $(this).addClass("fa-check").attr("checked", "checked");
+      }
+      $(".selectAll").removeAttr("checked").removeClass("fa-check");
+      toggleActions();
+    });
+
+    function toggleActions() {
+      $(".toolbarBtn").attr("disabled", "disabled");
+
+      var selector = $(".hueCheckbox[checked='checked']");
+      if (selector.length == 1) {
+        if (selector.data("edit-url")) {
+          $("#editBtn").removeAttr("disabled").click(function () {
+            location.href = selector.data("edit-url");
+          });
+        }
+        if (selector.data("clone-url")) {
+          $("#cloneBtn").removeAttr("disabled").click(function () {
+            location.href = selector.data("clone-url")
+          });
+        }
+        if (selector.data("history-url")) {
+          $("#historyBtn").removeAttr("disabled").click(function () {
+            location.href = selector.data("history-url")
+          });
+        }
+      }
+      if (selector.length >= 1) {
+        $("#trashContextBtn").removeAttr("disabled");
+        $("#trashContextCaretBtn").removeAttr("disabled");
+      }
+    }
+
+    function deleteQueries() {
+      viewModel.chosenSavedQueries.removeAll();
+      $(".hueCheckbox[checked='checked']").each(function( index ) {
+        viewModel.chosenSavedQueries.push($(this).data("delete-name"));
+      });
+
+      $("#deleteContext").modal("show");
+    }
+
+    $("#deleteContextBtn").click(function () {
+      $("#skipTrash").val(true);
+      $("#deleteContextMessage").text("${ _('Delete the selected queries?') }");
+      deleteQueries();
+    });
+
+
+    $("a[data-row-selector='true']").jHueRowSelector();
+  });
+</script>
+
+${ commonfooter(messages) | n,unicode }

+ 114 - 0
apps/spark/src/spark/templates/list_jars.mako

@@ -0,0 +1,114 @@
+## Licensed to Cloudera, Inc. under one
+## or more contributor license agreements.  See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership.  Cloudera, Inc. licenses this file
+## to you under the Apache License, Version 2.0 (the
+## "License"); you may not use this file except in compliance
+## with the License.  You may obtain a copy of the License at
+##
+##     http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+<%!
+  from desktop.views import commonheader, commonfooter
+  from django.utils.translation import ugettext as _
+%>
+
+<%namespace name="common" file="common.mako" />
+
+${ commonheader(_('Query'), app_name, user) | n,unicode }
+
+${ common.navbar('jars') }
+
+<div class="container-fluid">
+  <div class="card card-small">
+    <h1 class="card-heading simple">${_('Jars')}</h1>
+
+    <table class="table table-condensed datatables">
+    <thead>
+      <tr>
+        <th>${_('Name')}</th>
+        <th>${_('Upload time')}</th>
+      </tr>
+    </thead>
+    <tbody>
+      % for name, ts in jars.iteritems():
+      <tr>
+        <td>${ name }</td>
+        <td>${ ts }</td>
+      </tr>
+      % endfor
+
+    </tbody>
+  </table>
+    <div class="card-body">
+      <p>
+        ## ${ comps.pagination(page) }
+      </p>
+    </div>
+  </div>
+</div>
+
+<div id="deleteQuery" class="modal hide fade">
+  <form id="deleteQueryForm" action="${ url(app_name + ':delete_design') }" method="POST">
+    <input type="hidden" name="skipTrash" id="skipTrash" value="false"/>
+    <div class="modal-header">
+      <a href="#" class="close" data-dismiss="modal">&times;</a>
+      <h3 id="deleteQueryMessage">${_('Confirm action')}</h3>
+    </div>
+    <div class="modal-footer">
+      <input type="button" class="btn" data-dismiss="modal" value="${_('Cancel')}" />
+      <input type="submit" class="btn btn-danger" value="${_('Yes')}"/>
+    </div>
+    <div class="hide">
+      <select name="designs_selection" data-bind="options: availableSavedQueries, selectedOptions: chosenSavedQueries" multiple="true"></select>
+    </div>
+  </form>
+</div>
+
+<script src="/static/ext/js/knockout-min.js" type="text/javascript" charset="utf-8"></script>
+
+<script type="text/javascript" charset="utf-8">
+  $(document).ready(function () {
+    var viewModel = {
+        availableSavedQueries : ko.observableArray(${ jars | n,unicode }),
+        chosenSavedQueries : ko.observableArray([])
+    };
+
+    ko.applyBindings(viewModel);
+
+    var savedQueries = $(".datatables").dataTable({
+      "sDom":"<'row'r>t<'row'<'span8'i><''p>>",
+      "bPaginate":false,
+      "bLengthChange":false,
+      "bInfo":false,
+      "aaSorting":[
+        [4, 'desc']
+      ],
+      "aoColumns":[
+        null,
+        null,
+        null,
+        null,
+        { "sSortDataType":"dom-sort-value", "sType":"numeric" }
+      ],
+      "oLanguage":{
+        "sEmptyTable":"${_('No data available')}",
+        "sZeroRecords":"${_('No matching records')}",
+      },
+      "bStateSave": true
+    });
+
+    $("#filterInput").keyup(function () {
+      savedQueries.fnFilter($(this).val());
+    });
+
+    $("a[data-row-selector='true']").jHueRowSelector();
+  });
+</script>
+
+${ commonfooter(messages) | n,unicode }

+ 123 - 0
apps/spark/src/spark/templates/list_jobs.mako

@@ -0,0 +1,123 @@
+## Licensed to Cloudera, Inc. under one
+## or more contributor license agreements.  See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership.  Cloudera, Inc. licenses this file
+## to you under the Apache License, Version 2.0 (the
+## "License"); you may not use this file except in compliance
+## with the License.  You may obtain a copy of the License at
+##
+##     http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+<%!
+  from desktop.views import commonheader, commonfooter
+  from django.utils.translation import ugettext as _
+%>
+
+<%namespace name="common" file="common.mako" />
+
+${ commonheader(_('Query'), app_name, user) | n,unicode }
+
+${ common.navbar('jobs') }
+
+<div class="container-fluid">
+  <div class="card card-small">
+    <h1 class="card-heading simple">${_('Jobs')}</h1>
+
+    <table class="table table-condensed datatables">
+    <thead>
+      <tr>
+        <th>${_('Status')}</th>
+        <th>${_('Job id')}</th>
+        <th>${_('Class path')}</th>
+        <th>${_('Context')}</th>
+        <th>${_('Start time')}</th>
+        <th>${_('Duration')}</th>
+      </tr>
+    </thead>
+    <tbody>
+      % for job in jobs:
+      <tr>
+        <td>${ job.get('status') }</td>
+        <td>${ job.get('jobId') }</td>
+        <td>${ job.get('classPath') }</td>
+        <td>${ job.get('context') }</td>
+        <td>${ job.get('startTime') }</td>
+        <td>${ job.get('duration') }</td>
+      </tr>
+      % endfor
+
+    </tbody>
+  </table>
+    <div class="card-body">
+      <p>
+        ## ${ comps.pagination(page) }
+      </p>
+    </div>
+  </div>
+</div>
+
+<div id="deleteQuery" class="modal hide fade">
+  <form id="deleteQueryForm" action="${ url(app_name + ':delete_design') }" method="POST">
+    <input type="hidden" name="skipTrash" id="skipTrash" value="false"/>
+    <div class="modal-header">
+      <a href="#" class="close" data-dismiss="modal">&times;</a>
+      <h3 id="deleteQueryMessage">${_('Confirm action')}</h3>
+    </div>
+    <div class="modal-footer">
+      <input type="button" class="btn" data-dismiss="modal" value="${_('Cancel')}" />
+      <input type="submit" class="btn btn-danger" value="${_('Yes')}"/>
+    </div>
+    <div class="hide">
+      <select name="designs_selection" data-bind="options: availableSavedQueries, selectedOptions: chosenSavedQueries" multiple="true"></select>
+    </div>
+  </form>
+</div>
+
+<script src="/static/ext/js/knockout-min.js" type="text/javascript" charset="utf-8"></script>
+
+<script type="text/javascript" charset="utf-8">
+  $(document).ready(function () {
+    var viewModel = {
+        availableSavedQueries : ko.observableArray(${ jobs_json | n,unicode }),
+        chosenSavedQueries : ko.observableArray([])
+    };
+
+    ko.applyBindings(viewModel);
+
+    var savedQueries = $(".datatables").dataTable({
+      "sDom":"<'row'r>t<'row'<'span8'i><''p>>",
+      "bPaginate":false,
+      "bLengthChange":false,
+      "bInfo":false,
+      "aaSorting":[
+        [4, 'desc']
+      ],
+      "aoColumns":[
+        null,
+        null,
+        null,
+        null,
+        null,
+        null
+      ],
+      "oLanguage":{
+        "sEmptyTable":"${_('No data available')}",
+        "sZeroRecords":"${_('No matching records')}",
+      },
+      "bStateSave": true
+    });
+
+    $("#filterInput").keyup(function () {
+      savedQueries.fnFilter($(this).val());
+    });
+
+    $("a[data-row-selector='true']").jHueRowSelector();
+  });
+</script>
+
+${ commonfooter(messages) | n,unicode }

+ 0 - 154
apps/spark/src/spark/tests.py

@@ -14,157 +14,3 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-
-
-import json
-import time
-
-from django.contrib.auth.models import User
-from django.core.urlresolvers import reverse
-
-from nose.tools import assert_true, assert_equal
-
-from desktop.lib.django_test_util import make_logged_in_client
-from desktop.lib.test_utils import grant_access
-
-from spark.models import create_or_update_script, SparkScript
-from spark.api import OozieSparkApi, get
-
-
-class TestSparkBase(object):
-  SCRIPT_ATTRS = {
-      'id': 1000,
-      'name': 'Test',
-      'script': 'print "spark"',
-      'parameters': [],
-      'resources': [],
-      'hadoopProperties': [],
-      'language': 'python'
-  }
-
-  def setUp(self):
-    self.c = make_logged_in_client(is_superuser=False)
-    grant_access("test", "test", "spark")
-    self.user = User.objects.get(username='test')
-
-  def create_script(self):
-    return create_script(self.user)
-
-
-def create_script(user, xattrs=None):
-  attrs = {'user': user}
-  attrs.update(TestSparkBase.SCRIPT_ATTRS)
-  if xattrs is not None:
-    attrs.update(xattrs)
-  return create_or_update_script(**attrs)
-
-
-class TestMock(TestSparkBase):
-
-  def test_create_script(self):
-    spark_script = self.create_script()
-    assert_equal('Test', spark_script.dict['name'])
-
-  def test_save(self):
-    attrs = {'user': self.user,}
-    attrs.update(TestSparkBase.SCRIPT_ATTRS)
-    attrs['language'] = json.dumps(TestSparkBase.SCRIPT_ATTRS['language'])
-    attrs['parameters'] = json.dumps(TestSparkBase.SCRIPT_ATTRS['parameters'])
-    attrs['resources'] = json.dumps(TestSparkBase.SCRIPT_ATTRS['resources'])
-    attrs['hadoopProperties'] = json.dumps(TestSparkBase.SCRIPT_ATTRS['hadoopProperties'])
-
-    # Save
-    self.c.post(reverse('spark:save'), data=attrs, follow=True)
-
-    # Update
-    self.c.post(reverse('spark:save'), data=attrs, follow=True)
-
-  def test_parse_oozie_logs(self):
-    api = get(None, None, self.user)
-
-    assert_equal('''Stdoutput aaa''', api._match_logs({'logs': [None, OOZIE_LOGS]}))
-
-
-OOZIE_LOGS ="""  Log Type: stdout
-
-  Log Length: 58465
-
-  Oozie Launcher starts
-
-  Heart beat
-  Starting the execution of prepare actions
-  Completed the execution of prepare actions successfully
-
-  Files in current dir:/var/lib/hadoop-yarn/cache/yarn/nm-local-dir/usercache/romain/appcache/application_1383078934625_0050/container_1383078934625_0050_01_000002/.
-  ======================
-  File: .launch_container.sh.crc
-  File: oozie-sharelib-oozie-3.3.2-cdh4.4.0-SNAPSHOT.jar
-
-  Oozie Java/Map-Reduce/Pig action launcher-job configuration
-  =================================================================
-  Workflow job id   : 0000011-131105103808962-oozie-oozi-W
-  Workflow action id: 0000011-131105103808962-oozie-oozi-W@spark
-
-  Classpath         :
-  ------------------------
-  /var/lib/hadoop-yarn/cache/yarn/nm-local-dir/usercache/romain/appcache/application_1383078934625_0050/container_1383078934625_0050_01_000002
-  /etc/hadoop/conf
-  /usr/lib/hadoop/hadoop-nfs-2.1.0-cdh5.0.0-SNAPSHOT.jar
-  /usr/lib/hadoop/hadoop-common-2.1.0-cdh5.0.0-SNAPSHOT.jar
-  ------------------------
-
-  Main class        : org.apache.oozie.action.hadoop.ShellMain
-
-  Maximum output    : 2048
-
-  Arguments         :
-
-  Java System Properties:
-  ------------------------
-  #
-  #Tue Nov 05 14:02:13 ICT 2013
-  java.runtime.name=Java(TM) SE Runtime Environment
-  oozie.action.externalChildIDs.properties=/var/lib/hadoop-yarn/cache/yarn/nm-local-dir/usercache/romain/appcache/application_1383078934625_0050/container_1383078934625_0050_01_000002/externalChildIds.properties
-  sun.boot.library.path=/usr/lib/jvm/java-7-oracle/jre/lib/amd64
-  ------------------------
-
-  =================================================================
-
-  >>> Invoking Main class now >>>
-
-
-  Oozie Shell action configuration
-  =================================================================
-  Shell configuration:
-  --------------------
-  dfs.datanode.data.dir : file:///var/lib/hadoop-hdfs/cache/${user.name}/dfs/data
-  dfs.namenode.checkpoint.txns : 1000000
-  s3.replication : 3
-  --------------------
-
-  Current working dir /var/lib/hadoop-yarn/cache/yarn/nm-local-dir/usercache/romain/appcache/application_1383078934625_0050/container_1383078934625_0050_01_000002
-  Full Command ..
-  -------------------------
-  0:spark.sh:
-  List of passing environment
-  -------------------------
-  TERM=xterm:
-  JSVC_HOME=/usr/lib/bigtop-utils:
-  HADOOP_PREFIX=/usr/lib/hadoop:
-  HADOOP_MAPRED_HOME=/usr/lib/hadoop-mapreduce:
-  YARN_NICENESS=0:
-  =================================================================
-
-  >>> Invoking Shell command line now >>
-
-  Stdoutput aaa
-  Exit code of the Shell command 0
-  <<< Invocation of Shell command completed <<<
-
-
-  <<< Invocation of Main class completed <<<
-
-
-  Oozie Launcher ends
-
-"""

+ 30 - 12
apps/spark/src/spark/urls.py

@@ -17,19 +17,37 @@
 
 from django.conf.urls.defaults import patterns, url
 
+
+# Views
 urlpatterns = patterns('spark.views',
-  url(r'^$', 'app', name='index'),
+  url(r'^$', 'editor', name='index'),
+  url(r'^editor/(?P<design_id>\d+)?$', 'editor', name='editor'),
+  url(r'^editor/(?P<design_id>\d+)?$', 'editor', name='execute_query'),
+  url(r'^list_jobs', 'list_jobs', name='list_jobs'),
+  url(r'^list_contexts', 'list_contexts', name='list_contexts'),
+  url(r'^delete_contexts', 'delete_contexts', name='delete_contexts'),
+  url(r'^list_jars', 'list_jars', name='list_jars'),
+  url(r'^upload_app$', 'upload_app', name='upload_app'),
+)
+
+# APIs
+urlpatterns += patterns('spark.api',
+  url(r'^api/jars$', 'jars', name='jars'),
+  url(r'^api/execute$', 'execute', name='execute'),
+  url(r'^api/contexts$', 'contexts', name='contexts'),
+  url(r'^api/job/(?P<job_id>.+)$', 'job', name='job'),
+  url(r'^api/create_context$', 'create_context', name='create_context'),
+  url(r'^api/delete_context', 'delete_context', name='delete_context'),
+)
 
-  url(r'^app/$', 'app', name='app'),
+urlpatterns += patterns('beeswax.views',
+  url(r'^save_design_properties$', 'save_design_properties', name='save_design_properties'), # Ajax
 
-  # Ajax
-  url(r'^scripts/$', 'scripts', name='scripts'),
-  url(r'^dashboard/$', 'dashboard', name='dashboard'),
-  url(r'^save/$', 'save', name='save'),
-  url(r'^run/$', 'run', name='run'),
-  url(r'^copy/$', 'copy', name='copy'),
-  url(r'^delete/$', 'delete', name='delete'),
-  url(r'^watch/(?P<job_id>[-\w]+)$', 'watch', name='watch'),
-  url(r'^stop/$', 'stop', name='stop'),
-  url(r'^install_examples$', 'install_examples', name='install_examples'),
+  url(r'^my_queries$', 'my_queries', name='my_queries'),
+  url(r'^list_designs$', 'list_designs', name='list_designs'),
+  url(r'^list_trashed_designs$', 'list_trashed_designs', name='list_trashed_designs'),
+  url(r'^delete_designs$', 'delete_design', name='delete_design'),
+  url(r'^restore_designs$', 'restore_design', name='restore_design'),
+  url(r'^clone_design/(?P<design_id>\d+)$', 'clone_design', name='clone_design'),
+  url(r'^query_history$', 'list_query_history', name='list_query_history')
 )

+ 116 - 184
apps/spark/src/spark/views.py

@@ -18,226 +18,158 @@
 import json
 import logging
 
-from django.core.urlresolvers import reverse
 from django.http import HttpResponse
 from django.utils.translation import ugettext as _
-from django.views.decorators.http import require_http_methods
+from django.core.urlresolvers import reverse
 
-from desktop.lib.django_util import render
-from desktop.lib.exceptions_renderable import PopupException
-from desktop.lib.rest.http_client import RestException
+from desktop.context_processors import get_app_name
 from desktop.models import Document
+from desktop.lib.django_util import render
+from django.shortcuts import redirect
 
-from oozie.views.dashboard import show_oozie_error, check_job_access_permission,\
-                                  check_job_edition_permission
+from beeswax import models as beeswax_models
+from beeswax.views import safe_get_design
 
-from spark import api
-from spark.models import get_workflow_output, hdfs_link, SparkScript,\
-  create_or_update_script, get_scripts
+from spark.design import SparkDesign
+from spark.job_server_api import get_api
+from spark.forms import UploadApp
+from desktop.lib.exceptions import StructuredException
 
 
 LOG = logging.getLogger(__name__)
 
 
-def app(request):
-  return render('app.mako', request, {
-    'autocomplete_base_url': reverse('beeswax:autocomplete', kwargs={}),
-  })
-
-
-def scripts(request):
-  return HttpResponse(json.dumps(get_scripts(request.user, is_design=True)), mimetype="application/json")
-
-
-@show_oozie_error
-def dashboard(request):
-  spark_api = api.get(request.fs, request.jt, request.user)
-
-  jobs = spark_api.get_jobs()
-  hue_jobs = Document.objects.available(SparkScript, request.user)
-  massaged_jobs = spark_api.massaged_jobs_for_json(request, jobs, hue_jobs)
-
-  return HttpResponse(json.dumps(massaged_jobs), mimetype="application/json")
-
-
-def save(request):
-  if request.method != 'POST':
-    raise PopupException(_('POST request required.'))
-
-  attrs = {
-    'id': request.POST.get('id'),
-    'name': request.POST.get('name'),
-    'script': request.POST.get('script'),
-    'user': request.user,
-    'parameters': json.loads(request.POST.get('parameters')),
-    'resources': json.loads(request.POST.get('resources')),
-    'hadoopProperties': json.loads(request.POST.get('hadoopProperties')),
-    'language': json.loads(request.POST.get('language')),
-  }
-  spark_script = create_or_update_script(**attrs)
-  spark_script.is_design = True
-  spark_script.save()
-
-  response = {
-    'id': spark_script.id,
-  }
-
-  return HttpResponse(json.dumps(response), content_type="text/plain")
-
+def editor(request, design_id=None):
+  action = request.path
+  app_name = get_app_name(request)
+  query_type = beeswax_models.SavedQuery.TYPES_MAPPING[app_name]
+  design = safe_get_design(request, query_type, design_id)
 
-@show_oozie_error
-def stop(request):
-  if request.method != 'POST':
-    raise PopupException(_('POST request required.'))
-
-  spark_script = SparkScript.objects.get(id=request.POST.get('id'))
-  job_id = spark_script.dict['job_id']
+  return render('editor.mako', request, {
+    'action': action,
+    'design': design,
+    'can_edit_name': design.id and not design.is_auto,
+  })
 
-  job = check_job_access_permission(request, job_id)
-  check_job_edition_permission(job, request.user)
 
-  try:
-    api.get(request.fs, request.jt, request.user).stop(job_id)
-  except RestException, e:
-    raise PopupException(_("Error stopping Pig script.") % e.message)
+def list_jobs(request):
+  api = get_api(request.user)
+  jobs = api.jobs()
 
-  return watch(request, job_id)
+  return render('list_jobs.mako', request, {
+    'jobs': jobs,
+    'jobs_json': json.dumps(jobs)
+  })
 
 
-@show_oozie_error
-def run(request):
-  if request.method != 'POST':
-    raise PopupException(_('POST request required.'))
-
-  attrs = {
-    'id': request.POST.get('id'),
-    'name': request.POST.get('name'),
-    'script': request.POST.get('script'),
-    'user': request.user,
-    'parameters': json.loads(request.POST.get('parameters')),
-    'resources': json.loads(request.POST.get('resources')),
-    'hadoopProperties': json.loads(request.POST.get('hadoopProperties')),
-    'language': json.loads(request.POST.get('language')),
-    'is_design': False
-  }
+def list_contexts(request):
+  api = get_api(request.user)
+  contexts = api.contexts()
 
-  spark_script = create_or_update_script(**attrs)
-
-  params = request.POST.get('submissionVariables')
-  oozie_id = api.get(request.fs, request.jt, request.user).submit(spark_script, params)
+  return render('list_contexts.mako', request, {
+    'contexts': contexts,
+    'contexts_json': json.dumps(contexts)
+  })
 
-  spark_script.update_from_dict({'job_id': oozie_id})
-  spark_script.save()
 
-  response = {
-    'id': spark_script.id,
-    'watchUrl': reverse('spark:watch', kwargs={'job_id': oozie_id}) + '?format=python'
-  }
+def delete_contexts(request):
+  if request.method == 'POST':
+    api = get_api(request.user)
+    ids = request.POST.getlist('contexts_selection')
+    for name in ids:
+      api.delete_context(name)
+    return redirect(reverse('spark:list_contexts'))
+  else:
+    return render('confirm.mako', request, {'url': request.path, 'title': _('Delete context(s)?')})
 
-  return HttpResponse(json.dumps(response), content_type="text/plain")
 
+def list_jars(request):
+  api = get_api(request.user)
 
-def copy(request):
-  if request.method != 'POST':
-    raise PopupException(_('POST request required.'))
-
-  spark_script = SparkScript.objects.get(id=request.POST.get('id'))
-  spark_script.doc.get().can_edit_or_exception(request.user)
-
-  existing_script_data = spark_script.dict
-
-  owner=request.user
-  name = existing_script_data["name"] + _(' (Copy)')
-  script = existing_script_data["script"]
-  parameters = existing_script_data["parameters"]
-  resources = existing_script_data["resources"]
-  hadoopProperties = existing_script_data["hadoopProperties"]
-  language = existing_script_data["language"]
-
-  script_copy = SparkScript.objects.create()
-  script_copy.update_from_dict({
-      'name': name,
-      'script': script,
-      'parameters': parameters,
-      'resources': resources,
-      'hadoopProperties': hadoopProperties,
-      'language': language
+  return render('list_jars.mako', request, {
+    'jars': api.jars()
   })
-  script_copy.save()
 
-  copy_doc = spark_script.doc.get().copy()
-  script_copy.doc.add(copy_doc)
 
-  response = {
-    'id': script_copy.id,
-    'name': name,
-    'script': script,
-    'parameters': parameters,
-    'resources': resources,
-    'hadoopProperties': hadoopProperties,
-    'language': language
-  }
-
-  return HttpResponse(json.dumps(response), content_type="text/plain")
-
-
-def delete(request):
+def upload_app(request):
   if request.method != 'POST':
-    raise PopupException(_('POST request required.'))
-
-  ids = request.POST.get('ids').split(",")
-
-  for script_id in ids:
-    try:
-      spark_script = SparkScript.objects.get(id=script_id)
-      spark_script.doc.get().can_edit_or_exception(request.user)
-      spark_script.doc.get().delete()
-      spark_script.delete()
-    except:
-      None
-
+    raise StructuredException(code="INVALID_REQUEST_ERROR", message=_('Requires a POST'))
   response = {
-    'ids': ids,
+    'status': -1
   }
 
-  return HttpResponse(json.dumps(response), content_type="text/plain")
-
+  form = UploadApp(request.POST, request.FILES)
 
-@show_oozie_error
-def watch(request, job_id):
-  oozie_workflow = check_job_access_permission(request, job_id)
-  logs, workflow_actions = api.get(request.jt, request.jt, request.user).get_log(request, oozie_workflow)
-  output = get_workflow_output(oozie_workflow, request.fs)
+  if form.is_valid():
+    app_name = form.cleaned_data['app_name']
+    try:
+      data = form.cleaned_data['jar_file'].read()
+      api = get_api(request.user)
+      response['status'] = 0
+      response['results'] = api.upload_jar(app_name, data)
+    except ValueError:
+      # No json is returned
+      pass
+  else:
+    response['results'] = form.errors
 
-  workflow = {
-    'job_id': oozie_workflow.id,
-    'status': oozie_workflow.status,
-    'progress': oozie_workflow.get_progress(),
-    'isRunning': oozie_workflow.is_running(),
-    'killUrl': reverse('oozie:manage_oozie_jobs', kwargs={'job_id': oozie_workflow.id, 'action': 'kill'}),
-    'rerunUrl': reverse('oozie:rerun_oozie_job', kwargs={'job_id': oozie_workflow.id, 'app_path': oozie_workflow.appPath}),
-    'actions': workflow_actions
-  }
+  return redirect(reverse('spark:index'))
 
-  response = {
-    'workflow': workflow,
-    'logs': logs,
-    'output': hdfs_link(output)
-  }
 
-  return HttpResponse(json.dumps(response), content_type="text/plain")
+def save_design(request, save_form, query_form, type_, design, explicit_save=False):
+  """
+  save_design(request, save_form, query_form, type_, design, explicit_save) -> SavedQuery
 
+  A helper method to save the design:
+    * If ``explicit_save``, then we save the data in the current design.
+    * If the user clicked the submit button, we do NOT overwrite the current
+      design. Instead, we create a new "auto" design (iff the user modified
+      the data). This new design is named after the current design, with the
+      AUTO_DESIGN_SUFFIX to signify that it's different.
 
-def install_examples(request):
-  result = {'status': -1, 'message': ''}
+  Need to return a SavedQuery because we may end up with a different one.
+  Assumes that form.saveform is the SaveForm, and that it is valid.
+  """
 
-  if request.method != 'POST':
-    result['message'] = _('A POST request is required.')
+  if type_ == beeswax_models.SPARK:
+    design_cls = SparkDesign
   else:
-    try:
-      result['status'] = 0
-    except Exception, e:
-      LOG.exception(e)
-      result['message'] = str(e)
+    raise ValueError(_('Invalid design type %(type)s') % {'type': type_})
+
+  old_design = design
+  design_obj = design_cls(query_form)
+  new_data = design_obj.dumps()
+
+  # Auto save if (1) the user didn't click "save", and (2) the data is different.
+  # Don't generate an auto-saved design if the user didn't change anything
+  if explicit_save:
+    design.name = save_form.cleaned_data['name']
+    design.desc = save_form.cleaned_data['desc']
+    design.is_auto = False
+  elif new_data != old_design.data:
+    # Auto save iff the data is different
+    if old_design.id is not None:
+      # Clone iff the parent design isn't a new unsaved model
+      design = old_design.clone()
+      if not old_design.is_auto:
+        design.name = old_design.name + beeswax_models.SavedQuery.AUTO_DESIGN_SUFFIX
+    else:
+      design.name = beeswax_models.SavedQuery.DEFAULT_NEW_DESIGN_NAME
+    design.is_auto = True
+
+  design.type = type_
+  design.data = new_data
+
+  design.save()
+
+  LOG.info('Saved %s design "%s" (id %s) for %s' % (design.name and '' or 'auto ', design.name, design.id, design.owner))
+
+  if design.doc.exists():
+    design.doc.update(name=design.name, description=design.desc)
+  else:
+    Document.objects.link(design, owner=design.owner, extra=design.type, name=design.name, description=design.desc)
+
+  if design.is_auto:
+    design.doc.get().add_to_history()
 
-  return HttpResponse(json.dumps(result), mimetype="application/json")
+  return design

+ 0 - 148
apps/spark/static/css/spark.css

@@ -1,148 +0,0 @@
-/*
- Licensed to Cloudera, Inc. under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  Cloudera, Inc. licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-.running {
-  background-color: #faa732;
-  border-left: 2px solid #faa732;
-}
-
-.succeeded {
-  background-color: #5eb95e;
-  border-left: 2px solid #5eb95e;
-}
-
-.failed {
-  background-color: #dd514c;
-  border-left: 2px solid #dd514c;
-}
-
-.sidebar-nav {
-  padding: 9px 0;
-}
-
-.CodeMirror {
-  border: 1px solid #eee;
-}
-
-.bottomAlert {
-  position: fixed;
-  bottom: 0;
-  left: 0;
-  margin: 0;
-  width: 100%;
-  text-align: center;
-  display: none;
-  z-index: 1000;
-}
-
-#logs .alert-modified {
-  padding-right: 14px;
-}
-
-#logs pre {
-  margin: 0;
-  color: #666;
-  border-color: #DDD;
-}
-
-.parameterTableCnt {
-  background-color: #F5F5F5;
-}
-
-.parameterTable td {
-  padding: 7px;
-}
-
-.span2 .pull-right {
-  display: none;
-}
-
-#logsModal {
-  width: 90%;
-  left: 5%;
-  margin-left: auto;
-  margin-right: auto;
-}
-
-.scroll {
-  overflow-y: scroll;
-  height: 300px;
-}
-
-.widget-content {
-  padding: 10px;
-}
-
-.editable {
-  cursor: pointer;
-}
-
-.editable-container h3 {
-  display: none;
-}
-
-#properties h4 {
-  color: #3A87AD;
-}
-
-.mainAction {
-  float: right;
-  font-size: 48px;
-  opacity: 0.4;
-  color: #338bb8;
-  cursor: pointer;
-  margin-top: 6px;
-}
-
-.mainAction i {
-  cursor: pointer;
-}
-
-.mainAction:hover {
-  opacity: 0.88;
-  text-decoration: none;
-}
-
-.unsaved {
-  border-color: #C63D37!important;
-}
-
-.editorError {
-  color: #B94A48;
-  background-color: #F2DEDE;
-  padding: 4px;
-  font-size: 11px;
-}
-
-#navigatorFunctions li {
-  width: 95%;
-  white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
-}
-
-.navigatorFunctionCategoryContent li {
-  padding-left: 8px;
-}
-
-.navigatorFunctionCategory {
-  font-weight: bold;
-}
-.tooltip.left {
-  margin-left: -13px;
-}

BIN
apps/spark/static/help/images/23888161.png


+ 3 - 121
apps/spark/static/help/index.html

@@ -5,132 +5,14 @@
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 <link rel="stylesheet" type="text/css" href="commonltr.css"/>
-<title>Pig Editor</title>
+<title>Spark</title>
 </head>
-<body id="xd_583c10bfdbd326ba-3ca24a24-13d80143249--7f9c"><a name="xd_583c10bfdbd326ba-3ca24a24-13d80143249--7f9c"><!-- --></a>
+<body id="topic_4"><a name="topic_4"><!-- --></a>
 
 
-  <h1 class="title topictitle1">Pig Editor</h1>
 
+  <h1 class="title topictitle1">Spark</h1>
 
-  <div class="body conbody">
-    <p class="p">The Pig Editor application allows you to define Pig scripts, run scripts,
-      and view the status of jobs. For information about Pig, see <a class="xref" href="http://archive.cloudera.com/cdh5/cdh/5/pig/" target="_blank">Pig Documentation</a>. </p>
-
-  </div>
-
-  <div class="topic concept nested1" id="concept_u25_g2v_yj"><a name="concept_u25_g2v_yj"><!-- --></a>
-    <h2 class="title topictitle2">Pig Editor Installation and Configuration </h2>
-
-    <div class="body conbody">
-      <p class="p">Pig Editor is one of the applications installed as part of Hue.
-
-    </div>
-
-  </div>
-
-  <div class="topic concept nested1" id="concept_e2q_xn5_wj"><a name="concept_e2q_xn5_wj"><!-- --></a>
-    <h2 class="title topictitle2">Starting Pig Editor</h2>
-
-    <div class="body conbody">
-      <div class="p">Click the <strong class="ph b">Pig Editor</strong> icon (<a name="concept_e2q_xn5_wj__image_fgk_4n5_wj"><!-- --></a><img class="image" id="concept_e2q_xn5_wj__image_fgk_4n5_wj" src="/pig/static/art/icon_pig_24.png"/>) in the navigation bar at the top of the Hue
-        browser page. The Pig Editor opens with three tabs:<a name="concept_e2q_xn5_wj__ul_itr_clx_2k"><!-- --></a><ul class="ul" id="concept_e2q_xn5_wj__ul_itr_clx_2k">
-          <li class="li">Editor - editor where you can create, edit, run, save, copy, and
-            delete scripts and edit script properties.</li>
-
-          <li class="li">Scripts - script manager where you can create, open, run, copy,
-            and delete scripts. </li>
-
-          <li class="li">Dashboard - dashboard where you can view running and completed
-            scripts and view the log of a job. </li>
-
-        </ul>
-</div>
-
-    </div>
-
-  </div>
-
-  <div class="topic concept nested1" id="concept_lng_kjt_yj"><a name="concept_lng_kjt_yj"><!-- --></a>
-    <h2 class="title topictitle2">Installing the Sample Pig Scripts </h2>
-
-    <div class="body conbody">
-      <div class="note note"><span class="notetitle"><img src="/static/art/help/note.jpg"/> 
-      <b>Note</b>:</span> You must be a superuser to perform this task.</div>
-
-      <a name="concept_lng_kjt_yj__ol_zys_pjt_yj"><!-- --></a><ol class="ol" id="concept_lng_kjt_yj__ol_zys_pjt_yj">
-        <li class="li">Click <a name="concept_lng_kjt_yj__d45e102"><!-- --></a><img class="image" id="concept_lng_kjt_yj__d45e102" src="/static/art/hue-logo-mini.png"/>. The Quick Start Wizard opens.</li>
-<li class="li">Click <strong class="ph b">Step 2:
-            Examples</strong>.</li>
-
-        <li class="li">Click <strong class="ph b">Pig Editor</strong>.</li>
-
-      </ol>
-
-    </div>
-
-    <div class="topic concept nested2" id="concept_b5z_23x_2k"><a name="concept_b5z_23x_2k"><!-- --></a>
-      <h3 class="title topictitle3">Scripts</h3>
-
-      <div class="body conbody">
-        <div class="section" id="concept_b5z_23x_2k__section_s35_5lx_2k"><a name="concept_b5z_23x_2k__section_s35_5lx_2k"><!-- --></a><h4 class="title sectiontitle">Creating a Script</h4>
-
-          <a name="concept_b5z_23x_2k__ol_mwq_z2y_2k"><!-- --></a><ol class="ol" id="concept_b5z_23x_2k__ol_mwq_z2y_2k">
-            <li class="li">In either the Editor or Scripts screen, click <span class="ph uicontrol">New
-                script</span>. Edit the script as desired.</li>
-
-            <li class="li">Click <span class="ph uicontrol">Edit
-              Properties</span>. In the Script name field, type a name for the script.</li>
-
-            <li class="li">Click <span class="ph uicontrol">Save</span>.</li>
-
-          </ol>
-
-        </div>
-
-        <div class="section" id="concept_b5z_23x_2k__section_tvv_5lx_2k"><a name="concept_b5z_23x_2k__section_tvv_5lx_2k"><!-- --></a><h4 class="title sectiontitle">Opening a Script</h4>
-
-          <a name="concept_b5z_23x_2k__ol_nvn_2fy_2k"><!-- --></a><ol class="ol" id="concept_b5z_23x_2k__ol_nvn_2fy_2k">
-            <li class="li">Click the <span class="ph uicontrol">Scripts</span> tab.</li>
-
-            <li class="li">In the list of scripts, click a script.</li>
-
-          </ol>
-
-        </div>
-
-        <div class="section" id="concept_b5z_23x_2k__section_gjr_rfy_2k"><a name="concept_b5z_23x_2k__section_gjr_rfy_2k"><!-- --></a><h4 class="title sectiontitle">Running a Script</h4>
-
-          <a name="concept_b5z_23x_2k__ol_r2q_sfy_2k"><!-- --></a><ol class="ol" id="concept_b5z_23x_2k__ol_r2q_sfy_2k">
-            <li class="li">Do one of the following:<a name="concept_b5z_23x_2k__ul_gj2_5fy_2k"><!-- --></a><ul class="ul" id="concept_b5z_23x_2k__ul_gj2_5fy_2k">
-                <li class="li">In the Editor screen, click the <span class="ph uicontrol">Run</span> button.</li>
-
-                <li class="li">In the Scripts screen,  check the checkbox next to a script and click the
-                    <span class="ph uicontrol">Run</span> button.</li>
-
-              </ul>
-</li>
-
-          </ol>
-
-        </div>
-
-        <div class="section" id="concept_b5z_23x_2k__section_kf2_zfy_2k"><a name="concept_b5z_23x_2k__section_kf2_zfy_2k"><!-- --></a><h4 class="title sectiontitle">Viewing the Result of Running a Script</h4>
-
-          <a name="concept_b5z_23x_2k__ol_jvm_2gy_2k"><!-- --></a><ol class="ol" id="concept_b5z_23x_2k__ol_jvm_2gy_2k">
-            <li class="li">Click the <span class="ph uicontrol">Dashboard</span> tab.</li>
-
-            <li class="li">Click a job.</li>
-
-          </ol>
-
-        </div>
-
-      </div>
-
-    </div>
-
-  </div>
 
 
 </body>

+ 181 - 0
apps/spark/static/js/autocomplete.utils.js

@@ -0,0 +1,181 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+function spark_jsoncalls(options) {
+  if (typeof spark_AUTOCOMPLETE_BASE_URL != "undefined") {
+    if (options.database === null) {
+      $.getJSON(spark_AUTOCOMPLETE_BASE_URL, options.onDataReceived);
+    }
+    if (options.database) {
+      if (options.table) {
+        $.getJSON(spark_AUTOCOMPLETE_BASE_URL + "/servers/" + options.server + "/databases/" + options.database + "/tables/" + options.table + "/columns", options.onDataReceived);
+      }
+      else {
+        $.getJSON(spark_AUTOCOMPLETE_BASE_URL + "/servers/" + options.server + "/databases/" + options.database + "/tables", options.onDataReceived);
+      }
+    }
+  }
+  else {
+    try {
+      console.error("You need to specify a spark_AUTOCOMPLETE_BASE_URL to use the autocomplete");
+    }
+    catch (e) {
+    }
+  }
+}
+
+function spark_hasExpired(timestamp){
+  var TIME_TO_LIVE_IN_MILLIS = 600000; // 10 minutes
+  return (new Date()).getTime() - timestamp > TIME_TO_LIVE_IN_MILLIS;
+}
+
+function spark_getTableAliases(textScanned) {
+  var _aliases = {};
+  var _val = textScanned; //codeMirror.getValue();
+  var _from = _val.toUpperCase().indexOf("FROM ");
+  if (_from > -1) {
+    var _match = _val.toUpperCase().substring(_from).match(/ON|WHERE|GROUP|SORT|ORDER/);
+    var _to = _val.length;
+    if (_match) {
+      _to = _match.index;
+    }
+    var _found = _val.substr(_from, _to).replace(/(\r\n|\n|\r)/gm, "").replace(/from/gi, "").replace(/join/gi, ",").split(",");
+    for (var i = 0; i < _found.length; i++) {
+      var _tablealias = $.trim(_found[i]).split(" ");
+      if (_tablealias.length > 1) {
+        _aliases[_tablealias[1]] = _tablealias[0];
+      }
+    }
+  }
+  return _aliases;
+}
+
+function spark_tableHasAlias(tableName, textScanned) {
+  var _aliases = spark_getTableAliases(textScanned);
+  for (var alias in _aliases) {
+    if (_aliases[alias] == tableName) {
+      return true;
+    }
+  }
+  return false;
+}
+
+function spark_getTableColumns(serverName, databaseName, tableName, textScanned, callback) {
+  if (tableName.indexOf("(") > -1) {
+    tableName = tableName.substr(tableName.indexOf("(") + 1);
+  }
+
+  var _aliases = spark_getTableAliases(textScanned);
+  if (_aliases[tableName]) {
+    tableName = _aliases[tableName];
+  }
+
+  if ($.totalStorage('spark_columns_' + serverName + '_' + databaseName + '_' + tableName) && $.totalStorage('spark_extended_columns_' + serverName + '_' + databaseName + '_' + tableName)) {
+    callback($.totalStorage('spark_columns_' + serverName + '_' + databaseName + '_' + tableName), $.totalStorage('spark_extended_columns_' + serverName + '_' + databaseName + '_' + tableName));
+    if ($.totalStorage('spark_timestamp_columns_' + serverName + '_' + databaseName + '_' + tableName) === null || spark_hasExpired($.totalStorage('spark_timestamp_columns_' + serverName + '_' + databaseName + '_' + tableName))){
+      spark_jsoncalls({
+        server: serverName,
+        database: databaseName,
+        table: tableName,
+        onDataReceived: function (data) {
+          if (typeof spark_AUTOCOMPLETE_GLOBAL_CALLBACK == "function") {
+            spark_AUTOCOMPLETE_GLOBAL_CALLBACK(data);
+          }
+          if (data.error) {
+            if (typeof spark_AUTOCOMPLETE_FAILS_SILENTLY_ON == "undefined" || data.code === null || spark_AUTOCOMPLETE_FAILS_SILENTLY_ON.indexOf(data.code) == -1){
+              $(document).trigger('error', data.error);
+            }
+          }
+          else {
+            $.totalStorage('spark_columns_' + serverName + '_' + databaseName + '_' + tableName, (data.columns ? "* " + data.columns.join(" ") : "*"));
+            $.totalStorage('spark_extended_columns_' + serverName + '_' + databaseName + '_' + tableName, (data.extended_columns ? data.extended_columns : []));
+            $.totalStorage('spark_timestamp_columns_' + serverName + '_' + databaseName + '_' + tableName, (new Date()).getTime());
+          }
+        }
+      });
+    }
+  }
+  else {
+    spark_jsoncalls({
+      server: serverName,
+      database: databaseName,
+      table: tableName,
+      onDataReceived: function (data) {
+        if (typeof spark_AUTOCOMPLETE_GLOBAL_CALLBACK == "function") {
+          spark_AUTOCOMPLETE_GLOBAL_CALLBACK(data);
+        }
+        if (data.error) {
+          if (typeof spark_AUTOCOMPLETE_FAILS_SILENTLY_ON == "undefined" || data.code === null || spark_AUTOCOMPLETE_FAILS_SILENTLY_ON.indexOf(data.code) == -1){
+            $(document).trigger('error', data.error);
+          }
+        }
+        else {
+          $.totalStorage('spark_columns_' + serverName + '_' + databaseName + '_' + tableName, (data.columns ? "* " + data.columns.join(" ") : "*"));
+          $.totalStorage('spark_extended_columns_' + serverName + '_' + databaseName + '_' + tableName, (data.extended_columns ? data.extended_columns : []));
+          $.totalStorage('spark_timestamp_columns_' + serverName + '_' + databaseName + '_' + tableName, (new Date()).getTime());
+          callback($.totalStorage('spark_columns_' + serverName + '_' + databaseName + '_' + tableName), $.totalStorage('spark_extended_columns_' + serverName + '_' + databaseName + '_' + tableName));
+        }
+      }
+    });
+  }
+}
+
+function spark_getTables(serverName, databaseName, callback) {
+  if ($.totalStorage('spark_tables_' + serverName + '_' + databaseName)) {
+    callback($.totalStorage('spark_tables_' + serverName + '_' + databaseName));
+    if ($.totalStorage('spark_timestamp_tables_' + serverName + '_' + databaseName) === null || spark_hasExpired($.totalStorage('spark_timestamp_tables_' + serverName + '_' + databaseName))){
+      spark_jsoncalls({
+        server: serverName,
+        database: databaseName,
+        onDataReceived: function (data) {
+          if (typeof spark_AUTOCOMPLETE_GLOBAL_CALLBACK == "function") {
+            spark_AUTOCOMPLETE_GLOBAL_CALLBACK(data);
+          }
+          if (data.error) {
+            if (typeof spark_AUTOCOMPLETE_FAILS_SILENTLY_ON == "undefined" || data.code === null || spark_AUTOCOMPLETE_FAILS_SILENTLY_ON.indexOf(data.code) == -1){
+              $(document).trigger('error', data.error);
+            }
+          }
+          else {
+            $.totalStorage('spark_tables_' + serverName + '_' + databaseName, data.tables.join(" "));
+            $.totalStorage('spark_timestamp_tables_' + serverName + '_' + databaseName, (new Date()).getTime());
+          }
+        }
+      });
+    }
+  }
+  else {
+    spark_jsoncalls({
+      server: serverName,
+      database: databaseName,
+      onDataReceived: function (data) {
+        if (typeof spark_AUTOCOMPLETE_GLOBAL_CALLBACK == "function") {
+          spark_AUTOCOMPLETE_GLOBAL_CALLBACK(data);
+        }
+        if (data.error) {
+          if (typeof spark_AUTOCOMPLETE_FAILS_SILENTLY_ON == "undefined" || data.code === null || spark_AUTOCOMPLETE_FAILS_SILENTLY_ON.indexOf(data.code) == -1){
+            $(document).trigger('error', data.error);
+          }
+        }
+        else {
+          $.totalStorage('spark_tables_' + serverName + '_' + databaseName, data.tables.join(" "));
+          $.totalStorage('spark_timestamp_tables_' + serverName + '_' + databaseName, (new Date()).getTime());
+          callback($.totalStorage('spark_tables_' + serverName + '_' + databaseName));
+        }
+      }
+    });
+  }
+}

+ 0 - 606
apps/spark/static/js/spark.ko.js

@@ -1,606 +0,0 @@
-// Licensed to Cloudera, Inc. under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  Cloudera, Inc. licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-var Resource = function (resource) {
-  var self = this;
-
-  self.type = ko.observable(resource.type);
-  self.value = ko.observable(resource.value);
-};
-
-var HadoopProperty = function (property) {
-  var self = this;
-
-  self.name = ko.observable(property.name);
-  self.value = ko.observable(property.value);
-};
-
-var PigParameter = HadoopProperty;
-
-
-var SparkScript = function (sparkScript) {
-  var self = this;
-
-  self.id = ko.observable(sparkScript.id);
-  self.isDesign = ko.observable(sparkScript.isDesign);
-  self.name = ko.observable(sparkScript.name);
-  self.language = ko.observable(sparkScript.language);
-  self.script = ko.observable(sparkScript.script);
-  self.scriptSumup = ko.observable(sparkScript.script.replace(/\W+/g, ' ').substring(0, 100));
-  self.isRunning = ko.observable(false);
-  self.selected = ko.observable(false);
-  self.watchUrl = ko.observable("");
-  self.actions = ko.observableArray([]);
-
-  self.handleSelect = function (row, e) {
-    this.selected(!this.selected());
-  };
-  self.hovered = ko.observable(false);
-  self.toggleHover = function (row, e) {
-    this.hovered(!this.hovered());
-  };
-
-  self.parameters = ko.observableArray([]);
-  ko.utils.arrayForEach(sparkScript.parameters, function (parameter) {
-    self.parameters.push(new PigParameter({name: parameter.name, value: parameter.value}));
-  });
-  self.addParameter = function () {
-    self.parameters.push(new PigParameter({name: '', value: ''}));
-    self.updateParentModel();
-  };
-  self.removeParameter = function () {
-    self.parameters.remove(this);
-    self.updateParentModel();
-  };
-  self.getParameters = function () {
-    var params = {};
-    return params;
-  };
-
-  self.hadoopProperties = ko.observableArray([]);
-  ko.utils.arrayForEach(sparkScript.hadoopProperties, function (property) {
-    self.hadoopProperties.push(new HadoopProperty({name: property.name, value: property.value}));
-  });
-  self.addHadoopProperties = function () {
-    self.hadoopProperties.push(new HadoopProperty({name: '', value: ''}));
-    self.updateParentModel();
-  };
-  self.removeHadoopProperties = function () {
-    self.hadoopProperties.remove(this);
-    self.updateParentModel();
-  };
-
-  self.resources = ko.observableArray([]);
-  ko.utils.arrayForEach(sparkScript.resources, function (resource) {
-    self.resources.push(new Resource({type: resource.type, value: resource.value}));
-  });
-  self.addResource = function () {
-    self.resources.push(new Resource({type: 'file', value: ''}));
-    self.updateParentModel();
-  };
-  self.removeResource = function () {
-    self.resources.remove(this);
-    self.updateParentModel();
-  };
-
-  self.parentModel = sparkScript.parentModel;
-  self.updateParentModel = function () {
-    if (typeof self.parentModel != "undefined" && self.parentModel != null) {
-      self.parentModel.isDirty(true);
-    }
-  }
-
-  self.name.subscribe(function (name) {
-    self.updateParentModel();
-  });
-
-  self.language.subscribe(function (lang) {
-    if (typeof codeMirror != "undefined"){
-      codeMirror.setOption("mode", "text/x-" + lang);
-    }
-  });
-}
-
-var Workflow = function (wf) {
-  return {
-    id: wf.id,
-    scriptId: wf.scriptId,
-    scriptContent: wf.scriptContent,
-    lastModTime: wf.lastModTime,
-    endTime: wf.endTime,
-    status: wf.status,
-    statusClass: "label " + getStatusClass(wf.status),
-    isRunning: wf.isRunning,
-    duration: wf.duration,
-    appName: wf.appName,
-    progress: wf.progress,
-    progressPercent: wf.progressPercent,
-    progressClass: "bar " + getStatusClass(wf.status, "bar-"),
-    user: wf.user,
-    absoluteUrl: wf.absoluteUrl,
-    watchUrl: wf.watchUrl,
-    canEdit: wf.canEdit,
-    killUrl: wf.killUrl,
-    created: wf.created,
-    run: wf.run
-  }
-}
-
-
-var SparkViewModel = function (props) {
-  var self = this;
-
-  self.LABELS = props.labels;
-
-  self.LIST_SCRIPTS = props.listScripts;
-  self.SAVE_URL = props.saveUrl;
-  self.RUN_URL = props.runUrl;
-  self.STOP_URL = props.stopUrl;
-  self.COPY_URL = props.copyUrl;
-  self.DELETE_URL = props.deleteUrl;
-
-  self.isLoading = ko.observable(false);
-  self.allSelected = ko.observable(false);
-  self.submissionVariables = ko.observableArray([]);
-
-  self.scripts = ko.observableArray([]);
-
-  self.filteredScripts = ko.observableArray(self.scripts());
-
-  self.runningScripts = ko.observableArray([]);
-  self.completedScripts = ko.observableArray([]);
-
-  self.isDashboardLoaded = false;
-  self.isDirty = ko.observable(false);
-
-  var _defaultScript = {
-    id: -1,
-    name: self.LABELS.NEW_SCRIPT_NAME,
-    language: 'python',
-    script: self.LABELS.NEW_SCRIPT_CONTENT['python'],
-    parameters: self.LABELS.NEW_SCRIPT_PARAMETERS,
-    resources: self.LABELS.NEW_SCRIPT_RESOURCES,
-    hadoopProperties: self.LABELS.NEW_SCRIPT_HADOOP_PROPERTIES,
-    parentModel: self
-  };
-
-  self.currentScript = ko.observable(new SparkScript(_defaultScript));
-  self.loadingScript = null;
-  self.currentDeleteType = ko.observable("");
-
-  self.selectedScripts = ko.computed(function () {
-    return ko.utils.arrayFilter(self.scripts(), function (script) {
-      return script.selected();
-    });
-  }, self);
-
-  self.selectedScript = ko.computed(function () {
-    return self.selectedScripts()[0];
-  }, self);
-
-  self.selectAll = function () {
-    self.allSelected(! self.allSelected());
-    ko.utils.arrayForEach(self.scripts(), function (script) {
-      script.selected(self.allSelected());
-    });
-    return true;
-  };
-
-  self.getScriptById = function (id) {
-    var _s = null;
-    ko.utils.arrayForEach(self.scripts(), function (script) {
-      if (script.id() == id) {
-        _s = script;
-      }
-    });
-    return _s;
-  }
-
-  self.filterScripts = function (filter) {
-    self.filteredScripts(ko.utils.arrayFilter(self.scripts(), function (script) {
-      return script.isDesign() && script.name().toLowerCase().indexOf(filter.toLowerCase()) > -1
-    }));
-  };
-
-  self.loadScript = function (id) {
-    var _s = self.getScriptById(id);
-    if (_s != null) {
-      self.currentScript(_s);
-    }
-    else {
-      self.currentScript(new SparkScript(_defaultScript));
-    }
-  }
-
-  self.confirmNewScript = function () {
-    if (self.isDirty()) {
-      showConfirmModal();
-    }
-    else {
-      self.newScript();
-    }
-  };
-
-  self.confirmScript = function () {
-    if (self.loadingScript != null){
-      self.viewScript(self.loadingScript);
-    }
-    else {
-      self.newScript();
-    }
-  };
-
-  self.newScript = function () {
-    self.loadingScript = null;
-    self.currentScript(new SparkScript(_defaultScript));
-    self.isDirty(false);
-    $("#confirmModal").modal("hide");
-    $("#newScriptModal").modal("show");
-    $(document).trigger("loadEditor");
-    $(document).trigger("showEditor");
-    $(document).trigger("clearLogs");
-  };
-
-  self.createAndEditScript = function () {
-	self.currentScript().script(LABELS.NEW_SCRIPT_CONTENT[self.currentScript().language()]);
-	$(document).trigger("loadEditor");
-	$("#newScriptModal").modal("hide");
-	$(document).trigger("showEditor");
-  };
-
-  self.editScript = function (script) {
-    $(document).trigger("showEditor");
-  };
-
-  self.editScriptProperties = function (script) {
-    $(document).trigger("showProperties");
-  };
-
-  self.showScriptLogs = function (script) {
-    $(document).trigger("showLogs");
-  };
-
-  self.confirmViewScript = function (script) {
-    if (self.isDirty()) {
-      self.loadingScript = script;
-      showConfirmModal();
-    }
-    else {
-      self.viewScript(script);
-    }
-  };
-
-  self.viewScript = function (script) {
-    self.loadingScript = null;
-    self.currentScript(script);
-    self.isDirty(false);
-    $("#confirmModal").modal("hide");
-    $(document).trigger("loadEditor");
-    $(document).trigger("showEditor");
-  };
-
-  self.saveScript = function () {
-    if (self.LABELS.NEW_SCRIPT_NAME == self.currentScript().name()){
-      showNameModal();
-    }
-    else {
-      $("#nameModal").modal("hide");
-      callSave(self.currentScript());
-      self.isDirty(false);
-    }
-  };
-
-  self.runScript = function () {
-    callRun(self.currentScript());
-  };
-
-  self.copyScript = function () {
-    callCopy(self.currentScript());
-    viewModel.isDirty(true);
-  };
-
-  self.confirmDeleteScript = function () {
-    self.currentDeleteType("single");
-    showDeleteModal();
-  };
-
-  self.stopScript = function () {
-    callStop(self.currentScript());
-  };
-
-  self.listRunScript = function () {
-    self.currentScript(self.selectedScript());
-    self.runOrShowSubmissionModal();
-  };
-
-  self.listCopyScript = function () {
-    callCopy(self.selectedScript());
-  };
-
-  self.listConfirmDeleteScripts = function () {
-    self.currentDeleteType("multiple");
-    showDeleteModal();
-  };
-
-  self.deleteScripts = function () {
-    var ids = [];
-    if (self.currentDeleteType() == "single") {
-      ids.push(self.currentScript().id());
-    }
-    if (self.currentDeleteType() == "multiple") {
-      $(self.selectedScripts()).each(function (index, script) {
-        ids.push(script.id());
-      });
-    }
-    callDelete(ids);
-  };
-
-  self.updateScripts = function () {
-    $.getJSON(self.LIST_SCRIPTS, function (data) {
-      self.scripts(ko.utils.arrayMap(data, function (script) {
-        script.parentModel = self;
-        return new SparkScript(script);
-      }));
-      self.filteredScripts(self.scripts());
-      $(document).trigger("scriptsRefreshed");
-    });
-  };
-
-  self.updateDashboard = function (workflows) {
-    self.isDashboardLoaded = true;
-    var koWorkflows = ko.utils.arrayMap(workflows, function (wf) {
-      return new Workflow(wf);
-    });
-    self.runningScripts(ko.utils.arrayFilter(koWorkflows, function (wf) {
-      return wf.isRunning
-    }));
-    self.completedScripts(ko.utils.arrayFilter(koWorkflows, function (wf) {
-      return !wf.isRunning
-    }));
-  }
-
-  self.runOrShowSubmissionModal = function runOrShowSubmissionModal() {
-    var script = self.currentScript();
-    if (! $.isEmptyObject(script.getParameters())) {
-      self.submissionVariables.removeAll();
-      $.each(script.getParameters(), function (key, value) {
-        self.submissionVariables.push({'name': key, 'value': value});
-      });
-      $("#runScriptBtn").button("reset");
-      $("#runScriptBtn").attr("data-loading-text", $("#runScriptBtn").text() + " ...");
-      $("#submitModal").modal({
-        keyboard: true,
-        show: true
-      });
-    } else {
-      self.runScript();
-    }
-  };
-
-  self.showStopModal = function showStopModal() {
-    $("#stopScriptBtn").button("reset");
-    $("#stopScriptBtn").attr("data-loading-text", $("#stopScriptBtn").text() + " ...");
-    $("#stopModal").modal({
-      keyboard: true,
-      show: true
-    });
-  }
-
-  self.showFileChooser = function showFileChooser() {
-    var inputPath = this;
-    var path = inputPath.value().substr(0, inputPath.value().lastIndexOf("/"));
-    $("#filechooser").jHueFileChooser({
-      initialPath: path,
-      onFileChoose: function (filePath) {
-        inputPath.value(filePath);
-        $("#chooseFile").modal("hide");
-      },
-      createFolder: false
-    });
-    $("#chooseFile").modal("show");
-  };
-
-  function showDeleteModal() {
-    $(".deleteMsg").addClass("hide");
-    if (self.currentDeleteType() == "single") {
-      $(".deleteMsg.single").removeClass("hide");
-    }
-    if (self.currentDeleteType() == "multiple") {
-      if (self.selectedScripts().length > 1) {
-        $(".deleteMsg.multiple").removeClass("hide");
-      }
-      else {
-        $(".deleteMsg.single").removeClass("hide");
-      }
-    }
-    $("#deleteModal").modal({
-      keyboard: true,
-      show: true
-    });
-  }
-
-  function showStopModal() {
-    $(".stopMsg").addClass("hide");
-    if (self.currentStopType() == "single") {
-      $(".stopMsg.single").removeClass("hide");
-    }
-    if (self.currentStopType() == "multiple") {
-      if (self.selectedScripts().length > 1) {
-        $(".stopMsg.multiple").removeClass("hide");
-      } else {
-        $(".stopMsg.single").removeClass("hide");
-      }
-    }
-    $("#stopModal").modal({
-      keyboard: true,
-      show: true
-    });
-  }
-
-  function showConfirmModal() {
-    $("#confirmModal").modal({
-      keyboard: true,
-      show: true
-    });
-  }
-
-  function showNameModal() {
-    $("#nameModal").modal({
-      keyboard: true,
-      show: true
-    });
-  }
-
-  function callSave(script) {
-    $(document).trigger("saving");
-    $.post(self.SAVE_URL,
-        {
-          id: script.id(),
-          name: script.name(),
-          script: script.script(),
-          parameters: ko.toJSON(script.parameters()),
-          resources: ko.toJSON(script.resources()),
-          hadoopProperties: ko.toJSON(script.hadoopProperties()),
-          language: ko.toJSON(script.language())
-        },
-        function (data) {
-          self.currentScript().id(data.id);
-          $(document).trigger("saved");
-          self.updateScripts();
-        }, "json");
-  }
-
-  function callRun(script) {
-    self.currentScript(script);
-    $(document).trigger("showLogs");
-    $(document).trigger("running");
-    $("#submitModal").modal("hide");
-    $.post(self.RUN_URL,
-        {
-          id: script.id(),
-          name: script.name(),
-          script: script.script(),
-          parameters: ko.toJSON(script.parameters()),
-          submissionVariables: ko.utils.stringifyJson(self.submissionVariables()),
-          resources: ko.toJSON(script.resources()),
-          hadoopProperties: ko.toJSON(script.hadoopProperties()),
-          language: ko.toJSON(script.language())
-        },
-        function (data) {
-          if (data.id && self.currentScript().id() != data.id){
-            script.id(data.id);
-            $(document).trigger("loadEditor");
-          }
-          script.isRunning(true);
-          script.watchUrl(data.watchUrl);
-          $(document).trigger("startLogsRefresh");
-          $(document).trigger("refreshDashboard");
-          self.updateScripts();
-        }, "json").fail( function(xhr, textStatus, errorThrown) {
-          $(document).trigger("error", xhr.responseText);
-        });
-  }
-
-  function callStop(script) {
-    $(document).trigger("stopping");
-    $.post(self.STOP_URL, {
-        id: script.id()
-      },
-      function (data) {
-        $(document).trigger("stopped");
-        $("#stopModal").modal("hide");
-      }, "json");
-  }
-
-  function callCopy(script) {
-    $.post(self.COPY_URL,
-        {
-          id: script.id()
-        },
-        function (data) {
-          data.parentModel = self;
-          self.currentScript(new SparkScript(data));
-          $(document).trigger("loadEditor");
-          self.updateScripts();
-        }, "json");
-  }
-
-  function callDelete(ids) {
-    if (ids.indexOf(self.currentScript().id()) > -1) {
-      self.currentScript(new SparkScript(_defaultScript));
-      $(document).trigger("loadEditor");
-    }
-    $.post(self.DELETE_URL, {
-      ids: ids.join(",")
-    },
-    function (data) {
-      self.updateScripts();
-      $("#deleteModal").modal("hide");
-      viewModel.isDirty(false);
-    }, "json");
-  }
-
-  self.viewSubmittedScript = function (workflow) {
-    self.loadScript(workflow.scriptId);
-    self.currentScript().script(workflow.scriptContent);
-    self.currentScript().isRunning(true);
-    self.currentScript().watchUrl(workflow.watchUrl);
-    $(document).trigger("loadEditor");
-    $(document).trigger("clearLogs");
-    $(document).trigger("startLogsRefresh");
-    $(document).trigger("showLogs");
-  };
-
-  self.showLogsInterval = -1;
-  self.showLogsAtEnd = true;
-  self.showLogs = function (workflow) {
-    window.clearInterval(self.showLogsInterval);
-    $("#logsModal pre").scroll(function () {
-      self.showLogsAtEnd = $(this).scrollTop() + $(this).height() + 20 >= $(this)[0].scrollHeight;
-    });
-    if (workflow.isRunning) {
-      $("#logsModal img").removeClass("hide");
-      $("#logsModal pre").addClass("hide");
-      $("#logsModal").modal({
-        keyboard: true,
-        show: true
-      });
-      $("#logsModal").on("hide", function () {
-        window.clearInterval(self.showLogsInterval);
-      });
-      self.showLogsInterval = window.setInterval(function () {
-        $.getJSON(workflow.watchUrl, function (data) {
-          if (data.workflow && !data.workflow.isRunning) {
-            window.clearInterval(self.showLogsInterval);
-          }
-          if (data.logs.spark) {
-            $("#logsModal img").addClass("hide");
-            $("#logsModal pre").removeClass("hide");
-            var _logsEl = $("#logsModal pre");
-            var _newLinesCount = _logsEl.html() == "" ? 0 : _logsEl.html().split("<br>").length;
-            var newLines = data.logs.spark.split("\n").slice(_newLinesCount);
-            if (newLines.length > 0){
-              _logsEl.html(_logsEl.html() + newLines.join("<br>") + "<br>");
-            }
-            if (self.showLogsAtEnd) {
-              _logsEl.scrollTop(_logsEl[0].scrollHeight - _logsEl.height());
-            }
-          }
-        });
-      }, 1000);
-    }
-  };
-};

+ 296 - 0
apps/spark/static/js/spark.vm.js

@@ -0,0 +1,296 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+function sparkViewModel() {
+  var self = this;
+
+  self.appNames = ko.observableArray(); // List of jars
+  self.selectedAppName = ko.observable(0);
+  self.autoContext = ko.observable(true);
+  self.contexts = ko.observableArray(); // List of contexts
+  self.selectedContext = ko.observable(0);
+  self.classPathes = ko.observableArray(); // Read from upload or edit manually or better API
+  self.classPath = ko.observable('spark.jobserver.WordCountExample');
+  self.query = ko.mapping.fromJS({
+    'id': -1,
+    'jobId': null,
+    'context': null,
+    'query': '', // query == params
+    'name': null,
+    'description': null,
+    'errors': []
+  });
+  self.rows = ko.observableArray();
+  self.resultsEmpty = ko.observable(false);
+
+  self.appName = ko.computed({
+    'read': function() {
+      if (self.appNames().length > 0) {
+        return self.appNames()[self.selectedAppName()];
+      } else{
+        return null;
+      }
+    },
+    'write': function(value) {
+      var filtered = $.each(self.appNames(), function(index, appName) {
+        if (appName.name() == value) {
+          self.selectedAppName(index);
+        }
+      });
+    }
+  });
+
+  self.context = ko.computed({
+    'read': function() {
+      if (self.contexts().length > 0) {
+        return self.contexts()[self.selectedContext()];
+      } else{
+        return null;
+      }
+    },
+    'write': function(value) {
+      var filtered = $.each(self.contexts(), function(index, context) {
+        if (context.name() == value) {
+          self.selectedContext(index);
+        }
+      });
+    }
+  });
+
+  self.updateResults = function(results) {
+    self.rows.removeAll();
+    var newRows = [];
+    $.each(results, function(key, value) {
+      newRows.push([key, value]);
+    });
+    self.rows(newRows);
+  };
+
+  self.updateAppNames = function(appNames) {
+    var newAppNames = [];
+    $.each(appNames, function(key, value) {
+      newAppNames.push({
+        'name': ko.observable(key),
+        'nice_name': ko.observable(key)
+      });
+    });
+    self.appNames(newAppNames);
+
+    var last = $.totalStorage('hueSparkLastAppName') || (newAppNames.length > 0 ? newAppNames[0].name() : null);
+    if (last) {
+      self.appName(last);
+    }
+  };
+
+  self.updateContexts = function(contexts) {
+    var newContexts = [];
+    $.each(contexts, function(index, value) {
+      newContexts.push(createDropdownItem(value));
+    });
+    self.contexts(newContexts);
+
+    var last = $.totalStorage('hueSparkLastContext') || (newContexts.length > 0 ? newContexts[0].name() : null);
+    if (last) {
+      self.context(last);
+    }
+  };
+
+  function createDropdownItem(item) {
+    return {
+      'name': ko.observable(item),
+      'nice_name': ko.observable(item)
+    };
+  };
+
+  self.updateQuery = function(design) {
+    self.query.query(design.query);
+    self.query.id(design.id);
+    self.query.name(design.name);
+    self.query.description(design.desc);
+    self.server(design.server);
+  };
+
+  self.chooseAppName = function(value, e) {
+    $.each(self.appNames(), function(index, appName) {
+      if (appName.name() == value.name()) {
+        self.selectedAppName(index);
+      }
+    });
+    $.totalStorage('hueSparkLastAppName', self.appName().name());
+  };
+
+  self.chooseContext = function(value, e) {
+    $.each(self.contexts(), function(index, context) {
+      if (context.name() == value.name()) {
+        self.selectedContext(index);
+      }
+    });
+    $.totalStorage('hueSparkLastContext', self.context().name());
+  };
+
+  var error_fn = function(jqXHR, status, errorThrown) {
+    try {
+      $(document).trigger('server.error', $.parseJSON(jqXHR.responseText));
+    } catch(e) {
+      $(document).trigger('server.unmanageable_error', jqXHR.responseText);
+    }
+  };
+
+  self.fetchQuery = function(id) {
+    var _id = id || self.query.id();
+    if (_id && _id != -1) {
+      var request = {
+        url: '/spark/api/query/' + _id + '/get',
+        dataType: 'json',
+        type: 'GET',
+        success: function(data) {
+          self.updateQuery(data.design);
+        },
+        error: error_fn
+      };
+      $.ajax(request);
+    }
+  };
+
+  self.saveQuery = function() {
+    var self = this;
+    if (self.query.query() && self.query.name()) {
+      var data = ko.mapping.toJS(self.query);
+      data['desc'] = data['description'];
+      data['server'] = self.server().name();
+      var url = '/spark/api/query/';
+      if (self.query.id() && self.query.id() != -1) {
+        url += self.query.id() + '/';
+      }
+      var request = {
+        url: url,
+        dataType: 'json',
+        type: 'POST',
+        success: function(data) {
+          $(document).trigger('saved.query', data);
+        },
+        error: function() {
+          $(document).trigger('error.query');
+        },
+        data: data
+      };
+      $.ajax(request);
+    }
+  };
+
+  self.executeQuery = function() {
+    var data = ko.mapping.toJS(self.query);
+    data.appName = self.appName().name;
+    data.classPath = self.classPath();
+    data.autoContext = self.autoContext();
+    data.context = self.context().name;
+    var request = {
+      url: '/spark/api/execute',
+      dataType: 'json',
+      type: 'POST',
+      success: function(data) {
+        self.query.errors.removeAll();
+        if (data.status == 0) {
+          $(document).trigger('execute.query', data);
+          self.query.id(data.design);
+          self.query.jobId(data.results.result.jobId);
+          self.query.context(data.results.result.context);
+          self.checkQueryStatus();
+        } else {
+          self.query.errors.push(data.message);
+        }
+      },
+      error: error_fn,
+      data: data
+    };
+    $.ajax(request);
+  };
+
+  self.checkQueryStatus = function() {
+	var timerId = 0;
+	
+    var request = {
+      url: '/spark/api/job/' + self.query.jobId(),
+      dataType: 'json',
+      type: 'GET',
+      success: function(data) {
+        // Script finished
+        if (data.results.status == 'OK' || data.results.status == 'ERROR') {
+    	  clearInterval(timerId);
+    	  self.updateResults(data.results.result);
+
+          self.resultsEmpty($.isEmptyObject(data.results.result));
+          $(document).trigger('executed.query', data);
+        }
+      },
+      error: error_fn
+    };
+
+    timerId = setInterval(function(){
+      $.ajax(request);
+    }, 1000);
+  };
+
+  self.fetchAppNames = function() {
+    var request = {
+      url: '/spark/api/jars',
+      dataType: 'json',
+      type: 'GET',
+      success: function(data) {
+        self.updateAppNames(data.jars);
+      },
+      error: error_fn
+    };
+    $.ajax(request);
+  };
+
+  self.fetchContexts = function() {
+    var request = {
+      url: '/spark/api/contexts',
+      dataType: 'json',
+      type: 'GET',
+      success: function(data) {
+        self.updateContexts(data.contexts);
+      },
+      error: error_fn
+    };
+    $.ajax(request);
+  };
+
+  self.createContext = function() {
+    var data = $("#createContextForm").serialize(); // Not koified
+    var request = {
+      url: '/spark/api/create_context',
+      dataType: 'json',
+      type: 'POST',
+      success: function(result) {
+        self.query.errors.removeAll();
+        if (result.status == 'OK') {
+      	  self.contexts().push(createDropdownItem(result.name));
+      	  self.context(result.name);
+      	  self.autoContext(false);
+      	  $(document).trigger('created.context', data);
+        } else {
+          $(document).trigger('error', result.result);
+        }
+      },
+      error: error_fn,
+      data: data
+    };
+    $.ajax(request);
+  };
+}

+ 0 - 38
apps/spark/static/js/utils.js

@@ -1,38 +0,0 @@
-// Licensed to Cloudera, Inc. under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  Cloudera, Inc. licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-function getStatusClass(status, prefix) {
-  if (prefix == null) {
-    prefix = "label-";
-  }
-  var klass = "";
-  if (['SUCCEEDED', 'OK'].indexOf(status) > -1) {
-    klass = prefix + "success";
-  }
-  else if (['RUNNING', 'READY', 'PREP', 'WAITING', 'SUSPENDED', 'PREPSUSPENDED', 'PREPPAUSED', 'PAUSED',
-    'SUBMITTED',
-    'SUSPENDEDWITHERROR',
-    'PAUSEDWITHERROR'].indexOf(status) > -1) {
-    klass = prefix + "warning";
-  }
-  else {
-    klass = prefix + "important";
-    if (prefix == "bar-") {
-      klass = prefix + "danger";
-    }
-  }
-  return klass;
-}