[1.7.x] Fixed #22857 -- Reset translations when only .mo file changed

No need to restart the server when a translation file changes.
Refs #9523. Thanks artscoop for the report and Tim Graham for
the review.

Backport of 0d363b25b8 from master
This commit is contained in:
Claude Paroz 2014-06-21 11:40:36 +02:00 committed by Tim Graham
parent 31c56f1ee0
commit cbcb7c010b
1 changed files with 30 additions and 4 deletions

View File

@ -70,6 +70,9 @@ except ImportError:
RUN_RELOADER = True RUN_RELOADER = True
FILE_MODIFIED = 1
I18N_MODIFIED = 2
_mtimes = {} _mtimes = {}
_win = (sys.platform == "win32") _win = (sys.platform == "win32")
@ -112,13 +115,31 @@ def gen_filenames():
yield filename yield filename
def reset_translations():
import gettext
from django.utils.translation import trans_real
gettext._translations = {}
trans_real._translations = {}
trans_real._default = None
trans_real._active = threading.local()
def inotify_code_changed(): def inotify_code_changed():
""" """
Checks for changed code using inotify. After being called Checks for changed code using inotify. After being called
it blocks until a change event has been fired. it blocks until a change event has been fired.
""" """
class EventHandler(pyinotify.ProcessEvent):
modified_code = None
def process_default(self, event):
if event.path.endswith('.mo'):
EventHandler.modified_code = I18N_MODIFIED
else:
EventHandler.modified_code = FILE_MODIFIED
wm = pyinotify.WatchManager() wm = pyinotify.WatchManager()
notifier = pyinotify.Notifier(wm) notifier = pyinotify.Notifier(wm, EventHandler())
def update_watch(sender=None, **kwargs): def update_watch(sender=None, **kwargs):
mask = ( mask = (
@ -138,10 +159,12 @@ def inotify_code_changed():
# Block until an event happens. # Block until an event happens.
update_watch() update_watch()
notifier.check_events(timeout=None) notifier.check_events(timeout=None)
notifier.read_events()
notifier.process_events()
notifier.stop() notifier.stop()
# If we are here the code must have changed. # If we are here the code must have changed.
return True return EventHandler.modified_code
def code_changed(): def code_changed():
@ -160,7 +183,7 @@ def code_changed():
del _error_files[_error_files.index(filename)] del _error_files[_error_files.index(filename)]
except ValueError: except ValueError:
pass pass
return True return I18N_MODIFIED if filename.endswith('.mo') else FILE_MODIFIED
return False return False
@ -209,8 +232,11 @@ def reloader_thread():
else: else:
fn = code_changed fn = code_changed
while RUN_RELOADER: while RUN_RELOADER:
if fn(): change = fn()
if change == FILE_MODIFIED:
sys.exit(3) # force reload sys.exit(3) # force reload
elif change == I18N_MODIFIED:
reset_translations()
time.sleep(1) time.sleep(1)