{"action":"created","comment":{"url":"https://api.github.com/repos/getnikola/nikola/pulls/comments/125167416","pull_request_review_id":47535364,"id":125167416,"diff_hunk":"@@ -2028,3 +2028,111 @@ def read_from_config(self, site, basename, posts_per_classification_per_language\n         args = {'translation_manager': self, 'site': site,\n                 'posts_per_classification_per_language': posts_per_classification_per_language}\n         signal('{}_translations_config'.format(basename.lower())).send(args)\n+\n+\n+# Moved to global variable to avoid recompilation\n+# of regex every time re_meta() is called.\n+_DEFAULT_REST_METADATA_PARSING = re.compile('^\\.\\. (.*?): (.*)')\n+\n+\n+def re_meta(line, match=None):\n+    \"\"\"Find metadata using regular expressions.\"\"\"\n+    if match:\n+        reStr = re.compile('^\\.\\. {0}: (.*)'.format(re.escape(match)))\n+    else:\n+        reStr = _DEFAULT_REST_METADATA_PARSING\n+    result = reStr.findall(line.strip())\n+    if match and result:\n+        return (match, result[0])\n+    elif not match and result:\n+        return (result[0][0], result[0][1].strip())\n+    else:\n+        return (None,)\n+\n+\n+def extract_metadata(file_lines):\n+    \"\"\"Extract metadata from the lines of a file.\n+\n+    Returns a pair ``(meta, metadata_type)``, where ``meta`` is the\n+    metadata dictionary and ``metadata_type`` the metadata format.\n+\n+    Valid values for ``metadata_type`` are:\n+    * ``'none'``: no metadata was found (file was empty)\n+    * ``'yaml'``: metadata in YAML format\n+    * ``'toml'``: metadata in TOML format\n+    * ``'rest'``: metadata in reST format (the standard Nikola\n+                  reST-like metadata format)\n+    \"\"\"\n+    meta = {}\n+    if not file_lines:\n+        return meta, 'none'\n+\n+    # Skip up to one empty line at the beginning (for txt2tags)\n+    if not file_lines[0]:\n+        file_lines = file_lines[1:]\n+\n+    # If 1st line is '---', then it's YAML metadata\n+    if file_lines[0] == '---':\n+        if yaml is None:\n+            req_missing('pyyaml', 'use YAML metadata', optional=True)\n+            raise ValueError('Error parsing metadata')\n+        idx = file_lines.index('---', 1)\n+        meta = yaml.safe_load('\\n'.join(file_lines[1:idx]))\n+        # We expect empty metadata to be '', not None\n+        for k in meta:\n+            if meta[k] is None:\n+                meta[k] = ''\n+        return meta, 'yaml'\n+\n+    # If 1st line is '+++', then it's TOML metadata\n+    if file_lines[0] == '+++':\n+        if toml is None:\n+            req_missing('toml', 'use TOML metadata', optional=True)\n+            raise ValueError('Error parsing metadata')\n+        idx = file_lines.index('+++', 1)\n+        meta = toml.loads('\\n'.join(file_lines[1:idx]))\n+        return meta, 'toml'\n+\n+    # First, get metadata from the beginning of the file,\n+    # up to first empty line\n+\n+    for line in file_lines:\n+        if not line:\n+            break\n+        match = re_meta(line)\n+        if match[0]:\n+            meta[match[0]] = match[1]\n+\n+    return meta, 'nikola'\n+\n+\n+def split_metadata(data):\n+    \"\"\"Split data from metadata in the raw post content.\n+\n+    This splits in the first empty line that is NOT at the beginning\n+    of the document, or after YAML/TOML metadata without an empty line.\n+\n+    Returns a tuple ``(meta, content, metadata_type)`` where ``meta`` and\n+    ``content`` are parts of ``data``, and ``metadata_type`` is the metadata\n+    format.\n+\n+    Valid values for ``metadata_type`` are:\n+    * ``'none'``: no metadata was found (file was empty)\n+    * ``'yaml'``: metadata in YAML format\n+    * ``'toml'``: metadata in TOML format\n+    * ``'rest'``: metadata in reST format (the standard Nikola\n+                  reST-like metadata format)\n+    \"\"\"\n+    if data.startswith('---'):  # YAML metadata","path":"nikola/utils.py","position":108,"original_position":108,"commit_id":"b8729eaeae0ebfbf1a7610389cae3b93612d74e3","original_commit_id":"9c3d10762b9d2cf9f1a99a1cc4afa94cb3a8c11e","user":{"login":"Kwpolska","id":327323,"avatar_url":"https://avatars2.githubusercontent.com/u/327323?v=3","gravatar_id":"","url":"https://api.github.com/users/Kwpolska","html_url":"https://github.com/Kwpolska","followers_url":"https://api.github.com/users/Kwpolska/followers","following_url":"https://api.github.com/users/Kwpolska/following{/other_user}","gists_url":"https://api.github.com/users/Kwpolska/gists{/gist_id}","starred_url":"https://api.github.com/users/Kwpolska/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Kwpolska/subscriptions","organizations_url":"https://api.github.com/users/Kwpolska/orgs","repos_url":"https://api.github.com/users/Kwpolska/repos","events_url":"https://api.github.com/users/Kwpolska/events{/privacy}","received_events_url":"https://api.github.com/users/Kwpolska/received_events","type":"User","site_admin":false},"body":"Yes, I’ll handle it then.","created_at":"2017-07-01T19:15:10Z","updated_at":"2017-07-01T19:15:10Z","html_url":"https://github.com/getnikola/nikola/pull/2856#discussion_r125167416","pull_request_url":"https://api.github.com/repos/getnikola/nikola/pulls/2856","_links":{"self":{"href":"https://api.github.com/repos/getnikola/nikola/pulls/comments/125167416"},"html":{"href":"https://github.com/getnikola/nikola/pull/2856#discussion_r125167416"},"pull_request":{"href":"https://api.github.com/repos/getnikola/nikola/pulls/2856"}}},"pull_request":{"url":"https://api.github.com/repos/getnikola/nikola/pulls/2856","id":128497317,"html_url":"https://github.com/getnikola/nikola/pull/2856","diff_url":"https://github.com/getnikola/nikola/pull/2856.diff","patch_url":"https://github.com/getnikola/nikola/pull/2856.patch","issue_url":"https://api.github.com/repos/getnikola/nikola/issues/2856","number":2856,"state":"open","locked":false,"title":"Generalize metadata functions and moving them to utils.py","user":{"login":"felixfontein","id":5781356,"avatar_url":"https://avatars3.githubusercontent.com/u/5781356?v=3","gravatar_id":"","url":"https://api.github.com/users/felixfontein","html_url":"https://github.com/felixfontein","followers_url":"https://api.github.com/users/felixfontein/followers","following_url":"https://api.github.com/users/felixfontein/following{/other_user}","gists_url":"https://api.github.com/users/felixfontein/gists{/gist_id}","starred_url":"https://api.github.com/users/felixfontein/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/felixfontein/subscriptions","organizations_url":"https://api.github.com/users/felixfontein/orgs","repos_url":"https://api.github.com/users/felixfontein/repos","events_url":"https://api.github.com/users/felixfontein/events{/privacy}","received_events_url":"https://api.github.com/users/felixfontein/received_events","type":"User","site_admin":false},"body":"This makes implementing getnikola/plugins#232 much easier, and separates the metadata extraction from the higher level parts (metadata transformation).","created_at":"2017-07-01T18:44:06Z","updated_at":"2017-07-01T19:15:10Z","closed_at":null,"merged_at":null,"merge_commit_sha":"1657c7a3e2dee47f81ec95ba4b69860ca6a30e07","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/getnikola/nikola/pulls/2856/commits","review_comments_url":"https://api.github.com/repos/getnikola/nikola/pulls/2856/comments","review_comment_url":"https://api.github.com/repos/getnikola/nikola/pulls/comments{/number}","comments_url":"https://api.github.com/repos/getnikola/nikola/issues/2856/comments","statuses_url":"https://api.github.com/repos/getnikola/nikola/statuses/b8729eaeae0ebfbf1a7610389cae3b93612d74e3","head":{"label":"getnikola:generalize-metadata-functions","ref":"generalize-metadata-functions","sha":"b8729eaeae0ebfbf1a7610389cae3b93612d74e3","user":{"login":"getnikola","id":5413476,"avatar_url":"https://avatars3.githubusercontent.com/u/5413476?v=3","gravatar_id":"","url":"https://api.github.com/users/getnikola","html_url":"https://github.com/getnikola","followers_url":"https://api.github.com/users/getnikola/followers","following_url":"https://api.github.com/users/getnikola/following{/other_user}","gists_url":"https://api.github.com/users/getnikola/gists{/gist_id}","starred_url":"https://api.github.com/users/getnikola/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/getnikola/subscriptions","organizations_url":"https://api.github.com/users/getnikola/orgs","repos_url":"https://api.github.com/users/getnikola/repos","events_url":"https://api.github.com/users/getnikola/events{/privacy}","received_events_url":"https://api.github.com/users/getnikola/received_events","type":"Organization","site_admin":false},"repo":{"id":4025121,"name":"nikola","full_name":"getnikola/nikola","owner":{"login":"getnikola","id":5413476,"avatar_url":"https://avatars3.githubusercontent.com/u/5413476?v=3","gravatar_id":"","url":"https://api.github.com/users/getnikola","html_url":"https://github.com/getnikola","followers_url":"https://api.github.com/users/getnikola/followers","following_url":"https://api.github.com/users/getnikola/following{/other_user}","gists_url":"https://api.github.com/users/getnikola/gists{/gist_id}","starred_url":"https://api.github.com/users/getnikola/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/getnikola/subscriptions","organizations_url":"https://api.github.com/users/getnikola/orgs","repos_url":"https://api.github.com/users/getnikola/repos","events_url":"https://api.github.com/users/getnikola/events{/privacy}","received_events_url":"https://api.github.com/users/getnikola/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/getnikola/nikola","description":"A static website and blog generator","fork":false,"url":"https://api.github.com/repos/getnikola/nikola","forks_url":"https://api.github.com/repos/getnikola/nikola/forks","keys_url":"https://api.github.com/repos/getnikola/nikola/keys{/key_id}","collaborators_url":"https://api.github.com/repos/getnikola/nikola/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/getnikola/nikola/teams","hooks_url":"https://api.github.com/repos/getnikola/nikola/hooks","issue_events_url":"https://api.github.com/repos/getnikola/nikola/issues/events{/number}","events_url":"https://api.github.com/repos/getnikola/nikola/events","assignees_url":"https://api.github.com/repos/getnikola/nikola/assignees{/user}","branches_url":"https://api.github.com/repos/getnikola/nikola/branches{/branch}","tags_url":"https://api.github.com/repos/getnikola/nikola/tags","blobs_url":"https://api.github.com/repos/getnikola/nikola/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/getnikola/nikola/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/getnikola/nikola/git/refs{/sha}","trees_url":"https://api.github.com/repos/getnikola/nikola/git/trees{/sha}","statuses_url":"https://api.github.com/repos/getnikola/nikola/statuses/{sha}","languages_url":"https://api.github.com/repos/getnikola/nikola/languages","stargazers_url":"https://api.github.com/repos/getnikola/nikola/stargazers","contributors_url":"https://api.github.com/repos/getnikola/nikola/contributors","subscribers_url":"https://api.github.com/repos/getnikola/nikola/subscribers","subscription_url":"https://api.github.com/repos/getnikola/nikola/subscription","commits_url":"https://api.github.com/repos/getnikola/nikola/commits{/sha}","git_commits_url":"https://api.github.com/repos/getnikola/nikola/git/commits{/sha}","comments_url":"https://api.github.com/repos/getnikola/nikola/comments{/number}","issue_comment_url":"https://api.github.com/repos/getnikola/nikola/issues/comments{/number}","contents_url":"https://api.github.com/repos/getnikola/nikola/contents/{+path}","compare_url":"https://api.github.com/repos/getnikola/nikola/compare/{base}...{head}","merges_url":"https://api.github.com/repos/getnikola/nikola/merges","archive_url":"https://api.github.com/repos/getnikola/nikola/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/getnikola/nikola/downloads","issues_url":"https://api.github.com/repos/getnikola/nikola/issues{/number}","pulls_url":"https://api.github.com/repos/getnikola/nikola/pulls{/number}","milestones_url":"https://api.github.com/repos/getnikola/nikola/milestones{/number}","notifications_url":"https://api.github.com/repos/getnikola/nikola/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/getnikola/nikola/labels{/name}","releases_url":"https://api.github.com/repos/getnikola/nikola/releases{/id}","deployments_url":"https://api.github.com/repos/getnikola/nikola/deployments","created_at":"2012-04-14T13:53:22Z","updated_at":"2017-07-01T18:32:43Z","pushed_at":"2017-07-01T19:12:48Z","git_url":"git://github.com/getnikola/nikola.git","ssh_url":"git@github.com:getnikola/nikola.git","clone_url":"https://github.com/getnikola/nikola.git","svn_url":"https://github.com/getnikola/nikola","homepage":"https://getnikola.com/","size":25150,"stargazers_count":1234,"watchers_count":1234,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":305,"mirror_url":null,"open_issues_count":59,"forks":305,"open_issues":59,"watchers":1234,"default_branch":"master"}},"base":{"label":"getnikola:master","ref":"master","sha":"c94951d0a8dff7fe10d0e624174f08d5bcd3a5b3","user":{"login":"getnikola","id":5413476,"avatar_url":"https://avatars3.githubusercontent.com/u/5413476?v=3","gravatar_id":"","url":"https://api.github.com/users/getnikola","html_url":"https://github.com/getnikola","followers_url":"https://api.github.com/users/getnikola/followers","following_url":"https://api.github.com/users/getnikola/following{/other_user}","gists_url":"https://api.github.com/users/getnikola/gists{/gist_id}","starred_url":"https://api.github.com/users/getnikola/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/getnikola/subscriptions","organizations_url":"https://api.github.com/users/getnikola/orgs","repos_url":"https://api.github.com/users/getnikola/repos","events_url":"https://api.github.com/users/getnikola/events{/privacy}","received_events_url":"https://api.github.com/users/getnikola/received_events","type":"Organization","site_admin":false},"repo":{"id":4025121,"name":"nikola","full_name":"getnikola/nikola","owner":{"login":"getnikola","id":5413476,"avatar_url":"https://avatars3.githubusercontent.com/u/5413476?v=3","gravatar_id":"","url":"https://api.github.com/users/getnikola","html_url":"https://github.com/getnikola","followers_url":"https://api.github.com/users/getnikola/followers","following_url":"https://api.github.com/users/getnikola/following{/other_user}","gists_url":"https://api.github.com/users/getnikola/gists{/gist_id}","starred_url":"https://api.github.com/users/getnikola/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/getnikola/subscriptions","organizations_url":"https://api.github.com/users/getnikola/orgs","repos_url":"https://api.github.com/users/getnikola/repos","events_url":"https://api.github.com/users/getnikola/events{/privacy}","received_events_url":"https://api.github.com/users/getnikola/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/getnikola/nikola","description":"A static website and blog generator","fork":false,"url":"https://api.github.com/repos/getnikola/nikola","forks_url":"https://api.github.com/repos/getnikola/nikola/forks","keys_url":"https://api.github.com/repos/getnikola/nikola/keys{/key_id}","collaborators_url":"https://api.github.com/repos/getnikola/nikola/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/getnikola/nikola/teams","hooks_url":"https://api.github.com/repos/getnikola/nikola/hooks","issue_events_url":"https://api.github.com/repos/getnikola/nikola/issues/events{/number}","events_url":"https://api.github.com/repos/getnikola/nikola/events","assignees_url":"https://api.github.com/repos/getnikola/nikola/assignees{/user}","branches_url":"https://api.github.com/repos/getnikola/nikola/branches{/branch}","tags_url":"https://api.github.com/repos/getnikola/nikola/tags","blobs_url":"https://api.github.com/repos/getnikola/nikola/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/getnikola/nikola/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/getnikola/nikola/git/refs{/sha}","trees_url":"https://api.github.com/repos/getnikola/nikola/git/trees{/sha}","statuses_url":"https://api.github.com/repos/getnikola/nikola/statuses/{sha}","languages_url":"https://api.github.com/repos/getnikola/nikola/languages","stargazers_url":"https://api.github.com/repos/getnikola/nikola/stargazers","contributors_url":"https://api.github.com/repos/getnikola/nikola/contributors","subscribers_url":"https://api.github.com/repos/getnikola/nikola/subscribers","subscription_url":"https://api.github.com/repos/getnikola/nikola/subscription","commits_url":"https://api.github.com/repos/getnikola/nikola/commits{/sha}","git_commits_url":"https://api.github.com/repos/getnikola/nikola/git/commits{/sha}","comments_url":"https://api.github.com/repos/getnikola/nikola/comments{/number}","issue_comment_url":"https://api.github.com/repos/getnikola/nikola/issues/comments{/number}","contents_url":"https://api.github.com/repos/getnikola/nikola/contents/{+path}","compare_url":"https://api.github.com/repos/getnikola/nikola/compare/{base}...{head}","merges_url":"https://api.github.com/repos/getnikola/nikola/merges","archive_url":"https://api.github.com/repos/getnikola/nikola/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/getnikola/nikola/downloads","issues_url":"https://api.github.com/repos/getnikola/nikola/issues{/number}","pulls_url":"https://api.github.com/repos/getnikola/nikola/pulls{/number}","milestones_url":"https://api.github.com/repos/getnikola/nikola/milestones{/number}","notifications_url":"https://api.github.com/repos/getnikola/nikola/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/getnikola/nikola/labels{/name}","releases_url":"https://api.github.com/repos/getnikola/nikola/releases{/id}","deployments_url":"https://api.github.com/repos/getnikola/nikola/deployments","created_at":"2012-04-14T13:53:22Z","updated_at":"2017-07-01T18:32:43Z","pushed_at":"2017-07-01T19:12:48Z","git_url":"git://github.com/getnikola/nikola.git","ssh_url":"git@github.com:getnikola/nikola.git","clone_url":"https://github.com/getnikola/nikola.git","svn_url":"https://github.com/getnikola/nikola","homepage":"https://getnikola.com/","size":25150,"stargazers_count":1234,"watchers_count":1234,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":305,"mirror_url":null,"open_issues_count":59,"forks":305,"open_issues":59,"watchers":1234,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/getnikola/nikola/pulls/2856"},"html":{"href":"https://github.com/getnikola/nikola/pull/2856"},"issue":{"href":"https://api.github.com/repos/getnikola/nikola/issues/2856"},"comments":{"href":"https://api.github.com/repos/getnikola/nikola/issues/2856/comments"},"review_comments":{"href":"https://api.github.com/repos/getnikola/nikola/pulls/2856/comments"},"review_comment":{"href":"https://api.github.com/repos/getnikola/nikola/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/getnikola/nikola/pulls/2856/commits"},"statuses":{"href":"https://api.github.com/repos/getnikola/nikola/statuses/b8729eaeae0ebfbf1a7610389cae3b93612d74e3"}}}}
{"actor":{"display_login":"Kwpolska"}}