diff --git a/.build/patches/subliminal.patch b/.build/patches/subliminal.patch
new file mode 100644
index 0000000000000000000000000000000000000000..b89b2a9ac330da6427ec3515ab8648c2a0f8f182
--- /dev/null
+++ b/.build/patches/subliminal.patch
@@ -0,0 +1,151 @@
+diff --git a/sublimnal/api.py b/subliminal/api.py
+index 13c614f..6fe3368 100644
+--- a/sublimnal/api.py
++++ b/subliminal/api.py
+@@ -7,6 +7,7 @@ import os.path
+ import socket
+ 
+ from babelfish import Language
++from pkg_resources import EntryPoint
+ import requests
+ from stevedore import EnabledExtensionManager, ExtensionManager
+ 
+@@ -14,7 +15,30 @@ from .subtitle import compute_score, get_subtitle_path
+ 
+ logger = logging.getLogger(__name__)
+ 
+-provider_manager = ExtensionManager('subliminal.providers')
++
++class InternalExtensionManager(ExtensionManager):
++    """Add support for internal entry points to the :class:`~stevedore.extension.Extensionmanager`
++    Internal entry points are useful for libraries that ship their own plugins but still keep the entry point open.
++    All other parameters are passed onwards to the :class:`~stevedore.extension.Extensionmanager` constructor.
++    :param internal_entry_points: the internal providers
++    :type internal_entry_points: list of :class:`~pkg_resources.EntryPoint`
++    """
++    def __init__(self, namespace, internal_entry_points, **kwargs):
++        self.internal_entry_points = list(internal_entry_points)
++        super(InternalExtensionManager, self).__init__(namespace, **kwargs)
++
++    def _find_entry_points(self, namespace):
++        return self.internal_entry_points + super(InternalExtensionManager, self)._find_entry_points(namespace)
++
++
++provider_manager = InternalExtensionManager('subliminal.providers', [EntryPoint.parse(ep) for ep in (
++    'addic7ed = subliminal.providers.addic7ed:Addic7edProvider',
++    'napiprojekt = subliminal.providers.napiprojekt:NapiProjektProvider',
++    'opensubtitles = subliminal.providers.opensubtitles:OpenSubtitlesProvider',
++    'podnapisi = subliminal.providers.podnapisi:PodnapisiProvider',
++    'thesubdb = subliminal.providers.thesubdb:TheSubDBProvider',
++    'tvsubtitles = subliminal.providers.tvsubtitles:TVsubtitlesProvider'
++)])
+ 
+ 
+ class ProviderPool(object):
+diff --git a/subliminal/compat.py b/subliminal/compat.py
+new file mode 100644
+index 0000000..28bd3e8
+--- /dev/null
++++ b/subliminal/compat.py
+@@ -0,0 +1,21 @@
++# -*- coding: utf-8 -*-
++import sys
++import socket
++
++
++if sys.version_info[0] == 2:
++    from xmlrpclib import ServerProxy, Transport
++    from httplib import HTTPConnection
++elif sys.version_info[0] == 3:
++    from xmlrpc.client import ServerProxy, Transport
++    from http.client import HTTPConnection
++
++
++class TimeoutTransport(Transport, object):
++    def __init__(self, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, *args, **kwargs):
++        super(TimeoutTransport, self).__init__(*args, **kwargs)
++        self.timeout = timeout
++
++    def make_connection(self, host):
++        h = HTTPConnection(host, timeout=self.timeout)
++        return h
+diff --git a/subliminal/converters/podnapisi.py b/subliminal/converters/podnapisi.py
+new file mode 100644
+index 0000000..d73cb1c
+--- /dev/null
++++ b/subliminal/converters/podnapisi.py
+@@ -0,0 +1,32 @@
++# -*- coding: utf-8 -*-
++from __future__ import unicode_literals
++from babelfish import LanguageReverseConverter, LanguageConvertError, LanguageReverseError
++
++
++class PodnapisiConverter(LanguageReverseConverter):
++    def __init__(self):
++        self.from_podnapisi = {2: ('eng',), 28: ('spa',), 26: ('pol',), 36: ('srp',), 1: ('slv',), 38: ('hrv',),
++                               9: ('ita',), 8: ('fra',), 48: ('por', 'BR'), 23: ('nld',), 12: ('ara',), 13: ('ron',),
++                               33: ('bul',), 32: ('por',), 16: ('ell',), 15: ('hun',), 31: ('fin',), 30: ('tur',),
++                               7: ('ces',), 25: ('swe',), 27: ('rus',), 24: ('dan',), 22: ('heb',), 51: ('vie',),
++                               52: ('fas',), 5: ('deu',), 14: ('spa', 'AR'), 54: ('ind',), 47: ('srp', None, 'Cyrl'),
++                               3: ('nor',), 20: ('est',), 10: ('bos',), 17: ('zho',), 37: ('slk',), 35: ('mkd',),
++                               11: ('jpn',), 4: ('kor',), 29: ('sqi',), 6: ('isl',), 19: ('lit',), 46: ('ukr',),
++                               44: ('tha',), 53: ('cat',), 56: ('sin',), 21: ('lav',), 40: ('cmn',), 55: ('msa',),
++                               42: ('hin',), 50: ('bel',)}
++        self.to_podnapisi = {v: k for k, v in self.from_podnapisi.items()}
++        self.codes = set(self.from_podnapisi.keys())
++
++    def convert(self, alpha3, country=None, script=None):
++        if (alpha3,) in self.to_podnapisi:
++            return self.to_podnapisi[(alpha3,)]
++        if (alpha3, country) in self.to_podnapisi:
++            return self.to_podnapisi[(alpha3, country)]
++        if (alpha3, country, script) in self.to_podnapisi:
++            return self.to_podnapisi[(alpha3, country, script)]
++        raise LanguageConvertError(alpha3, country, script)
++
++    def reverse(self, podnapisi):
++        if podnapisi not in self.from_podnapisi:
++            raise LanguageReverseError(podnapisi)
++        return self.from_podnapisi[podnapisi]
+diff --git a/sublimnal/providers/addic7ed.py b/subliminal/providers/addic7ed.py
+index edaa728..3edfe35 100644
+--- a/sublimnal/providers/addic7ed.py
++++ b/subliminal/providers/addic7ed.py
+@@ -2,7 +2,7 @@
+ import logging
+ import re
+ 
+-from babelfish import Language
++from babelfish import Language, language_converters
+ from requests import Session
+ 
+ from . import ParserBeautifulSoup, Provider, get_version
+@@ -13,6 +13,7 @@ from ..subtitle import Subtitle, fix_line_ending, guess_matches, guess_propertie
+ from ..video import Episode
+ 
+ logger = logging.getLogger(__name__)
++language_converters.register('addic7ed = subliminal.converters.addic7ed:Addic7edConverter')
+ 
+ series_year_re = re.compile('^(?P<series>[ \w]+)(?: \((?P<year>\d{4})\))?$')
+ 
+diff --git a/sublimnal/providers/tvsubtitles.py b/subliminal/providers/tvsubtitles.py
+index e63cd43..06fd878 100644
+--- a/sublimnal/providers/tvsubtitles.py
++++ b/subliminal/providers/tvsubtitles.py
+@@ -4,7 +4,7 @@ import logging
+ import re
+ from zipfile import ZipFile
+ 
+-from babelfish import Language
++from babelfish import Language, language_converters
+ from requests import Session
+ 
+ from . import ParserBeautifulSoup, Provider, get_version
+@@ -15,6 +15,7 @@ from ..subtitle import Subtitle, fix_line_ending, guess_matches, guess_propertie
+ from ..video import Episode
+ 
+ logger = logging.getLogger(__name__)
++language_converters.register('tvsubtitles = subliminal.converters.tvsubtitles:TVsubtitlesConverter')
+ 
+ link_re = re.compile('^(?P<series>.+?)(?: \(?\d{4}\)?| \((?:US|UK)\))? \((?P<first_year>\d{4})-\d{4}\)$')
+ episode_id_re = re.compile('^episode-\d+\.html$')
diff --git a/gui/slick/images/subtitles/napiprojekt.png b/gui/slick/images/subtitles/napiprojekt.png
new file mode 100644
index 0000000000000000000000000000000000000000..147c6658ad74434a41b1d46744dddb3659df330e
Binary files /dev/null and b/gui/slick/images/subtitles/napiprojekt.png differ
diff --git a/gui/slick/views/config_providers.mako b/gui/slick/views/config_providers.mako
index 365951b34703c320827b0b3f98ae46a4aeb695f0..25186301c5f5a343a82858e879e52d3637461f22 100644
--- a/gui/slick/views/config_providers.mako
+++ b/gui/slick/views/config_providers.mako
@@ -432,6 +432,18 @@ $('#config-components').tabs();
                         </div>
                         % endif
 
