Repository: getnikola/nikola

Issue:
Recent title reading changes break normal builds
``` rest
.. title: Creating a Site (Not a Blog) with Nikola
.. slug: creating-a-site-not-a-blog-with-nikola
.. date: 2015-01-10 10:00:00 UTC
.. tags: nikola, python
.. link:
.. description:

Creating a Site (Not a Blog) with Nikola
========================================
```

```
Scanning posts......[2015-07-20T14:50:30Z] ERROR: Nikola: Two posts are trying to generate index.html: stories/creating-a-site.txt and stories/index.html
[2015-07-20T14:50:30Z] ERROR: Nikola: Two posts are trying to generate index.html: stories/creating-a-site.txt and stories/index.html
done!
```

git bisect: 7491fe1e1d23fbe952a0456ff9f88b738f951c34



Discussion:

Resolving patch:
diff --git a/nikola/data/themes/base/messages/messages_nb.py b/nikola/data/themes/base/messages/messages_nb.py
--- a/nikola/data/themes/base/messages/messages_nb.py
+++ b/nikola/data/themes/base/messages/messages_nb.py
@@ -2,38 +2,38 @@
 from __future__ import unicode_literals
 
 MESSAGES = {
-    "%d min remaining to read": "",
-    "(active)": "",
+    "%d min remaining to read": "%d min gjenstår å lese",
+    "(active)": "(aktiv)",
     "Also available in:": "Også tilgjengelig på:",
     "Archive": "Arkiv",
     "Categories": "Kategorier",
-    "Comments": "",
+    "Comments": "Kommentarer",
     "LANGUAGE": "norsk",
-    "Languages:": "",
+    "Languages:": "Språk:",
     "More posts about %s": "Flere innlegg om %s",
     "Newer posts": "Nyere innlegg",
     "Next post": "Neste innlegg",
-    "No posts found.": "",
-    "Nothing found.": "",
+    "No posts found.": "Fant ingen innlegg.",
+    "Nothing found.": "Fant ingenting.",
     "Older posts": "Eldre innlegg",
     "Original site": "Opprinnelig side",
     "Posted:": "Publisert:",
     "Posts about %s": "Innlegg om %s",
     "Posts for year %s": "Innlegg fra %s",
-    "Posts for {month} {day}, {year}": "",
+    "Posts for {month} {day}, {year}": "Innlegg fra {day}. {month} {year}",
     "Posts for {month} {year}": "Innlegg fra {month} {year}",
     "Previous post": "Forrige innlegg",
-    "Publication date": "",
-    "RSS feed": "",
+    "Publication date": "Publiseringsdato",
+    "RSS feed": "RSS-nyhetskanal",
     "Read in English": "Les på norsk",
     "Read more": "Les mer",
-    "Skip to main content": "",
+    "Skip to main content": "Hopp til hovedinnholdet",
     "Source": "Kilde",
-    "Subcategories:": "",
+    "Subcategories:": "Underkategorier:",
     "Tags and Categories": "Merker og kategorier",
     "Tags": "Merker",
-    "Write your page here.": "",
-    "Write your post here.": "",
+    "Write your page here.": "Skriv siden din her.",
+    "Write your post here.": "Skriv innlegget din her.",
     "old posts, page %d": "eldre innlegg, side %d",
     "page %d": "side %d",
 }
diff --git a/nikola/post.py b/nikola/post.py
--- a/nikola/post.py
+++ b/nikola/post.py
@@ -836,61 +836,47 @@ def get_metadata_from_file(source_path, config=None, lang=None):
 
 
 def _get_metadata_from_file(meta_data):
