Repository: Flexget/Flexget

Issue:
Series/template caching?
Hi

As a result of my investigation:
http://discuss.flexget.com/t/does-flexget-cache-the-templates-in-the-config-file/1607/2

In short:
Adding a new tvshow to series in config file and using emit_series with from_start does not emit the new tvshow. A combination of both begin setting and from_start also does not work.

Setting the begin episode in the config and removing the option from_start works. Using the cli to set the begin episode also works (while still using both the begin setting in the config and from_start option).



Discussion:
can you provide an example config of this please?

Ok, while trying to build the smallest reproducible config, I've discovered something else that should make it pretty easy for you to find the issue. It goes back to my original idea that flexget somehow caches the templates/config file.

It seems that this problem only applies if the series plugin is in a template, because if it is inside a task it works as it should. This also matches with something that my friend told me the other day, that commenting and uncommenting the from_begin line forces the expected behavior, until the next time you change the series list. In fact, it doesn't seem to have anything to do with emit_series or from_start, as changing anything in the task also forces the expected behavior.

Steps to reproduce:
- https://gist.github.com/Jonybat/406e82458417b556930999fd164c895b
- `flexget -c test.yml execute --discover-now`

> You should see discovering 1 title (Arrow)
- Uncomment the Daredevil lines and run the task again

> You should still only see discovery 1 title (Arrow)
- Now change torrentz: good to any, or anything at all in the task, and run it again

> You should now see discovering 2 titles


Resolving patch:
diff --git a/flexget/task.py b/flexget/task.py
--- a/flexget/task.py
+++ b/flexget/task.py
@@ -1,5 +1,6 @@
 from __future__ import unicode_literals, division, absolute_import
 from builtins import *  # pylint: disable=unused-import, redefined-builtin
+from past.builtins import basestring
 
 import copy
 import hashlib
@@ -511,7 +512,13 @@ def _execute(self):
 
         # Save current config hash and set config_modidied flag
         with Session() as session:
-            config_hash = hashlib.md5(str(sorted(self.config.items())).encode('utf-8')).hexdigest()
+            task_templates = {}
+            templates = self.config.get('template', [])
+            for template, value in self.manager.config.get('templates', {}).items():
+                if isinstance(templates, basestring) or isinstance(templates, list) and template in templates:
+                    task_templates.update({template: value})
+            hashable_config = list(self.config.items()) + list(task_templates.items())
+            config_hash = hashlib.md5(str(sorted(hashable_config)).encode('utf-8')).hexdigest()
             last_hash = session.query(TaskConfigHash).filter(TaskConfigHash.task == self.name).first()
             if self.is_rerun:
                 # Restore the config to state right after start phase


Test patch:
diff --git a/tests/test_task.py b/tests/test_task.py
new file mode 100644
--- /dev/null
+++ b/tests/test_task.py
@@ -0,0 +1,31 @@
+from __future__ import unicode_literals, division, absolute_import
+from builtins import *  # pylint: disable=unused-import, redefined-builtin
+
+
+class TestTemplate(object):
+    config = """
+        templates:
+          test_series:
+            series:
+              test:
+                - House
+              settings:
+                test:
+                  identified_by: ep
+
+        tasks:
+          test:
+            template: test_series
+            emit_series:
+              from_start: yes
+            rerun: 0
+    """
+
+    def test_config_template_hash_check(self, manager, execute_task):
+        task = execute_task('test')
+        assert len(task.entries) == 1, 'Should have emitted House S01E01'
+
+        manager.config['templates']['test_series']['series']['test'].append('Hawaii Five-O')
+
+        task = execute_task('test')
+        assert len(task.entries) == 2, 'Should have emitted House S01E02 and Hawaii Five-O S01E01'