+                        % if hasattr(curTorrentProvider, 'engrelease'):
+                        <div class="field-pair">
+                            <label for="${curTorrentProvider.getID()}_engrelease">
+                                <span class="component-title">English torrents</span>
+                                <span class="component-desc">
+                                    <input type="checkbox" name="${curTorrentProvider.getID()}_engrelease" id="${curTorrentProvider.getID()}_engrelease" ${('', 'checked="checked"')[bool(curTorrentProvider.engrelease)]} />
+                                    <p>only download english torrents ,or torrents containing english subtitles</p>
+                                </span>
+                            </label>
+                        </div>
+                        % endif
+
                         % if hasattr(curTorrentProvider, 'sorting'):
                         <div class="field-pair">
                             <label for="${curTorrentProvider.getID()}_sorting">
diff --git a/lib/subliminal/__init__.py b/lib/subliminal/__init__.py
index 68de539bffcb3e3ecac2062f79addbe0c58e2474..23dd54d0ecd1c0414a204f199b6d1670da5a38eb 100644
--- a/lib/subliminal/__init__.py
+++ b/lib/subliminal/__init__.py
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 __title__ = 'subliminal'
-__version__ = '1.0.dev0'
+__version__ = '1.1.0.dev0'
 __author__ = 'Antoine Bertin'
 __license__ = 'MIT'
 __copyright__ = 'Copyright 2015, Antoine Bertin'
