Skip to content

Commit

Permalink
Merge branch 'feature/ranges'
Browse files Browse the repository at this point in the history
  • Loading branch information
caleb531 committed Jan 15, 2015
2 parents 5b3fdec + 1689dff commit 0e3ee72
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 31 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ YouVersion Suggest is an Alfred workflow which allows you to search the online [

## Usage

Type the `yv` keyword, along with a space and a phrase representing the bible reference you wish to find. The phrase can be partial book name, chapter, or verse. You may also include an option version (translation) at the end of your query. As you type, YouVersion Suggest will display a list of suggestions matching your query.
Type the `yv` keyword, along with a space and a phrase representing the bible reference you wish to find. The phrase can be partial book name, chapter, verse, or range of verses. You may also include an option version (translation) at the end of your query. As you type, YouVersion Suggest will display a list of suggestions matching your query.

### Query Examples

* `luke`
* `eph 3`
* `1 c 3 esv`
* `luke` => Luke
* `eph 3` => Ephesians 3
* `1 t 3 e` => 1 Thessalonians 3 (ESV), 1 Timothy 3 (ESV)
* `mat 6:34 nlt` => Matthew 6:34 (NLT)
* `1 co 13.4-7` => 1 Corinthians 13.4-7

## Testing

Expand Down
Binary file modified YouVersion Suggest.alfredworkflow
Binary file not shown.
1 change: 1 addition & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from tests.test_search_chapter import *
from tests.test_search_verse import *
from tests.test_search_version import *
from tests.test_search_incomplete import *
from tests.test_search_xml import *
from tests.test_search_main import *
from tests.test_open import *
27 changes: 27 additions & 0 deletions tests/test_search_incomplete.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env python
import unittest
import yv_suggest.search as yvs

class SearchIncompleteTestCase(unittest.TestCase):
'''test the searching of incomplete Bible references'''

def test_incomplete_verse(self):
'''should treat incomplete verse reference as chapter reference'''
results = yvs.get_result_list('psalm 19:')
self.assertEqual(len(results), 1)
self.assertEqual(results[0]['title'], 'Psalm 19')

def test_incomplete_dot_verse(self):
'''should treat incomplete "dot verse" reference as chapter reference'''
results = yvs.get_result_list('psalm 19.')
self.assertEqual(len(results), 1)
self.assertEqual(results[0]['title'], 'Psalm 19')

def test_incomplete_verse_range(self):
'''should treat incomplete verse ranges as single-verse references'''
results = yvs.get_result_list('psalm 19.7-')
self.assertEqual(len(results), 1)
self.assertEqual(results[0]['title'], 'Psalm 19.7')

if __name__ == '__main__':
unittest.main()
11 changes: 11 additions & 0 deletions tests/test_search_verse.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,21 @@ def test_dot(self):
self.assertEqual(len(results), 1)
self.assertEqual(results[0]['title'], 'Luke 4.8')

def test_range(self):
'''should match verse ranges'''
results = yvs.get_result_list('1 cor 13.4-7')
self.assertEqual(len(results), 1)
self.assertEqual(results[0]['title'], '1 Corinthians 13.4-7')

def test_id(self):
'''should use correct ID for verses'''
results = yvs.get_result_list('luke 4:8')
self.assertEqual(results[0]['uid'], 'niv/luk.4.8')

def test_range_id(self):
'''should use correct ID for verse ranges'''
results = yvs.get_result_list('1 cor 13.4-7')
self.assertEqual(results[0]['uid'], 'niv/1co.13.4-7')

if __name__ == '__main__':
unittest.main()
62 changes: 35 additions & 27 deletions yv_suggest/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,11 @@ def get_versions():
default_version = 'NIV'

# Pattern for parsing any bible reference
bible_ref_patt = '^((\d )?[a-z ]+)( (\d+)((\:|\.)(\d+)?)?)?( [a-z]+\d*)?$'
ref_patt = '^((\d )?[a-z ]+)( (\d+)((\:|\.)(\d+)(-(\d+))?)?( [a-z]+\d*)?)?$'
# Pattern for parsing a chapter.verse reference (irrespective of book)
chapter_dot_verse_patt = '(\d+)\.(\d+)'
# Pattern for matching separator tokens at end of incomplete references
incomplete_ref_token_patt = '[\-\.\:]$'

# Guess a version based on the given partial version
def guess_version(partial_version):
Expand All @@ -66,12 +68,8 @@ def get_result_list_xml(results):
# Create <item> element for result with appropriate attributes
item = ET.Element('item')
item.set('uid', result['uid'])
if result.get('arg'):
item.set('arg', result['arg'])
if result.get('valid'):
item.set('valid', result['valid'])
else:
item.set('valid', 'yes')
item.set('arg', result.get('arg', ''))
item.set('valid', result.get('valid', 'yes'))
root.append(item)
# Create appropriate child elements of <item> element
title = ET.Element('title')
Expand All @@ -90,13 +88,15 @@ def format_query_str(query_str):
query_str = re.sub('\s+', ' ', query_str)
# Lowercase query for consistency
query_str = query_str.lower()
# Remove tokens at end of incomplete references
query_str = re.sub(incomplete_ref_token_patt, '', query_str)
return query_str

# Builds the query object from the given query string
def get_query_object(query_str):

# Match section of the bible based on query
ref_matches = re.search(bible_ref_patt, query_str)
ref_matches = re.search(ref_patt, query_str)

if ref_matches:

Expand Down Expand Up @@ -128,9 +128,14 @@ def get_query_object(query_str):
else:
query['verse'] = None

if ref_matches.group(9):
query['verse_end'] = int(ref_matches.group(9))
else:
query['verse_end'] = None

# Parse version if given
if ref_matches.group(8):
query['version'] = ref_matches.group(8).lstrip()
if ref_matches.group(10):
query['version'] = ref_matches.group(10).lstrip()
else:
query['version'] = None

Expand Down Expand Up @@ -182,35 +187,38 @@ def get_result_list(query_str):

if query['chapter']:

# Find chapter or verse
# If chapter exists within the book
if query['chapter'] <= book['chapters']:

# Find chapter if given
result['uid'] = '{book}.{chapter}'.format(
book=book['id'],
chapter=query['chapter']
)
result['title'] = '{book} {chapter}'.format(
book=book['name'],
chapter=query['chapter']
)

if query['verse']:

# Find verse if given
result['uid'] = '{book}.{chapter}.{verse}'.format(
book=book['id'],
chapter=query['chapter'],
result['uid'] += '.{verse}'.format(
verse=query['verse']
)
result['title'] = '{book} {chapter}{sep}{verse}'.format(
book=book['name'],
chapter=query['chapter'],
result['title'] += '{sep}{verse}'.format(
verse=query['verse'],
sep=query['separator']
)

else:
if query['verse_end']:

# Find chapter if given
result['uid'] = '{book}.{chapter}'.format(
book=book['id'],
chapter=query['chapter']
)
result['title'] = '{book} {chapter}'.format(
book=book['name'],
chapter=query['chapter']
)
result['uid'] += '-{verse}'.format(
verse=query['verse_end']
)
result['title'] += '-{verse}'.format(
verse=query['verse_end']
)

else:
# Find book if no chapter or verse is given
Expand Down

0 comments on commit 0e3ee72

Please sign in to comment.