-    """Parse file contents and obtain metadata.
-
-    >>> g = _get_metadata_from_file
-    >>> list(g([]).values())
-    []
-    >>> str(g(["======","FooBar","======"])["title"])
-    'FooBar'
-    >>> str(g(["FooBar","======"])["title"])
-    'FooBar'
-    >>> str(g(["#FooBar"])["title"])
-    'FooBar'
-    >>> str(g([".. title: FooBar"])["title"])
-    'FooBar'
-    >>> 'title' in g(["","",".. title: FooBar"])
-    False
-    >>> 'title' in g(["",".. title: FooBar"])  # for #520
-    True
-    >>> 'title' in g([".. foo: bar","","FooBar", "------"])  # for #1895
-    True
-
+    """
+    Extract metadata from a post's source file.
     """
     meta = {}
-    seen_meta_flag = False
+    if not meta_data:
+        return meta
+
     re_md_title = re.compile(r'^{0}([^{0}].*)'.format(re.escape('#')))
     # Assuming rst titles are going to be at least 4 chars long
     # otherwise this detects things like ''' wich breaks other markups.
     re_rst_title = re.compile(r'^([{0}]{{4,}})'.format(re.escape(
         string.punctuation)))
 
+    # Skip up to one empty line at the beginning (for txt2tags)
+    if not meta_data[0]:
+        meta_data = meta_data[1:]
+
+    # First, get metadata from the beginning of the file,
+    # up to first empty line
+
     for i, line in enumerate(meta_data):
-        # txt2tags requires an empty line at the beginning
-        # and since we are here because it's a 1-file post
-        # let's be flexible on what we accept, so, skip empty
-        # first lines.
-        if not line and not seen_meta_flag and i > 0:
+        if not line:
             break
-        if 'title' not in meta:
-            match = re_meta(line, 'title')
-            if match[0]:
-                meta['title'] = match[1]
-        if 'title' not in meta:
+        match = re_meta(line)
+        if match[0]:
+            meta[match[0]] = match[1]
+
+    # If we have no title, try to get it from document
+    if 'title' not in meta:
+        piece = meta_data[:]
+        for i, line in enumerate(piece):
             if re_rst_title.findall(line) and i > 0:
                 meta['title'] = meta_data[i - 1].strip()
-        if 'title' not in meta:
+                break
             if (re_rst_title.findall(line) and i >= 0 and
                     re_rst_title.findall(meta_data[i + 2])):
                 meta['title'] = meta_data[i + 1].strip()
-        if 'title' not in meta:
+                break
             if re_md_title.findall(line):
                 meta['title'] = re_md_title.findall(line)[0]
-
-        match = re_meta(line)
-        if match[0]:
-            meta[match[0]] = match[1]
-            seen_meta_flag = True
+                break
 
     return meta
 


Test patch:
diff --git a/tests/test_command_import_wordpress.py b/tests/test_command_import_wordpress.py
--- a/tests/test_command_import_wordpress.py
+++ b/tests/test_command_import_wordpress.py
@@ -444,7 +444,6 @@ def test_write_content_does_not_detroy_text(self):
         with mock.patch('nikola.plugins.basic_import.open', open_mock, create=True):
             self.import_command.write_content('some_file', content)
 
-        #import pdb; pdb.set_trace()
         open_mock.assert_has_calls([
             mock.call(u'some_file', u'wb+'),
             mock.call().__enter__(),
diff --git a/tests/test_rss_feeds.py b/tests/test_rss_feeds.py
--- a/tests/test_rss_feeds.py
+++ b/tests/test_rss_feeds.py
@@ -91,12 +91,9 @@ def setUp(self):
                     # lxml will complain if the encoding is specified in the
                     # xml when running with unicode strings.
                     # We do not include this in our content.
-                    try:
-                        file_content = [
-                            call[1][0]
-                            for call in opener_mock.mock_calls[2:-1]][0]
-                    except IndexError:
-                        import pdb; pdb.set_trace()
+                    file_content = [
+                        call[1][0]
+                        for call in opener_mock.mock_calls[2:-1]][0]
                     splitted_content = file_content.split('\n')
                     self.encoding_declaration = splitted_content[0]
                     content_without_encoding_declaration = splitted_content[1:]
diff --git a/tests/test_utils.py b/tests/test_utils.py
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -322,5 +322,18 @@ def test_dict_input_lang(self):
         self.assertEqual(inp['zz'], cn)
 
 
+def test_get_metadata_from_file():
+    # These were doctests and not running :-P
+    from nikola.post import _get_metadata_from_file
+    g = _get_metadata_from_file
+    assert list(g([]).values()) == []
+    assert str(g(["======","FooBar","======"])["title"]) == 'FooBar'
+    assert str(g(["FooBar","======"])["title"]) == 'FooBar'
+    assert str(g(["#FooBar"])["title"]) == 'FooBar'
+    assert str(g([".. title: FooBar"])["title"]) == 'FooBar'
+    assert 'title' not in g(["","",".. title: FooBar"])
+    assert 'title' in g(["",".. title: FooBar"])
+    assert 'title' in g([".. foo: bar","","FooBar", "------"])
+
 if __name__ == '__main__':
     unittest.main()