Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/master' into pytest
- Loading branch information
Showing
57 changed files
with
1,134 additions
and
248 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# encoding: utf-8 | ||
|
||
import os | ||
|
||
import click | ||
|
||
from ckan.cli import minify, less, translation | ||
import ckan.plugins.toolkit as toolkit | ||
|
||
|
||
@click.group( | ||
name=u"front-end-build", | ||
short_help=u"Creates and minifies css and JavaScript files.", | ||
invoke_without_command=True, | ||
) | ||
@click.pass_context | ||
def front_end_build(ctx): | ||
if ctx.invoked_subcommand is None: | ||
ctx.invoke(build) | ||
|
||
|
||
@front_end_build.command(short_help=u"Compile css and js.",) | ||
@click.pass_context | ||
def build(ctx): | ||
ctx.invoke(less.less) | ||
ctx.invoke(translation.js) | ||
|
||
# minification | ||
public = toolkit.config.get(u"ckan.base_public_folder") | ||
root = os.path.join(os.path.dirname(__file__), u"..", public, u"base") | ||
root = os.path.abspath(root) | ||
ckanext = os.path.join(os.path.dirname(__file__), u"..", u"..", u"ckanext") | ||
ckanext = os.path.abspath(ckanext) | ||
cmd = ctx.invoke(minify.minify, path=(root, ckanext)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
# encoding: utf-8 | ||
|
||
import click | ||
|
||
import ckan.lib.jobs as bg_jobs | ||
import ckan.logic as logic | ||
import ckan.plugins as p | ||
from ckan.cli import error_shout | ||
|
||
|
||
@click.group(name=u"jobs", short_help=u"Manage background jobs.") | ||
def jobs(): | ||
pass | ||
|
||
|
||
@jobs.command(short_help=u"Start a worker.",) | ||
@click.option(u"--burst", is_flag=True, help=u"Start worker in burst mode.") | ||
@click.argument(u"queues", nargs=-1) | ||
def worker(burst, queues): | ||
"""Start a worker that fetches jobs from queues and executes them. If | ||
no queue names are given then the worker listens to the default | ||
queue, this is equivalent to | ||
paster jobs worker default | ||
If queue names are given then the worker listens to those queues | ||
and only those: | ||
paster jobs worker my-custom-queue | ||
Hence, if you want the worker to listen to the default queue and | ||
some others then you must list the default queue explicitly: | ||
paster jobs worker default my-custom-queue | ||
If the `--burst` option is given then the worker will exit as soon | ||
as all its queues are empty. | ||
""" | ||
bg_jobs.Worker(queues).work(burst=burst) | ||
|
||
|
||
@jobs.command(name=u"list", short_help=u"List jobs.") | ||
@click.argument(u"queues", nargs=-1) | ||
def list_jobs(queues): | ||
"""List currently enqueued jobs from the given queues. If no queue | ||
names are given then the jobs from all queues are listed. | ||
""" | ||
data_dict = { | ||
u"queues": list(queues), | ||
} | ||
jobs = p.toolkit.get_action(u"job_list")({u"ignore_auth": True}, data_dict) | ||
if not jobs: | ||
return click.secho(u"There are no pending jobs.", fg=u"green") | ||
for job in jobs: | ||
if job[u"title"] is None: | ||
job[u"title"] = u"" | ||
else: | ||
job[u"title"] = u'"{}"'.format(job[u"title"]) | ||
click.secho(u"{created} {id} {queue} {title}".format(**job)) | ||
|
||
|
||
@jobs.command(short_help=u"Show details about a specific job.") | ||
@click.argument(u"id") | ||
def show(id): | ||
try: | ||
job = p.toolkit.get_action(u"job_show")( | ||
{u"ignore_auth": True}, {u"id": id} | ||
) | ||
except logic.NotFound: | ||
return error_shout(u'There is no job with ID "{}"'.format(id)) | ||
click.secho(u"ID: {}".format(job[u"id"])) | ||
if job[u"title"] is None: | ||
title = u"None" | ||
else: | ||
title = u'"{}"'.format(job[u"title"]) | ||
click.secho(u"Title: {}".format(title)) | ||
click.secho(u"Created: {}".format(job[u"created"])) | ||
click.secho(u"Queue: {}".format(job[u"queue"])) | ||
|
||
|
||
@jobs.command(short_help=u"Cancel a specific job.") | ||
@click.argument(u"id") | ||
def cancel(id): | ||
"""Cancel a specific job. Jobs can only be canceled while they are | ||
enqueued. Once a worker has started executing a job it cannot be | ||
aborted anymore. | ||
""" | ||
try: | ||
p.toolkit.get_action(u"job_cancel")( | ||
{u"ignore_auth": True}, {u"id": id} | ||
) | ||
except logic.NotFound: | ||
return error_shout(u'There is no job with ID "{}"'.format(id)) | ||
|
||
click.secho(u"Cancelled job {}".format(id), fg=u"green") | ||
|
||
|
||
@jobs.command(short_help=u"Cancel all jobs.") | ||
@click.argument(u"queues", nargs=-1) | ||
def clear(queues): | ||
"""Cancel all jobs on the given queues. If no queue names are given | ||
then ALL queues are cleared. | ||
""" | ||
data_dict = { | ||
u"queues": list(queues), | ||
} | ||
queues = p.toolkit.get_action(u"job_clear")( | ||
{u"ignore_auth": True}, data_dict | ||
) | ||
queues = (u'"{}"'.format(q) for q in queues) | ||
click.secho(u"Cleared queue(s) {}".format(u", ".join(queues)), fg=u"green") | ||
|
||
|
||
@jobs.command(short_help=u"Enqueue a test job.") | ||
@click.argument(u"queues", nargs=-1) | ||
def test(queues): | ||
"""Enqueue a test job. If no queue names are given then the job is | ||
added to the default queue. If queue names are given then a | ||
separate test job is added to each of the queues. | ||
""" | ||
for queue in queues or [bg_jobs.DEFAULT_QUEUE_NAME]: | ||
job = bg_jobs.enqueue( | ||
bg_jobs.test_job, [u"A test job"], title=u"A test job", queue=queue | ||
) | ||
click.secho( | ||
u'Added test job {} to queue "{}"'.format(job.id, queue), | ||
fg=u"green", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
# encoding: utf-8 | ||
|
||
import re | ||
import traceback | ||
|
||
import click | ||
|
||
from ckan.cli import error_shout | ||
|
||
|
||
@click.group( | ||
short_help=u"Code speed profiler.", invoke_without_command=True, | ||
) | ||
@click.pass_context | ||
def profile(ctx): | ||
"""Provide a ckan url and it will make the request and record how | ||
long each function call took in a file that can be read by | ||
pstats.Stats (command-line) or runsnakerun (gui). | ||
Usage: | ||
profile URL [username] | ||
e.g. profile /data/search | ||
The result is saved in profile.data.search | ||
To view the profile in runsnakerun: | ||
runsnakerun ckan.data.search.profile | ||
You may need to install python module: cProfile | ||
""" | ||
if ctx.invoked_subcommand is None: | ||
ctx.invoke(profile) | ||
|
||
|
||
@profile.command(short_help=u"Code speed profiler.",) | ||
@click.argument(u"url") | ||
@click.argument(u"user", required=False, default=u"visitor") | ||
def profile(url, user): | ||
import cProfile | ||
from ckan.tests.helpers import _get_test_app | ||
|
||
app = _get_test_app() | ||
|
||
def profile_url(url): | ||
try: | ||
res = app.get( | ||
url, status=[200], extra_environ={u"REMOTE_USER": str(user)} | ||
) | ||
except KeyboardInterrupt: | ||
raise | ||
except Exception: | ||
error_shout(traceback.format_exc()) | ||
|
||
output_filename = u"ckan%s.profile" % re.sub( | ||
u"[/?]", u".", url.replace(u"/", u".") | ||
) | ||
profile_command = u"profile_url('%s')" % url | ||
cProfile.runctx( | ||
profile_command, globals(), locals(), filename=output_filename | ||
) | ||
import pstats | ||
|
||
stats = pstats.Stats(output_filename) | ||
stats.sort_stats(u"cumulative") | ||
stats.print_stats(0.1) # show only top 10% of lines | ||
click.secho(u"Only top 10% of lines shown") | ||
click.secho(u"Written profile to: %s" % output_filename, fg=u"green") |
Oops, something went wrong.