bugdown: Add option to support "file:///" as hyperlink.

This contains contributions from Tim Abbott and Igor Tokarev.

Fixes #380.
This commit is contained in:
Kevin Chen 2016-03-10 16:17:40 +00:00 committed by Tim Abbott
parent 50382f153a
commit 6107c877e8
6 changed files with 33 additions and 4 deletions

View File

@ -719,7 +719,7 @@ def sanitize_url(url):
if not scheme:
return sanitize_url('http://' + url)
locless_schemes = ['mailto', 'news']
locless_schemes = ['mailto', 'news', 'file']
if netloc == '' and scheme not in locless_schemes:
# This fails regardless of anything else.
# Return immediately to save additional proccessing
@ -729,7 +729,7 @@ def sanitize_url(url):
# appears to have a netloc. Additionally there are plenty of other
# schemes that do weird things like launch external programs. To be
# on the safe side, we whitelist the scheme.
if scheme not in ('http', 'https', 'ftp', 'mailto'):
if scheme not in ('http', 'https', 'ftp', 'mailto', 'file'):
return None
# Upstream code scans path, parameters, and query for colon characters
@ -1079,12 +1079,14 @@ class Bugdown(markdown.Extension):
%s # zero-to-6 sets of paired parens
)?) # Path is optional
| (?:[\w.-]+\@[\w.-]+\.[\w]+) # Email is separate, since it can't have a path
%s # File path start with file:///, enable by setting ENABLE_FILE_LINKS=True
)
(?= # URL must be followed by (not included in group)
[!:;\?\),\.\'\"\>]* # Optional punctuation characters
(?:\Z|\s) # followed by whitespace or end of string
)
""" % (tlds, nested_paren_chunk)
""" % (tlds, nested_paren_chunk,
r"| (?:file://(/[^/ ]*)+/?)" if settings.ENABLE_FILE_LINKS else r"")
md.inlinePatterns.add('autolink', AutoLink(link_regex), '>link')
md.preprocessors.add('hanging_ulists',

View File

@ -925,7 +925,10 @@ class Message(ModelReprMixin, models.Model):
@staticmethod
def content_has_link(content):
# type: (text_type) -> bool
return 'http://' in content or 'https://' in content or '/user_uploads' in content
return ('http://' in content or
'https://' in content or
'/user_uploads' in content or
(settings.ENABLE_FILE_LINKS and 'file:///' in content))
@staticmethod
def is_status_message(content, rendered_content):

View File

@ -211,6 +211,22 @@ class BugdownTest(TestCase):
converted = bugdown_convert(inline_url)
self.assertEqual(match, converted)
def test_inline_file(self):
# type: () -> None
msg = 'Check out this file file:///Volumes/myserver/Users/Shared/pi.py'
converted = bugdown_convert(msg)
self.assertEqual(converted, '<p>Check out this file <a href="file:///Volumes/myserver/Users/Shared/pi.py" target="_blank" title="file:///Volumes/myserver/Users/Shared/pi.py">file:///Volumes/myserver/Users/Shared/pi.py</a></p>')
with self.settings(ENABLE_FILE_LINKS=False):
realm = Realm.objects.create(
domain='file_links_test.example.com',
string_id='file_links_test')
bugdown.make_md_engine(
realm.domain,
{'realm_filters': [[], u'file_links_test.example.com'], 'realm': [u'file_links_test.example.com', 'Realm name']})
converted = bugdown.convert(msg, realm_domain=realm.domain)
self.assertEqual(converted, '<p>Check out this file file:///Volumes/myserver/Users/Shared/pi.py</p>')
def test_inline_youtube(self):
# type: () -> None
msg = 'Check out the debate: http://www.youtube.com/watch?v=hx1mjT73xYE'

View File

@ -140,6 +140,10 @@ ERROR_REPORTING = True
# a link to an image is referenced in a message.
INLINE_IMAGE_PREVIEW = True
# Controls whether or not Zulip will parse links starting with
# "file:///" as a hyperlink (useful if you have e.g. an NFS share).
ENABLE_FILE_LINKS = False
# By default, files uploaded by users and user avatars are stored
# directly on the Zulip server. If file storage in Amazon S3 is
# desired, you can configure that as follows:

View File

@ -179,6 +179,7 @@ DEFAULT_SETTINGS = {'TWITTER_CONSUMER_KEY': '',
'FIRST_TIME_TOS_TEMPLATE': None,
'USING_PGROONGA': False,
'POST_MIGRATION_CACHE_FLUSHING': False,
'ENABLE_FILE_LINKS': False,
}
for setting_name, setting_val in six.iteritems(DEFAULT_SETTINGS):

View File

@ -91,6 +91,9 @@ CACHES['database'] = {
}
}
# Enable file:/// hyperlink support by default in tests
ENABLE_FILE_LINKS = True
LOGGING['loggers']['zulip.requests']['level'] = 'CRITICAL'
LOGGING['loggers']['zulip.management']['level'] = 'CRITICAL'