@@ -12,7 +12,7 @@ from .api import (ProviderPool, check_video, provider_manager, download_best_sub
 from .cache import region
 from .exceptions import Error, ProviderError
 from .providers import Provider
-from .subtitle import Subtitle
+from .subtitle import Subtitle, compute_score
 from .video import SUBTITLE_EXTENSIONS, VIDEO_EXTENSIONS, Episode, Movie, Video, scan_video, scan_videos
 
 logging.getLogger(__name__).addHandler(logging.NullHandler())
diff --git a/lib/subliminal/api.py b/lib/subliminal/api.py
index 92d7b4b7f24ab01f2716a237ef71714a67991b08..6fe33686f6016e46179f9aa22cd42bd586f83382 100644
--- a/lib/subliminal/api.py
+++ b/lib/subliminal/api.py
@@ -1,5 +1,4 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
 from collections import defaultdict
 import io
 import logging
@@ -10,8 +9,7 @@ import socket
 from babelfish import Language
 from pkg_resources import EntryPoint
 import requests
-from stevedore import ExtensionManager
-from stevedore.dispatch import DispatchExtensionManager
+from stevedore import EnabledExtensionManager, ExtensionManager
 
 from .subtitle import compute_score, get_subtitle_path
 
@@ -20,14 +18,10 @@ logger = logging.getLogger(__name__)
 
 class InternalExtensionManager(ExtensionManager):
     """Add support for internal entry points to the :class:`~stevedore.extension.Extensionmanager`
-
     Internal entry points are useful for libraries that ship their own plugins but still keep the entry point open.
-
     All other parameters are passed onwards to the :class:`~stevedore.extension.Extensionmanager` constructor.
-
     :param internal_entry_points: the internal providers
     :type internal_entry_points: list of :class:`~pkg_resources.EntryPoint`
-
     """
     def __init__(self, namespace, internal_entry_points, **kwargs):
         self.internal_entry_points = list(internal_entry_points)
@@ -39,6 +33,7 @@ class InternalExtensionManager(ExtensionManager):
 
 provider_manager = InternalExtensionManager('subliminal.providers', [EntryPoint.parse(ep) for ep in (
     'addic7ed = subliminal.providers.addic7ed:Addic7edProvider',
+    'napiprojekt = subliminal.providers.napiprojekt:NapiProjektProvider',
     'opensubtitles = subliminal.providers.opensubtitles:OpenSubtitlesProvider',
     'podnapisi = subliminal.providers.podnapisi:PodnapisiProvider',
     'thesubdb = subliminal.providers.thesubdb:TheSubDBProvider',
@@ -74,8 +69,8 @@ class ProviderPool(object):
         #: Discarded providers
         self.discarded_providers = set()
 
-        #: Dedicated :data:`provider_manager` as :class:`~stevedore.dispatch.DispatchExtensionManager`
-        self.manager = DispatchExtensionManager(provider_manager.namespace, lambda e: e.name in self.providers)
+        #: Dedicated :data:`provider_manager` as :class:`~stevedore.enabled.EnabledExtensionManager`
+        self.manager = EnabledExtensionManager(provider_manager.namespace, lambda e: e.name in self.providers)
 
     def __enter__(self):
         return self
@@ -217,7 +212,7 @@ class ProviderPool(object):
         for subtitle, score in scored_subtitles:
             # check score
             if score < min_score:
-                logger.info('Score %d is below min_score (%d)', (score, min_score))
+                logger.info('Score %d is below min_score (%d)', score, min_score)
                 break
 
             # check downloaded languages
@@ -297,7 +292,6 @@ def list_subtitles(videos, languages, **kwargs):
     :type videos: set of :class:`~subliminal.video.Video`
     :param languages: languages to search for.
     :type languages: set of :class:`~babelfish.language.Language`
-    :param providers: name of providers to use, if not all.
     :return: found subtitles per video.
     :rtype: dict of :class:`~subliminal.video.Video` to list of :class:`~subliminal.subtitle.Subtitle`
 
@@ -334,8 +328,6 @@ def download_subtitles(subtitles, **kwargs):
 
     :param subtitles: subtitles to download.
     :type subtitles: list of :class:`~subliminal.subtitle.Subtitle`
-    :param dict provider_configs: provider configuration as keyword arguments per provider name to pass when.
-        instanciating the :class:`~subliminal.providers.Provider`.
 
     """
     with ProviderPool(**kwargs) as pool:
@@ -356,7 +348,6 @@ def download_best_subtitles(videos, languages, min_score=0, hearing_impaired=Fal
     :type videos: set of :class:`~subliminal.video.Video`
     :param languages: languages to download.
     :type languages: set of :class:`~babelfish.language.Language`
-    :param providers: name of providers to use, if not all.
     :param int min_score: minimum score for a subtitle to be downloaded.
     :param bool hearing_impaired: hearing impaired preference.
     :param bool only_one: download only one subtitle, not one per language.
diff --git a/lib/subliminal/cli.py b/lib/subliminal/cli.py
index c1e690b0d6cb7fd0c90448595edc1cc2bb4e6ca4..537c21c8a430da21c333ff87d16cead816df8898 100644
--- a/lib/subliminal/cli.py
+++ b/lib/subliminal/cli.py
@@ -3,9 +3,10 @@
 Subliminal uses `click <http://click.pocoo.org>`_ to provide a powerful :abbr:`CLI (command-line interface)`.
 
 """
-from __future__ import unicode_literals
+from __future__ import division
 from collections import defaultdict
 from datetime import timedelta
+import json
 import logging
 import os
 import re
@@ -14,11 +15,14 @@ from babelfish import Error as BabelfishError, Language
 import click
 from dogpile.cache.backends.file import AbstractFileLock
 from dogpile.core import ReadWriteMutex
+from six.moves import configparser
 
 from subliminal import (Episode, Movie, ProviderPool, Video, __version__, check_video, provider_manager, region,
                         save_subtitles, scan_video, scan_videos)
 from subliminal.subtitle import compute_score
 
+logger = logging.getLogger(__name__)
+
 
 class MutexLock(AbstractFileLock):
     """:class:`MutexLock` is a thread-based rw lock based on :class:`dogpile.core.ReadWriteMutex`."""
@@ -40,6 +44,115 @@ class MutexLock(AbstractFileLock):
         return self.mutex.release_write_lock()
 
 
+class Config(object):
+    """A :class:`~configparser.SafeConfigParser` wrapper to store configuration.
+
+    Interaction with the configuration is done with the properties.
+
+    :param str path: path to the configuration file.
+
+    """
+    def __init__(self, path):
+        #: Path to the configuration file
+        self.path = path
+
+        #: The underlying configuration object
+        self.config = configparser.SafeConfigParser()
+        self.config.add_section('general')
+        self.config.set('general', 'languages', json.dumps(['en']))
+        self.config.set('general', 'providers', json.dumps(sorted([p.name for p in provider_manager])))
+        self.config.set('general', 'single', str(0))
+        self.config.set('general', 'embedded_subtitles', str(1))
+        self.config.set('general', 'age', str(int(timedelta(weeks=2).total_seconds())))
+        self.config.set('general', 'hearing_impaired', str(1))
+        self.config.set('general', 'min_score', str(0))
+
+    def read(self):
+        """Read the configuration from :attr:`path`"""
+        self.config.read(self.path)
+
+    def write(self):
+        """Write the configuration to :attr:`path`"""
+        with open(self.path, 'w') as f:
+            self.config.write(f)
+
+    @property
+    def languages(self):
+        return {Language.fromietf(l) for l in json.loads(self.config.get('general', 'languages'))}
+
+    @languages.setter
+    def languages(self, value):
+        self.config.set('general', 'languages', json.dumps(sorted([str(l) for l in value])))
+
+    @property
+    def providers(self):
+        return json.loads(self.config.get('general', 'providers'))
+
+    @providers.setter
+    def providers(self, value):
+        self.config.set('general', 'providers', json.dumps(sorted([p.lower() for p in value])))
+
+    @property
+    def single(self):
+        return self.config.getboolean('general', 'single')
+
+    @single.setter
+    def single(self, value):
+        self.config.set('general', 'single', str(int(value)))
+
+    @property
+    def embedded_subtitles(self):
+        return self.config.getboolean('general', 'embedded_subtitles')
+
+    @embedded_subtitles.setter
+    def embedded_subtitles(self, value):
+        self.config.set('general', 'embedded_subtitles', str(int(value)))
+
+    @property
+    def age(self):
+        return timedelta(seconds=self.config.getint('general', 'age'))
+
+    @age.setter
+    def age(self, value):
+        self.config.set('general', 'age', str(int(value.total_seconds())))
+
+    @property
+    def hearing_impaired(self):
+        return self.config.getboolean('general', 'hearing_impaired')
+
+    @hearing_impaired.setter
+    def hearing_impaired(self, value):
+        self.config.set('general', 'hearing_impaired', str(int(value)))
+
+    @property
+    def min_score(self):
+        return self.config.getfloat('general', 'min_score')
+
+    @min_score.setter
+    def min_score(self, value):
+        self.config.set('general', 'min_score', str(value))
+
+    @property
+    def provider_configs(self):
+        rv = {}
+        for provider in provider_manager:
+            if self.config.has_section(provider.name):
+                rv[provider.name] = {k: v for k, v in self.config.items(provider.name)}
+        return rv
+
+    @provider_configs.setter
+    def provider_configs(self, value):
+        # loop over provider configurations
+        for provider, config in value.items():
+            # create the corresponding section if necessary
+            if not self.config.has_section(provider):
+                self.config.add_section(provider)
+
+            # add config options
+            for k, v in config.items():
+                self.config.set(provider, k, v)
+
+
 class LanguageParamType(click.ParamType):
     """:class:`~click.ParamType` for languages that returns a :class:`~babelfish.language.Language`"""
     name = 'language'
@@ -82,26 +195,33 @@ AGE = AgeParamType()
 
 PROVIDER = click.Choice(sorted(provider_manager.names()))
 
-subliminal_cache = 'subliminal.dbm'
+app_dir = click.get_app_dir('subliminal')
+cache_file = 'subliminal.dbm'
+config_file = 'config.ini'
 
 
 @click.group(context_settings={'max_content_width': 100}, epilog='Suggestions and bug reports are greatly appreciated: '
              'https://github.com/Diaoul/subliminal/')
 @click.option('--addic7ed', type=click.STRING, nargs=2, metavar='USERNAME PASSWORD', help='Addic7ed configuration.')
-@click.option('--cache-dir', type=click.Path(writable=True, resolve_path=True, file_okay=False),
-              default=click.get_app_dir('subliminal'), show_default=True, expose_value=True,
-              help='Path to the cache directory.')
+@click.option('--opensubtitles', type=click.STRING, nargs=2, metavar='USERNAME PASSWORD',
+              help='OpenSubtitles configuration.')
+@click.option('--cache-dir', type=click.Path(writable=True, resolve_path=True, file_okay=False), default=app_dir,
+              show_default=True, expose_value=True, help='Path to the cache directory.')
 @click.option('--debug', is_flag=True, help='Print useful information for debugging subliminal and for reporting bugs.')
 @click.version_option(__version__)
 @click.pass_context
-def subliminal(ctx, addic7ed, cache_dir, debug):
+def subliminal(ctx, addic7ed, opensubtitles, cache_dir, debug):
     """Subtitles, faster than your thoughts."""
     # create cache directory
-    os.makedirs(cache_dir, exist_ok=True)
+    try:
+        os.makedirs(cache_dir)
+    except OSError:
+        if not os.path.isdir(cache_dir):
+            raise
 
     # configure cache
     region.configure('dogpile.cache.dbm', expiration_time=timedelta(days=30),
-                     arguments={'filename': os.path.join(cache_dir, subliminal_cache), 'lock_factory': MutexLock})
+                     arguments={'filename': os.path.join(cache_dir, cache_file), 'lock_factory': MutexLock})
 
     # configure logging
     if debug:
@@ -114,6 +234,8 @@ def subliminal(ctx, addic7ed, cache_dir, debug):
     ctx.obj = {'provider_configs': {}}
     if addic7ed:
         ctx.obj['provider_configs']['addic7ed'] = {'username': addic7ed[0], 'password': addic7ed[1]}
+    if opensubtitles:
+        ctx.obj['provider_configs']['opensubtitles'] = {'username': opensubtitles[0], 'password': opensubtitles[1]}
 
 
 @subliminal.command()
@@ -123,7 +245,7 @@ def subliminal(ctx, addic7ed, cache_dir, debug):
 def cache(ctx, clear_subliminal):
     """Cache management."""
     if clear_subliminal:
-        os.remove(os.path.join(ctx.parent.params['cache_dir'], subliminal_cache))
+        os.remove(os.path.join(ctx.parent.params['cache_dir'], cache_file))
         click.echo('Subliminal\'s cache cleared.')
     else:
         click.echo('Nothing done.')
@@ -139,11 +261,11 @@ def cache(ctx, clear_subliminal):
 @click.option('-e', '--encoding', type=click.STRING, metavar='ENC', help='Subtitle file encoding, default is to '
               'preserve original encoding.')
 @click.option('-s', '--single', is_flag=True, default=False, help='Save subtitle without language code in the file '
-              'name, i.e. use .srt extension.')
+              'name, i.e. use .srt extension. Do not use this unless your media player requires it.')
 @click.option('-f', '--force', is_flag=True, default=False, help='Force download even if a subtitle already exist.')
 @click.option('-hi', '--hearing-impaired', is_flag=True, default=False, help='Prefer hearing impaired subtitles.')
 @click.option('-m', '--min-score', type=click.IntRange(0, 100), default=0, help='Minimum score for a subtitle '
-              'to be downloaded.')
+              'to be downloaded (0 to 100).')
 @click.option('-v', '--verbose', count=True, help='Increase verbosity.')
 @click.argument('path', type=click.Path(), required=True, nargs=-1)
 @click.pass_obj
@@ -163,17 +285,31 @@ def download(obj, provider, language, age, directory, encoding, single, force, h
     # scan videos
     videos = []
     ignored_videos = []
-    with click.progressbar(path, label='Collecting videos',
-                           item_show_func=lambda p: str(p) if p is not None else '') as bar:
+    errored_paths = []
+    with click.progressbar(path, label='Collecting videos', item_show_func=lambda p: p or '') as bar:
         for p in bar:
+            logger.debug('Collecting path %s', p)
+
             # non-existing
             if not os.path.exists(p):
-                videos.append(Video.fromname(p))
+                try:
+                    video = Video.fromname(p)
+                except:
+                    logger.exception('Unexpected error while collecting non-existing path %s', p)
+                    errored_paths.append(p)
+                    continue
+                videos.append(video)
                 continue
 
             # directories
             if os.path.isdir(p):
-                for video in scan_videos(p, subtitles=not force, embedded_subtitles=not force):
+                try:
+                    scanned_videos = scan_videos(p, subtitles=not force, embedded_subtitles=not force)
+                except:
+                    logger.exception('Unexpected error while collecting directory path %s', p)
+                    errored_paths.append(p)
+                    continue
+                for video in scanned_videos:
                     if check_video(video, languages=language, age=age, undefined=single):
                         videos.append(video)
                     else:
@@ -181,16 +317,26 @@ def download(obj, provider, language, age, directory, encoding, single, force, h
                 continue
 
             # other inputs
-            video = scan_video(p, subtitles=not force, embedded_subtitles=not force)
+            try:
+                video = scan_video(p, subtitles=not force, embedded_subtitles=not force)
+            except:
+                logger.exception('Unexpected error while collecting path %s', p)
+                errored_paths.append(p)
+                continue
             if check_video(video, languages=language, age=age, undefined=single):
                 videos.append(video)
             else:
                 ignored_videos.append(video)
 
+    # output errored paths
+    if verbose > 0:
+        for p in errored_paths:
+            click.secho('%s errored' % p, fg='red')
+
     # output ignored videos
     if verbose > 1:
         for video in ignored_videos:
-            click.secho('%s ignored - subtitles: %s / age: %d day%s ' % (
+            click.secho('%s ignored - subtitles: %s / age: %d day%s' % (
                 os.path.split(video.name)[1],
                 ', '.join(str(s) for s in video.subtitle_languages) or 'none',
                 video.age.days,
@@ -198,10 +344,14 @@ def download(obj, provider, language, age, directory, encoding, single, force, h
             ), fg='yellow')
 
     # report collected videos
-    click.echo('%s video%s collected / %s video%s ignored' % (click.style(str(len(videos)), bold=True),
-                                                              's' if len(videos) > 1 else '',
-                                                              click.style(str(len(ignored_videos)), bold=True),
-                                                              's' if len(ignored_videos) > 1 else ''))
+    click.echo('%s video%s collected / %s video%s ignored / %s error%s' % (
+        click.style(str(len(videos)), bold=True, fg='green' if videos else None),
+        's' if len(videos) > 1 else '',
+        click.style(str(len(ignored_videos)), bold=True, fg='yellow' if ignored_videos else None),
+        's' if len(ignored_videos) > 1 else '',
+        click.style(str(len(errored_paths)), bold=True, fg='red' if errored_paths else None),
+        's' if len(errored_paths) > 1 else '',
+    ))
 
     # exit if no video collected
     if not videos:
@@ -259,7 +409,7 @@ def download(obj, provider, language, age, directory, encoding, single, force, h
                 scaled_score *= 100 / v.scores['hash']
 
                 # echo some nice colored output
-                click.echo('  - [{score}] - {language} subtitle from {provider_name} (match on {matches})'.format(
+                click.echo('  - [{score}] {language} subtitle from {provider_name} (match on {matches})'.format(
                     score=click.style('{:5.1f}'.format(scaled_score), fg=score_color, bold=score >= v.scores['hash']),
                     language=s.language.name if s.language.country is None else '%s (%s)' % (s.language.name,
                                                                                              s.language.country.name),
diff --git a/lib/subliminal/converters/addic7ed.py b/lib/subliminal/converters/addic7ed.py
index 571f8ee11f41427a5c4bc863e19fa9c2768e6beb..f9cb83161506ef5737f50b6cae8089a62a6ce4e8 100644
--- a/lib/subliminal/converters/addic7ed.py
+++ b/lib/subliminal/converters/addic7ed.py
@@ -1,12 +1,11 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
 from babelfish import LanguageReverseConverter, language_converters
 
 
 class Addic7edConverter(LanguageReverseConverter):
     def __init__(self):
         self.name_converter = language_converters['name']
-        self.from_addic7ed = {'CatalĂ ': ('cat',), 'Chinese (Simplified)': ('zho',), 'Chinese (Traditional)': ('zho',),
+        self.from_addic7ed = {u'CatalĂ ': ('cat',), 'Chinese (Simplified)': ('zho',), 'Chinese (Traditional)': ('zho',),
                               'Euskera': ('eus',), 'Galego': ('glg',), 'Greek': ('ell',), 'Malay': ('msa',),
                               'Portuguese (Brazilian)': ('por', 'BR'), 'Serbian (Cyrillic)': ('srp', None, 'Cyrl'),
                               'Serbian (Latin)': ('srp',), 'Spanish (Latin America)': ('spa',),
diff --git a/lib/subliminal/converters/tvsubtitles.py b/lib/subliminal/converters/tvsubtitles.py
index 9507df268f7e6d8470df51a3150c9499786e6b44..45b9fed1ae6e4d6abf2f22b7a570ffc2c899aa0e 100644
--- a/lib/subliminal/converters/tvsubtitles.py
+++ b/lib/subliminal/converters/tvsubtitles.py
@@ -1,5 +1,4 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
 from babelfish import LanguageReverseConverter, language_converters
 
 
diff --git a/lib/subliminal/exceptions.py b/lib/subliminal/exceptions.py
index e1ac1c67b04318141f5a4ef9ed840c81f4fb2fe2..de2fabc0e1f10e37f80ec299b32cf0fc63849dfd 100644
--- a/lib/subliminal/exceptions.py
+++ b/lib/subliminal/exceptions.py
@@ -1,7 +1,4 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-
 class Error(Exception):
     """Base class for exceptions in subliminal."""
     pass
diff --git a/lib/subliminal/providers/__init__.py b/lib/subliminal/providers/__init__.py
index 4181c8b0bf1cb76d6a7f848eff569c53408682bd..f5ab8a306e7ea7b26b8528ef449d400d323a23c2 100644
--- a/lib/subliminal/providers/__init__.py
+++ b/lib/subliminal/providers/__init__.py
@@ -1,5 +1,4 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
 import logging
 
 from bs4 import BeautifulSoup, FeatureNotFound
diff --git a/lib/subliminal/providers/addic7ed.py b/lib/subliminal/providers/addic7ed.py
index b0a86c2bfe91070b767fc0626cc097e4c8fbe0cc..3edfe357a00db97c81f4658e31fa39339264cad3 100644
--- a/lib/subliminal/providers/addic7ed.py
+++ b/lib/subliminal/providers/addic7ed.py
@@ -1,5 +1,4 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
 import logging
 import re
 
diff --git a/lib/subliminal/providers/napiprojekt.py b/lib/subliminal/providers/napiprojekt.py
new file mode 100644
index 0000000000000000000000000000000000000000..c89db7fb6c75e333b609d14b6251b5d06561ec39
--- /dev/null
+++ b/lib/subliminal/providers/napiprojekt.py
@@ -0,0 +1,99 @@
+# -*- coding: utf-8 -*-
+import logging
+
+from babelfish import Language
+from requests import Session
+
+from . import Provider
+from ..subtitle import Subtitle
+
+logger = logging.getLogger(__name__)
+
+
+def get_subhash(hash):
+    """Get a second hash based on napiprojekt's hash.
+
+    :param str hash: napiprojekt's hash.
+    :return: the subhash.
+    :rtype: str
+
+    """
+    idx = [0xe, 0x3, 0x6, 0x8, 0x2]
+    mul = [2, 2, 5, 4, 3]
+    add = [0, 0xd, 0x10, 0xb, 0x5]
+
+    b = []
+    for i in range(len(idx)):
+        a = add[i]
+        m = mul[i]
+        i = idx[i]
+        t = a + int(hash[i], 16)
+        v = int(hash[t:t + 2], 16)
+        b.append(('%x' % (v * m))[-1])
+
+    return ''.join(b)
+
+
+class NapiProjektSubtitle(Subtitle):
+    provider_name = 'napiprojekt'
+
+    def __init__(self, language, hash):
+        super(NapiProjektSubtitle, self).__init__(language)
+        self.hash = hash
+
+    @property
+    def id(self):
+        return self.hash
+
+    def get_matches(self, video, hearing_impaired=False):
+        matches = super(NapiProjektSubtitle, self).get_matches(video, hearing_impaired=hearing_impaired)
+
+        # hash
+        if 'napiprojekt' in video.hashes and video.hashes['napiprojekt'] == self.hash:
+            matches.add('hash')
+
+        return matches
+
+
+class NapiProjektProvider(Provider):
+    languages = {Language.fromalpha2(l) for l in ['pl']}
+    required_hash = 'napiprojekt'
+    server_url = 'http://napiprojekt.pl/unit_napisy/dl.php'
+
+    def initialize(self):
+        self.session = Session()
+
+    def terminate(self):
+        self.session.close()
+
+    def query(self, language, hash):
+        params = {
+            'v': 'dreambox',
+            'kolejka': 'false',
+            'nick': '',
+            'pass': '',
+            'napios': 'Linux',
+            'l': language.alpha2.upper(),
+            'f': hash,
+            't': get_subhash(hash)}
+        logger.info('Searching subtitle %r', params)
+        response = self.session.get(self.server_url, params=params, timeout=10)
+        response.raise_for_status()
+
+        # handle subtitles not found and errors
+        if response.content[:4] == b'NPc0':
+            logger.debug('No subtitles found')
+            return None
+
+        subtitle = NapiProjektSubtitle(language, hash)
+        subtitle.content = response.content
+        logger.debug('Found subtitle %r', subtitle)
+
+        return subtitle
+
+    def list_subtitles(self, video, languages):
+        return [s for s in [self.query(l, video.hashes['napiprojekt']) for l in languages] if s is not None]
+
+    def download_subtitle(self, subtitle):
+        # there is no download step, content is already filled from listing subtitles
+        pass
diff --git a/lib/subliminal/providers/opensubtitles.py b/lib/subliminal/providers/opensubtitles.py
index 64962b04545403970de3c57ce3feb5bff995943c..9698c11de12aa9ccd276fcbb807f510a29069190 100644
--- a/lib/subliminal/providers/opensubtitles.py
+++ b/lib/subliminal/providers/opensubtitles.py
@@ -1,5 +1,4 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
 import base64
 import logging
 import os
@@ -12,7 +11,7 @@ from six.moves.xmlrpc_client import ServerProxy
 
 from . import Provider, TimeoutSafeTransport, get_version
 from .. import __version__
-from ..exceptions import AuthenticationError, DownloadLimitExceeded, ProviderError
+from ..exceptions import AuthenticationError, ConfigurationError, DownloadLimitExceeded, ProviderError
 from ..subtitle import Subtitle, fix_line_ending, guess_matches
 from ..video import Episode, Movie
 
@@ -95,13 +94,19 @@ class OpenSubtitlesSubtitle(Subtitle):
 class OpenSubtitlesProvider(Provider):
     languages = {Language.fromopensubtitles(l) for l in language_converters['opensubtitles'].codes}
 
-    def __init__(self):
+    def __init__(self, username=None, password=None):
         self.server = ServerProxy('https://api.opensubtitles.org/xml-rpc', TimeoutSafeTransport(10))
+        if username and not password or not username and password:
+            raise ConfigurationError('Username and password must be specified')
+        # None values not allowed for logging in, so replace it by ''
+        self.username = username or ''
+        self.password = password or ''
         self.token = None
 
     def initialize(self):
         logger.info('Logging in')
-        response = checked(self.server.LogIn('', '', 'eng', 'subliminal v%s' % get_version(__version__)))
+        response = checked(self.server.LogIn(self.username, self.password, 'eng',
+                                             'subliminal v%s' % get_version(__version__)))
         self.token = response['token']
         logger.debug('Logged in with token %r', self.token)
 
@@ -109,6 +114,7 @@ class OpenSubtitlesProvider(Provider):
         logger.info('Logging out')
         checked(self.server.LogOut(self.token))
         self.server.close()
+        self.token = None
         logger.debug('Logged out')
 
     def no_operation(self):
@@ -140,7 +146,7 @@ class OpenSubtitlesProvider(Provider):
 
         # exit if no data
         if not response['data']:
-            logger.info('No subtitles found')
+            logger.debug('No subtitles found')
             return subtitles
 
         # loop over subtitle items
diff --git a/lib/subliminal/providers/podnapisi.py b/lib/subliminal/providers/podnapisi.py
index c83145a44a4132a91d4d48b6c38b5dedf46c322c..2790c6fa0ea60fb7043bbc1dd80626098aecec88 100644
--- a/lib/subliminal/providers/podnapisi.py
+++ b/lib/subliminal/providers/podnapisi.py
@@ -1,5 +1,4 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
 import io
 import logging
 import re
@@ -121,7 +120,9 @@ class PodnapisiProvider(Provider):
                 releases = []
                 if subtitle_xml.find('release').text:
                     for release in subtitle_xml.find('release').text.split():
-                        releases.append(re.sub(r'\.+$', '', release))  # remove trailing dots
+                        release = re.sub(r'\.+$', '', release)  # remove trailing dots
+                        release = ''.join(filter(lambda x: ord(x) < 128, release))  # remove non-ascii characters
+                        releases.append(release)
                 title = subtitle_xml.find('title').text
                 season = int(subtitle_xml.find('tvSeason').text)
                 episode = int(subtitle_xml.find('tvEpisode').text)
diff --git a/lib/subliminal/providers/thesubdb.py b/lib/subliminal/providers/thesubdb.py
index 0cc890e9425599c2cede0bf0fb7e4517a6d76486..bb82f8af55d567618c8948e041c34637b2ad2ef0 100644
--- a/lib/subliminal/providers/thesubdb.py
+++ b/lib/subliminal/providers/thesubdb.py
@@ -1,5 +1,4 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
 import logging
 
 from babelfish import Language
@@ -65,7 +64,7 @@ class TheSubDBProvider(Provider):
             language = Language.fromalpha2(language_code)
 
             subtitle = TheSubDBSubtitle(language, hash)
-            logger.info('Found subtitle %r', subtitle)
+            logger.debug('Found subtitle %r', subtitle)
             subtitles.append(subtitle)
 
         return subtitles
diff --git a/lib/subliminal/providers/tvsubtitles.py b/lib/subliminal/providers/tvsubtitles.py
index 5e60bc9e4af04b085af49d288416c3b2c8ffceca..06fd878a933dc83650aa4e04e423cbac6b03a582 100644
--- a/lib/subliminal/providers/tvsubtitles.py
+++ b/lib/subliminal/providers/tvsubtitles.py
@@ -1,5 +1,4 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
 import io
 import logging
 import re
@@ -181,7 +180,7 @@ class TVsubtitlesProvider(Provider):
 
             subtitle = TVsubtitlesSubtitle(language, page_link, subtitle_id, series, season, episode, year, rip,
                                            release)
-            logger.info('Found subtitle %s', subtitle)
+            logger.debug('Found subtitle %s', subtitle)
             subtitles.append(subtitle)
 
         return subtitles
diff --git a/lib/subliminal/score.py b/lib/subliminal/score.py
index 831314bc28b8927c39c07fcdc4e294329fa3e89a..fe417b44327c146cb52a567ff93229c75bd49eab 100755
--- a/lib/subliminal/score.py
+++ b/lib/subliminal/score.py
@@ -32,7 +32,7 @@ The :meth:`Subtitle.get_matches <subliminal.subtitle.Subtitle.get_matches>` meth
 :func:`~subliminal.subtitle.compute_score` computes the score.
 
 """
-from __future__ import unicode_literals, print_function
+from __future__ import print_function
 
 from sympy import Eq, solve, symbols
 
diff --git a/lib/subliminal/subtitle.py b/lib/subliminal/subtitle.py
index 68f5984249df41a8d5c59a56390dd82890c3ee8d..eeb840a8023fe713a9d29a27d1b5dcb87edc6bf1 100644
--- a/lib/subliminal/subtitle.py
+++ b/lib/subliminal/subtitle.py
@@ -1,5 +1,4 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
 import logging
 import os
 
diff --git a/lib/subliminal/video.py b/lib/subliminal/video.py
index 7e52502e3b4758a5dce3e93a08ddc6320f49d128..cc916ed1b086a12d4c13d65c4d05478a752f274c 100644
--- a/lib/subliminal/video.py
+++ b/lib/subliminal/video.py
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals, division
+from __future__ import division
 from datetime import datetime, timedelta
 import hashlib
 import logging
@@ -110,6 +110,11 @@ class Video(object):
 
     @classmethod
     def fromname(cls, name):
+        """Shortcut for :meth:`fromguess` with a `guess` guessed from the `name`.
+
+        :param str name: name of the video.
+
+        """
         return cls.fromguess(name, guess_file_info(name))
 
     def __repr__(self):
@@ -243,11 +248,6 @@ def search_external_subtitles(path):
     fileroot, fileext = os.path.splitext(filename)
     subtitles = {}
     for p in os.listdir(dirpath):
-        # skip badly encoded filenames
-        if isinstance(p, bytes):  # pragma: no cover
-            logger.error('Skipping badly encoded filename %r in %r', p.decode('utf-8', errors='replace'), dirpath)
-            continue
-
         # keep only valid subtitle filenames
         if not p.startswith(fileroot) or not p.endswith(SUBTITLE_EXTENSIONS):
             continue
@@ -302,6 +302,7 @@ def scan_video(path, subtitles=True, embedded_subtitles=True):
         logger.debug('Size is %d', video.size)
         video.hashes['opensubtitles'] = hash_opensubtitles(path)
         video.hashes['thesubdb'] = hash_thesubdb(path)
+        video.hashes['napiprojekt'] = hash_napiprojekt(path)
         logger.debug('Computed hashes %r', video.hashes)
     else:
         logger.warning('Size is lower than 10MB: hashes not computed')
@@ -390,8 +391,7 @@ def scan_video(path, subtitles=True, embedded_subtitles=True):
 def scan_videos(path, subtitles=True, embedded_subtitles=True):
     """Scan `path` for videos and their subtitles.
 
-    :params path: existing directory path to scan.
-    :type path: str
+    :param str path: existing directory path to scan.
     :param bool subtitles: scan for subtitles with the same name.
     :param bool embedded_subtitles: scan for embedded subtitles.
     :return: the scanned videos.
@@ -409,31 +409,16 @@ def scan_videos(path, subtitles=True, embedded_subtitles=True):
     # walk the path
     videos = []
     for dirpath, dirnames, filenames in os.walk(path):
-        # skip badly encoded directory names
-        if isinstance(dirpath, bytes):  # pragma: no cover
-            logger.error('Skipping badly encoded directory %r', dirpath.decode('utf-8', errors='replace'))
-            continue
-
         logger.debug('Walking directory %s', dirpath)
 
         # remove badly encoded and hidden dirnames
         for dirname in list(dirnames):
-            if isinstance(dirname, bytes):  # pragma: no cover
-                logger.error('Skipping badly encoded dirname %r in %r', dirname.decode('utf-8', errors='replace'),
-                             dirpath)
-                dirnames.remove(dirname)
-            elif dirname.startswith('.'):
+            if dirname.startswith('.'):
                 logger.debug('Skipping hidden dirname %r in %r', dirname, dirpath)
                 dirnames.remove(dirname)
 
         # scan for videos
         for filename in filenames:
-            # skip badly encoded filenames
-            if isinstance(filename, bytes):  # pragma: no cover
-                logger.error('Skipping badly encoded filename %r in %r', filename.decode('utf-8', errors='replace'),
-                             dirpath)
-                continue
-
             # filter on videos
             if not filename.endswith(VIDEO_EXTENSIONS):
                 continue
@@ -510,3 +495,17 @@ def hash_thesubdb(video_path):
         data += f.read(readsize)
 
     return hashlib.md5(data).hexdigest()
+
+
+def hash_napiprojekt(video_path):
+    """Compute a hash using NapiProjekt's algorithm.
+
+    :param str video_path: path of the video.
+    :return: the hash.
+    :rtype: str
+
+    """
+    readsize = 1024 * 1024 * 10
+    with open(video_path, 'rb') as f:
+        data = f.read(readsize)
+    return hashlib.md5(data).hexdigest()
diff --git a/sickbeard/__init__.py b/sickbeard/__init__.py
index ca3f7d8dcb1df1dbebb77283cf030162178a34c3..251a47393928fe6df97cf61a7bec2ac8547f3b7a 100644
--- a/sickbeard/__init__.py
+++ b/sickbeard/__init__.py
@@ -1232,6 +1232,11 @@ def initialize(consoleLogging=True):
             if hasattr(curTorrentProvider, 'ranked'):
                 curTorrentProvider.ranked = bool(check_setting_int(CFG, curTorrentProvider.getID().upper(),
                                                                       curTorrentProvider.getID() + '_ranked', 0))
+																	  
+            if hasattr(curTorrentProvider, 'engrelease'):
+                curTorrentProvider.engrelease = bool(check_setting_int(CFG, curTorrentProvider.getID().upper(),
+                                                                      curTorrentProvider.getID() + '_engrelease', 0))
+																	  
             if hasattr(curTorrentProvider, 'sorting'):
                 curTorrentProvider.sorting = check_setting_str(CFG, curTorrentProvider.getID().upper(),
                                                                    curTorrentProvider.getID() + '_sorting','seeders')
@@ -1785,6 +1790,9 @@ def save_config():
         if hasattr(curTorrentProvider, 'ranked'):
             new_config[curTorrentProvider.getID().upper()][curTorrentProvider.getID() + '_ranked'] = int(
                 curTorrentProvider.ranked)
+        if hasattr(curTorrentProvider, 'engrelease'):
+            new_config[curTorrentProvider.getID().upper()][curTorrentProvider.getID() + '_engrelease'] = int(
+                curTorrentProvider.engrelease)
         if hasattr(curTorrentProvider, 'sorting'):
             new_config[curTorrentProvider.getID().upper()][curTorrentProvider.getID() + '_sorting'] = curTorrentProvider.sorting
         if hasattr(curTorrentProvider, 'ratio'):
diff --git a/sickbeard/postProcessor.py b/sickbeard/postProcessor.py
index df6d9db731cfff5f326b78f0de2258be85e57df4..fd82df824a5bbdddbe785c05d45423829b43b749 100644
--- a/sickbeard/postProcessor.py
+++ b/sickbeard/postProcessor.py
@@ -853,6 +853,10 @@ class PostProcessor(object):
             self._log(u"File " + self.file_path + " seems to be a directory")
             return False
 
+        if not ek(os.path.exists, self.file_path):
+            self._log(u"File " + self.file_path + " doesn't exist, did unrar fail?")
+            return False
+
         for ignore_file in self.IGNORED_FILESTRINGS:
             if ignore_file in self.file_path:
                 self._log(u"File " + self.file_path + " is ignored type, skipping")
diff --git a/sickbeard/providers/tntvillage.py b/sickbeard/providers/tntvillage.py
index cbe223c257e8ebf578a659e34c4060d4904c24bd..98ca49f663d690a34cb05147b0ad0d54eea57f1e 100644
--- a/sickbeard/providers/tntvillage.py
+++ b/sickbeard/providers/tntvillage.py
@@ -77,6 +77,7 @@ class TNTVillageProvider(generic.TorrentProvider):
         self.password = None
         self.ratio = None
         self.cat = None
+        self.engrelease = None
         self.page = 10
         self.subtitle = None
         self.minseed = None
@@ -244,15 +245,28 @@ class TNTVillageProvider(generic.TorrentProvider):
                 continue
 
             if re.search("ita", name.split(sub)[0], re.I):
-                logger.log(u"Found Italian release", logger.DEBUG)
+                logger.log(u"Found Italian release:  " + name, logger.DEBUG)
                 italian = True
                 break
 
         if not subFound and re.search("ita", name, re.I):
-            logger.log(u"Found Italian release", logger.DEBUG)
+            logger.log(u"Found Italian release:  " + name, logger.DEBUG)
             italian = True
 
         return italian
+		
+    def _is_english(self, torrent_rows):
+
+        name = str(torrent_rows.find_all('td')[1].find('b').find('span'))
+        if not name or name is 'None':
+            return False
+
+        english = False
+        if re.search("eng", name, re.I):
+            logger.log(u"Found English release:  " + name, logger.DEBUG)
+            english = True
+
+        return english
 
     def _is_season_pack(self, name):
 
@@ -369,6 +383,10 @@ class TNTVillageProvider(generic.TorrentProvider):
                                     logger.log(u"Torrent is subtitled, skipping: %s "  % title, logger.DEBUG)
                                     continue
 
+                                if self.engrelease and not self._is_english(result):
+                                    logger.log(u"Torrent isnt english audio/subtitled , skipping: %s "  % title, logger.DEBUG)
+                                    continue
+
                                 search_show = re.split(r'([Ss][\d{1,2}]+)', search_string)[0]
                                 show_title = search_show
                                 rindex = re.search(r'([Ss][\d{1,2}]+)', title)
diff --git a/sickbeard/subtitles.py b/sickbeard/subtitles.py
index 25747df81af83cb8e13c2e05c2d9dff06ed81c14..00d697bf13bd55902eaeaf2cfaec5c532d7a1e77 100644
--- a/sickbeard/subtitles.py
+++ b/sickbeard/subtitles.py
@@ -39,6 +39,7 @@ distribution = pkg_resources.Distribution(location=os.path.dirname(os.path.dirna
 entry_points = {
     'subliminal.providers': [
         'addic7ed = subliminal.providers.addic7ed:Addic7edProvider',
+        'napiprojekt = subliminal.providers.napiprojekt:NapiProjektProvider',
         'opensubtitles = subliminal.providers.opensubtitles:OpenSubtitlesProvider',
         'podnapisi = subliminal.providers.podnapisi:PodnapisiProvider',
         'thesubdb = subliminal.providers.thesubdb:TheSubDBProvider',
@@ -58,6 +59,7 @@ subliminal.region.configure('dogpile.cache.memory')
 
 provider_urls = {
     'addic7ed': 'http://www.addic7ed.com',
+    'napiprojekt': 'http://www.napiprojekt.pl',
     'opensubtitles': 'http://www.opensubtitles.org',
     'podnapisi': 'http://www.podnapisi.net',
     'thesubdb': 'http://www.thesubdb.com',
@@ -123,7 +125,7 @@ def downloadSubtitles(subtitles_info):
         video = subliminal.scan_video(video_path, subtitles=False, embedded_subtitles=False)
     except Exception:
         logger.log(u'%s: Exception caught in subliminal.scan_video for S%02dE%02d' %
-        (subtitles_info['indexerid'], subtitles_info['season'], subtitles_info['episode']), logger.DEBUG)
+        (subtitles_info['show.indexerid'], subtitles_info['season'], subtitles_info['episode']), logger.DEBUG)
         return
 
     try:
diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py
index 52449e566097cd2cb17ef26547f7dbfa64250efa..bce3acd08b7435d0af33b4a810e12094e6d8c42b 100644
--- a/sickbeard/webserve.py
+++ b/sickbeard/webserve.py
@@ -1473,21 +1473,22 @@ class Home(WebRoot):
         return self.redirect("/home/displayShow?show=%i" % show.indexerid)
 
     def deleteShow(self, show=None, full=0):
-        error, show = Show.delete(show, full)
-
-        if error is not None:
-            return self._genericMessage('Error', error)
-
-        ui.notifications.message(
-            '%s has been %s %s' %
-            (
-                show.name,
-                ('deleted', 'trashed')[bool(sickbeard.TRASH_REMOVE_SHOW)],
-                ('(media untouched)', '(with all related media)')[bool(full)]
+        if show:
+            error, show = Show.delete(show, full)
+    
+            if error is not None:
+                return self._genericMessage('Error', error)
+    
+            ui.notifications.message(
+                '%s has been %s %s' %
+                (
+                    show.name,
+                    ('deleted', 'trashed')[bool(sickbeard.TRASH_REMOVE_SHOW)],
+                    ('(media untouched)', '(with all related media)')[bool(full)]
+                )
             )
-        )
-
-        time.sleep(cpu_presets[sickbeard.CPU_PRESET])
+    
+            time.sleep(cpu_presets[sickbeard.CPU_PRESET])
 
         # Don't redirect to the default page, so the user can confirm that the show was deleted
         return self.redirect('/home/')
@@ -4418,7 +4419,14 @@ class ConfigProviders(Config):
                         kwargs[curTorrentProvider.getID() + '_ranked'])
                 except:
                     curTorrentProvider.ranked = 0
-
+	
+            if hasattr(curTorrentProvider, 'engrelease'):
+                try:
+                    curTorrentProvider.engrelease = config.checkbox_to_value(
+                        kwargs[curTorrentProvider.getID() + '_engrelease'])
+                except:
+                    curTorrentProvider.engrelease = 0
+					
             if hasattr(curTorrentProvider, 'sorting'):
                 try:
                     curTorrentProvider.sorting = str(kwargs[curTorrentProvider.getID() + '_sorting']).strip()
diff --git a/tests/search_tests.py b/tests/search_tests.py
index 5f00ccce8de8351b6aa517a3fbde3858b46ea46e..c90378db4430547c0011d79c593374f3d20c85f0 100755
--- a/tests/search_tests.py
+++ b/tests/search_tests.py
@@ -103,8 +103,8 @@ def test_generator(curData, name, provider, forceSearch):
 
             title, url = provider._get_title_and_url(items[0])
             for word in show.name.split(" "):
-                if not word in title:
-                    print "Show name not in title: %s" % title
+                if not word.lower() in title.lower():
+                    print "Show name not in title: %s. URL: %s" % (title, url)
                     continue
 
             if not url: