mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
A tool shed admin will now receive content alerts (as part of the alert message) for each file uploaded to a repository that contains either image content or html content if the admin has chosen to receive email alerts for changes to the repository.
This commit is contained in:
@@ -26,6 +26,8 @@ Revision: ${revision}
|
||||
Change description:
|
||||
${description}
|
||||
|
||||
${content_alert_str}
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
This change alert was sent from the Galaxy tool shed hosted on the server
|
||||
"${host}"
|
||||
@@ -520,7 +522,7 @@ def get_configured_ui():
|
||||
def get_user( trans, id ):
|
||||
"""Get a user from the database by id"""
|
||||
return trans.sa_session.query( trans.model.User ).get( trans.security.decode_id( id ) )
|
||||
def handle_email_alerts( trans, repository ):
|
||||
def handle_email_alerts( trans, repository, content_alert_str='' ):
|
||||
repo_dir = repository.repo_path
|
||||
repo = hg.repository( get_configured_ui(), repo_dir )
|
||||
smtp_server = trans.app.config.smtp_server
|
||||
@@ -541,14 +543,25 @@ def handle_email_alerts( trans, repository ):
|
||||
username = ctx.user().split()[0]
|
||||
except:
|
||||
username = ctx.user()
|
||||
# Build the email message
|
||||
# We'll use 2 template bodies because we only want to send content
|
||||
# alerts to tool shed admin users.
|
||||
admin_body = string.Template( email_alert_template ) \
|
||||
.safe_substitute( host=trans.request.host,
|
||||
repository_name=repository.name,
|
||||
revision='%s:%s' %( str( ctx.rev() ), ctx ),
|
||||
display_date=display_date,
|
||||
description=ctx.description(),
|
||||
username=username,
|
||||
content_alert_str=content_alert_str )
|
||||
body = string.Template( email_alert_template ) \
|
||||
.safe_substitute( host=trans.request.host,
|
||||
repository_name=repository.name,
|
||||
revision='%s:%s' %( str( ctx.rev() ), ctx ),
|
||||
display_date=display_date,
|
||||
description=ctx.description(),
|
||||
username=username )
|
||||
username=username,
|
||||
content_alert_str='' )
|
||||
admin_users = trans.app.config.get( "admin_users", "" ).split( "," )
|
||||
frm = email_from
|
||||
subject = "Galaxy tool shed repository update alert"
|
||||
email_alerts = from_json_string( repository.email_alerts )
|
||||
@@ -556,7 +569,10 @@ def handle_email_alerts( trans, repository ):
|
||||
to = email.strip()
|
||||
# Send it
|
||||
try:
|
||||
util.send_mail( frm, to, subject, body, trans.app.config )
|
||||
if to in admin_users:
|
||||
util.send_mail( frm, to, subject, admin_body, trans.app.config )
|
||||
else:
|
||||
util.send_mail( frm, to, subject, body, trans.app.config )
|
||||
except Exception, e:
|
||||
log.exception( "An error occurred sending a tool shed repository update alert by email." )
|
||||
def update_for_browsing( trans, repository, current_working_dir, commit_message='' ):
|
||||
@@ -567,30 +583,20 @@ def update_for_browsing( trans, repository, current_working_dir, commit_message=
|
||||
repo = hg.repository( get_configured_ui(), repo_dir )
|
||||
# The following will delete the disk copy of only the files in the repository.
|
||||
#os.system( 'hg update -r null > /dev/null 2>&1' )
|
||||
repo.ui.pushbuffer()
|
||||
files_to_remove_from_disk = []
|
||||
files_to_commit = []
|
||||
commands.status( repo.ui, repo, all=True )
|
||||
status_and_file_names = repo.ui.popbuffer().strip().split( "\n" )
|
||||
if status_and_file_names and status_and_file_names[ 0 ] not in [ '' ]:
|
||||
# status_and_file_names looks something like:
|
||||
# ['? README', '? tmap_tool/tmap-0.0.9.tar.gz', '? dna_filtering.py', 'C filtering.py', 'C filtering.xml']
|
||||
# The codes used to show the status of files are:
|
||||
# M = modified
|
||||
# A = added
|
||||
# R = removed
|
||||
# C = clean
|
||||
# ! = deleted, but still tracked
|
||||
# ? = not tracked
|
||||
# I = ignored
|
||||
for status_and_file_name in status_and_file_names:
|
||||
if status_and_file_name.startswith( '?' ) or status_and_file_name.startswith( 'I' ):
|
||||
files_to_remove_from_disk.append( os.path.abspath( os.path.join( repo_dir, status_and_file_name.split()[1] ) ) )
|
||||
elif status_and_file_name.startswith( 'M' ) or status_and_file_name.startswith( 'A' ) or status_and_file_name.startswith( 'R' ):
|
||||
files_to_commit.append( os.path.abspath( os.path.join( repo_dir, status_and_file_name.split()[1] ) ) )
|
||||
# We may have files on disk in the repo directory that aren't being tracked, so they must be removed.
|
||||
# We'll use mercurial's purge extension to do this. Using this extension requires the following entry
|
||||
# in the repository's hgrc file which was not required for some time, so we'll add it if it's missing.
|
||||
# The codes used to show the status of files are as follows.
|
||||
# M = modified
|
||||
# A = added
|
||||
# R = removed
|
||||
# C = clean
|
||||
# ! = deleted, but still tracked
|
||||
# ? = not tracked
|
||||
# I = ignored
|
||||
# We'll use mercurial's purge extension to remove untracked file. Using this extension requires the
|
||||
# following entry in the repository's hgrc file which was not required for some time, so we'll add it
|
||||
# if it's missing.
|
||||
# [extensions]
|
||||
# hgext.purge=
|
||||
lines = repo.opener( 'hgrc', 'rb' ).readlines()
|
||||
@@ -624,9 +630,14 @@ def update_for_browsing( trans, repository, current_working_dir, commit_message=
|
||||
commit_message = 'Committed changes to: %s' % ', '.join( files_to_commit )
|
||||
repo.dirstate.write()
|
||||
repo.commit( user=trans.user.username, text=commit_message )
|
||||
cmd = 'hg update > /dev/null 2>&1'
|
||||
os.chdir( repo_dir )
|
||||
os.system( 'hg update > /dev/null 2>&1' )
|
||||
proc = subprocess.Popen( args=cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
|
||||
return_code = proc.wait()
|
||||
os.chdir( current_working_dir )
|
||||
if return_code != 0:
|
||||
output = proc.stdout.read( 32768 )
|
||||
log.debug( 'hg update > /dev/null 2>&1 failed in repository directory %s, reason: %s' % ( repo_dir, output ) )
|
||||
def load_tool( trans, config_file ):
|
||||
"""
|
||||
Load a single tool from the file named by `config_file` and return
|
||||
|
||||
@@ -101,12 +101,12 @@ class UploadController( BaseUIController ):
|
||||
full_path = os.path.abspath( os.path.join( repo_dir, upload_point, uploaded_file_filename ) )
|
||||
else:
|
||||
full_path = os.path.abspath( os.path.join( repo_dir, uploaded_file_filename ) )
|
||||
# TODO: enhance this method to set a flag and alert an admin to review content since
|
||||
# the hard checks are too restrictive.
|
||||
#ok, message = self.__check_file_content( uploaded_file_name )
|
||||
#if ok:
|
||||
# Move the uploaded file to the load_point within the repository hierarchy.
|
||||
shutil.move( uploaded_file_name, full_path )
|
||||
if os.path.isfile( full_path ):
|
||||
content_alert_str = self.__check_file_content( full_path )
|
||||
else:
|
||||
content_alert_str = ''
|
||||
commands.add( repo.ui, repo, full_path )
|
||||
try:
|
||||
commands.commit( repo.ui, repo, full_path, user=trans.user.username, message=commit_message )
|
||||
@@ -128,7 +128,7 @@ class UploadController( BaseUIController ):
|
||||
# Handle the special case where a xxx.loc.sample file is
|
||||
# being uploaded by copying it to ~/tool-data/xxx.loc.
|
||||
copy_sample_loc_file( trans, full_path )
|
||||
handle_email_alerts( trans, repository )
|
||||
handle_email_alerts( trans, repository, content_alert_str=content_alert_str )
|
||||
if ok:
|
||||
# Update the repository files for browsing.
|
||||
update_for_browsing( trans, repository, current_working_dir, commit_message=commit_message )
|
||||
@@ -194,18 +194,7 @@ class UploadController( BaseUIController ):
|
||||
tar.extractall( path=full_path )
|
||||
tar.close()
|
||||
uploaded_file.close()
|
||||
"""
|
||||
# TODO: enhance this method to set a flag and alert an admin to review content since
|
||||
# the hard checks are too restrictive.
|
||||
for filename_in_archive in filenames_in_archive:
|
||||
if os.path.isfile( filename_in_archive ):
|
||||
ok, message = self.__check_file_content( filename_in_archive )
|
||||
if not ok:
|
||||
# Refresh the repository files for browsing.
|
||||
current_working_dir = os.getcwd()
|
||||
update_for_browsing( trans, repository, current_working_dir )
|
||||
return False, message, []
|
||||
"""
|
||||
content_alert_str = ''
|
||||
if remove_repo_files_not_in_tar and not repository.is_new:
|
||||
# We have a repository that is not new (it contains files), so discover
|
||||
# those files that are in the repository, but not in the uploaded archive.
|
||||
@@ -250,6 +239,9 @@ class UploadController( BaseUIController ):
|
||||
# The directory is not empty
|
||||
pass
|
||||
for filename_in_archive in filenames_in_archive:
|
||||
# Check file content to ensure it is appropriate.
|
||||
if os.path.isfile( filename_in_archive ):
|
||||
content_alert_str += self.__check_file_content( filename_in_archive )
|
||||
commands.add( repo.ui, repo, filename_in_archive )
|
||||
if filename_in_archive.endswith( 'tool_data_table_conf.xml.sample' ):
|
||||
# Handle the special case where a tool_data_table_conf.xml.sample
|
||||
@@ -271,7 +263,7 @@ class UploadController( BaseUIController ):
|
||||
# exception. If this happens, we'll try the following.
|
||||
repo.dirstate.write()
|
||||
repo.commit( user=trans.user.username, text=commit_message )
|
||||
handle_email_alerts( trans, repository )
|
||||
handle_email_alerts( trans, repository, content_alert_str )
|
||||
return True, '', files_to_remove
|
||||
def uncompress( self, repository, uploaded_file_name, uploaded_file_filename, isgzip, isbz2 ):
|
||||
if isgzip:
|
||||
@@ -349,15 +341,9 @@ class UploadController( BaseUIController ):
|
||||
return False, message
|
||||
return True, ''
|
||||
def __check_file_content( self, file_path ):
|
||||
return True, ''
|
||||
message = ''
|
||||
ok = True
|
||||
head, tail = os.path.split( file_path )
|
||||
if check_html( file_path ):
|
||||
message = 'The file <b>%s</b> contains HTML content which cannot be uploaded to a Galaxy tool shed.' % str( tail )
|
||||
ok = False
|
||||
message = 'The file "%s" contains HTML content.\n' % str( file_path )
|
||||
elif check_image( file_path ):
|
||||
# For now we won't allow images to be uploaded.
|
||||
message = 'The file <b>%s</b> contains image content that cannot be uploaded to a Galaxy tool shed.' % str( tail )
|
||||
ok = False
|
||||
return ok, message
|
||||
message = 'The file "%s" contains image content.\n' % str( file_path )
|
||||
return message
|
||||
|
||||
@@ -64,7 +64,13 @@
|
||||
<div class="toolForm">
|
||||
<div class="toolFormTitle">Upload a single file or a tarball</div>
|
||||
<div class="toolFormBody">
|
||||
## TODO: nginx
|
||||
<div class="form-row">
|
||||
<div class="warningmessage">
|
||||
Uploading may take a while, depending upon the size of the file. Wait until a message is displayed in your
|
||||
browser after clicking the <b>Upload</b> button below.
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<form id="upload_form" name="upload_form" action="${h.url_for( controller='upload', action='upload', repository_id=trans.security.encode_id( repository.id ) )}" enctype="multipart/form-data" method="post">
|
||||
<div class="form-row">
|
||||
<label>File:</label>
|
||||
|
||||
Reference in New Issue
Block a user