We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Using `execfile` for settings is non-ideal
`execfile` does not set nice things like `__file__` when executing a module. This can lead to tracebacks like:

```
Traceback (most recent call last):
  File "/Users/Julian/.virtualenvs/julian/bin/pelican", line 3, in <module>
    main()
  File "/Users/Julian/.virtualenvs/julian/lib/python2.7/site-packages/pelican/__init__.py", line 127, in main
    settings = read_settings(args.settings)
  File "/Users/Julian/.virtualenvs/julian/lib/python2.7/site-packages/pelican/settings.py", line 55, in read_settings
    execfile(filename, tempdict)
  File "settings.py", line 10, in <module>
    THEME = os.path.abspath(os.path.dirname(__file__))
NameError: name '__file__' is not defined
```

I'm not a huge fan of using Python as a configuration format, but if it's going to be used, it'd be nice to have the settings module imported instead of `execfile`d. All the globals in the settings file is going to mean that to do that `import *` is going to be necessary, so I'd love to see a `Settings` object (or a simple `settings = some_dict`) instead, but I'll take what I can get :).

Of course, if these are things that you're open to, I'd be willing to contribute patches.

Cheers.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pelican/settings.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 import os
3 import locale
4 import logging
5 
6 from os.path import isabs
7 
8 
9 logger = logging.getLogger(__name__)
10 
11 
12 DEFAULT_THEME = os.sep.join([os.path.dirname(os.path.abspath(__file__)),
13                               "themes/notmyidea"])
14 _DEFAULT_CONFIG = {'PATH': '.',
15                    'ARTICLE_DIR': '',
16                    'ARTICLE_EXCLUDES': ('pages',),
17                    'PAGE_DIR': 'pages',
18                    'PAGE_EXCLUDES': (),
19                    'THEME': DEFAULT_THEME,
20                    'OUTPUT_PATH': 'output/',
21                    'MARKUP': ('rst', 'md'),
22                    'STATIC_PATHS': ['images', ],
23                    'THEME_STATIC_PATHS': ['static', ],
24                    'FEED_ATOM': 'feeds/all.atom.xml',
25                    'CATEGORY_FEED_ATOM': 'feeds/%s.atom.xml',
26                    'TRANSLATION_FEED': 'feeds/all-%s.atom.xml',
27                    'FEED_MAX_ITEMS': '',
28                    'SITEURL': '',
29                    'SITENAME': 'A Pelican Blog',
30                    'DISPLAY_PAGES_ON_MENU': True,
31                    'PDF_GENERATOR': False,
32                    'DEFAULT_CATEGORY': 'misc',
33                    'DEFAULT_DATE': 'fs',
34                    'WITH_FUTURE_DATES': True,
35                    'CSS_FILE': 'main.css',
36                    'NEWEST_FIRST_ARCHIVES': True,
37                    'REVERSE_CATEGORY_ORDER': False,
38                    'DELETE_OUTPUT_DIRECTORY': False,
39                    'ARTICLE_URL': '{slug}.html',
40                    'ARTICLE_SAVE_AS': '{slug}.html',
41                    'ARTICLE_LANG_URL': '{slug}-{lang}.html',
42                    'ARTICLE_LANG_SAVE_AS': '{slug}-{lang}.html',
43                    'PAGE_URL': 'pages/{slug}.html',
44                    'PAGE_SAVE_AS': 'pages/{slug}.html',
45                    'PAGE_LANG_URL': 'pages/{slug}-{lang}.html',
46                    'PAGE_LANG_SAVE_AS': 'pages/{slug}-{lang}.html',
47                    'CATEGORY_URL': 'category/{slug}.html',
48                    'CATEGORY_SAVE_AS': 'category/{slug}.html',
49                    'TAG_URL': 'tag/{slug}.html',
50                    'TAG_SAVE_AS': 'tag/{slug}.html',
51                    'AUTHOR_URL': u'author/{slug}.html',
52                    'AUTHOR_SAVE_AS': u'author/{slug}.html',
53                    'RELATIVE_URLS': True,
54                    'DEFAULT_LANG': 'en',
55                    'TAG_CLOUD_STEPS': 4,
56                    'TAG_CLOUD_MAX_ITEMS': 100,
57                    'DIRECT_TEMPLATES': ('index', 'tags', 'categories', 'archives'),
58                    'PAGINATED_DIRECT_TEMPLATES': ('index', ),
59                    'PELICAN_CLASS': 'pelican.Pelican',
60                    'DEFAULT_DATE_FORMAT': '%a %d %B %Y',
61                    'DATE_FORMATS': {},
62                    'JINJA_EXTENSIONS': [],
63                    'LOCALE': '',  # default to user locale
64                    'DEFAULT_PAGINATION': False,
65                    'DEFAULT_ORPHANS': 0,
66                    'DEFAULT_METADATA': (),
67                    'FILES_TO_COPY': (),
68                    'DEFAULT_STATUS': 'published',
69                    'ARTICLE_PERMALINK_STRUCTURE': '',
70                    'TYPOGRIFY': False,
71                    'LESS_GENERATOR': False,
72                    'SUMMARY_MAX_LENGTH': 50,
73                    'WEBASSETS': False,
74                    'PLUGINS': [],
75                    }
76 
77 
78 def read_settings(filename=None):
79     if filename:
80         local_settings = get_settings_from_file(filename)
81     else:
82         local_settings = _DEFAULT_CONFIG
83     configured_settings = configure_settings(local_settings, None, filename)
84     return configured_settings
85 
86 
87 def get_settings_from_file(filename, default_settings=None):
88     """Load a Python file into a dictionary.
89     """
90     if default_settings == None:
91         default_settings = _DEFAULT_CONFIG
92     context = default_settings.copy()
93     if filename:
94         tempdict = {}
95         execfile(filename, tempdict)
96         for key in tempdict:
97             if key.isupper():
98                 context[key] = tempdict[key]
99     return context
100 
101 
102 def configure_settings(settings, default_settings=None, filename=None):
103     """Provide optimizations, error checking, and warnings for loaded settings"""
104     if default_settings is None:
105         default_settings = _DEFAULT_CONFIG
106 
107     # Make the paths relative to the settings file
108     if filename:
109         for path in ['PATH', 'OUTPUT_PATH']:
110             if path in settings:
111                 if settings[path] is not None and not isabs(settings[path]):
112                     settings[path] = os.path.abspath(os.path.normpath(
113                         os.path.join(os.path.dirname(filename), settings[path]))
114                     )
115 
116     # if locales is not a list, make it one
117     locales = settings['LOCALE']
118 
119     if isinstance(locales, basestring):
120         locales = [locales]
121 
122     # try to set the different locales, fallback on the default.
123     if not locales:
124         locales = _DEFAULT_CONFIG['LOCALE']
125 
126     for locale_ in locales:
127         try:
128             locale.setlocale(locale.LC_ALL, locale_)
129             break  # break if it is successfull
130         except locale.Error:
131             pass
132     else:
133         logger.warn("LOCALE option doesn't contain a correct value")
134 
135     if ('SITEURL' in settings):
136         # If SITEURL has a trailing slash, remove it and provide a warning
137         siteurl = settings['SITEURL']
138         if (siteurl.endswith('/')):
139             settings['SITEURL'] = siteurl[:-1]
140             logger.warn("Removed extraneous trailing slash from SITEURL.")
141         # If SITEURL is defined but FEED_DOMAIN isn't, set FEED_DOMAIN = SITEURL
142         if not 'FEED_DOMAIN' in settings:
143             settings['FEED_DOMAIN'] = settings['SITEURL']
144 
145     # Warn if feeds are generated with both SITEURL & FEED_DOMAIN undefined
146     if (('FEED_ATOM' in settings) or ('FEED_RSS' in settings)) and (not 'FEED_DOMAIN' in settings):
147         logger.warn("Since feed URLs should always be absolute, you should specify "
148                  "FEED_DOMAIN in your settings. (e.g., 'FEED_DOMAIN = "
149                  "http://www.example.com')")
150 
151     if not 'TIMEZONE' in settings:
152         logger.warn("No timezone information specified in the settings. Assuming"
153                  " your timezone is UTC for feed generation. Check "
154                  "http://docs.notmyidea.org/alexis/pelican/settings.html#timezone "
155                  "for more information")
156 
157     if 'WEBASSETS' in settings and settings['WEBASSETS'] is not False:
158         try:
159             from webassets.ext.jinja2 import AssetsExtension
160             settings['JINJA_EXTENSIONS'].append(AssetsExtension)
161         except ImportError:
162             logger.warn("You must install the webassets module to use WEBASSETS.")
163             settings['WEBASSETS'] = False
164 
165     return settings
166
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pelican/settings.py b/pelican/settings.py
--- a/pelican/settings.py
+++ b/pelican/settings.py
@@ -1,4 +1,6 @@
 # -*- coding: utf-8 -*-
+import imp
+import inspect
 import os
 import locale
 import logging
@@ -84,21 +86,31 @@
     return configured_settings
 
 
-def get_settings_from_file(filename, default_settings=None):
-    """Load a Python file into a dictionary.
+def get_settings_from_module(module=None, default_settings=_DEFAULT_CONFIG):
     """
-    if default_settings == None:
-        default_settings = _DEFAULT_CONFIG
+    Load settings from a module, returning a dict.
+
+    """
+
     context = default_settings.copy()
-    if filename:
-        tempdict = {}
-        execfile(filename, tempdict)
-        for key in tempdict:
-            if key.isupper():
-                context[key] = tempdict[key]
+    if module is not None:
+         context.update(
+             (k, v) for k, v in inspect.getmembers(module) if k.isupper()
+         )
     return context
 
 
+def get_settings_from_file(filename, default_settings=_DEFAULT_CONFIG):
+    """
+    Load settings from a file path, returning a dict.
+
+    """
+
+    name = os.path.basename(filename).rpartition(".")[0]
+    module = imp.load_source(name, filename)
+    return get_settings_from_module(module, default_settings=default_settings)
+
+
 def configure_settings(settings, default_settings=None, filename=None):
     """Provide optimizations, error checking, and warnings for loaded settings"""
     if default_settings is None:

{"golden_diff": "diff --git a/pelican/settings.py b/pelican/settings.py\n--- a/pelican/settings.py\n+++ b/pelican/settings.py\n@@ -1,4 +1,6 @@\n # -*- coding: utf-8 -*-\n+import imp\n+import inspect\n import os\n import locale\n import logging\n@@ -84,21 +86,31 @@\n     return configured_settings\n \n \n-def get_settings_from_file(filename, default_settings=None):\n-    \"\"\"Load a Python file into a dictionary.\n+def get_settings_from_module(module=None, default_settings=_DEFAULT_CONFIG):\n     \"\"\"\n-    if default_settings == None:\n-        default_settings = _DEFAULT_CONFIG\n+    Load settings from a module, returning a dict.\n+\n+    \"\"\"\n+\n     context = default_settings.copy()\n-    if filename:\n-        tempdict = {}\n-        execfile(filename, tempdict)\n-        for key in tempdict:\n-            if key.isupper():\n-                context[key] = tempdict[key]\n+    if module is not None:\n+         context.update(\n+             (k, v) for k, v in inspect.getmembers(module) if k.isupper()\n+         )\n     return context\n \n \n+def get_settings_from_file(filename, default_settings=_DEFAULT_CONFIG):\n+    \"\"\"\n+    Load settings from a file path, returning a dict.\n+\n+    \"\"\"\n+\n+    name = os.path.basename(filename).rpartition(\".\")[0]\n+    module = imp.load_source(name, filename)\n+    return get_settings_from_module(module, default_settings=default_settings)\n+\n+\n def configure_settings(settings, default_settings=None, filename=None):\n     \"\"\"Provide optimizations, error checking, and warnings for loaded settings\"\"\"\n     if default_settings is None:\n", "issue": "Using `execfile` for settings is non-ideal\n`execfile` does not set nice things like `__file__` when executing a module. This can lead to tracebacks like:\n\n```\nTraceback (most recent call last):\n  File \"/Users/Julian/.virtualenvs/julian/bin/pelican\", line 3, in <module>\n    main()\n  File \"/Users/Julian/.virtualenvs/julian/lib/python2.7/site-packages/pelican/__init__.py\", line 127, in main\n    settings = read_settings(args.settings)\n  File \"/Users/Julian/.virtualenvs/julian/lib/python2.7/site-packages/pelican/settings.py\", line 55, in read_settings\n    execfile(filename, tempdict)\n  File \"settings.py\", line 10, in <module>\n    THEME = os.path.abspath(os.path.dirname(__file__))\nNameError: name '__file__' is not defined\n```\n\nI'm not a huge fan of using Python as a configuration format, but if it's going to be used, it'd be nice to have the settings module imported instead of `execfile`d. All the globals in the settings file is going to mean that to do that `import *` is going to be necessary, so I'd love to see a `Settings` object (or a simple `settings = some_dict`) instead, but I'll take what I can get :).\n\nOf course, if these are things that you're open to, I'd be willing to contribute patches.\n\nCheers.\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\nimport os\nimport locale\nimport logging\n\nfrom os.path import isabs\n\n\nlogger = logging.getLogger(__name__)\n\n\nDEFAULT_THEME = os.sep.join([os.path.dirname(os.path.abspath(__file__)),\n                              \"themes/notmyidea\"])\n_DEFAULT_CONFIG = {'PATH': '.',\n                   'ARTICLE_DIR': '',\n                   'ARTICLE_EXCLUDES': ('pages',),\n                   'PAGE_DIR': 'pages',\n                   'PAGE_EXCLUDES': (),\n                   'THEME': DEFAULT_THEME,\n                   'OUTPUT_PATH': 'output/',\n                   'MARKUP': ('rst', 'md'),\n                   'STATIC_PATHS': ['images', ],\n                   'THEME_STATIC_PATHS': ['static', ],\n                   'FEED_ATOM': 'feeds/all.atom.xml',\n                   'CATEGORY_FEED_ATOM': 'feeds/%s.atom.xml',\n                   'TRANSLATION_FEED': 'feeds/all-%s.atom.xml',\n                   'FEED_MAX_ITEMS': '',\n                   'SITEURL': '',\n                   'SITENAME': 'A Pelican Blog',\n                   'DISPLAY_PAGES_ON_MENU': True,\n                   'PDF_GENERATOR': False,\n                   'DEFAULT_CATEGORY': 'misc',\n                   'DEFAULT_DATE': 'fs',\n                   'WITH_FUTURE_DATES': True,\n                   'CSS_FILE': 'main.css',\n                   'NEWEST_FIRST_ARCHIVES': True,\n                   'REVERSE_CATEGORY_ORDER': False,\n                   'DELETE_OUTPUT_DIRECTORY': False,\n                   'ARTICLE_URL': '{slug}.html',\n                   'ARTICLE_SAVE_AS': '{slug}.html',\n                   'ARTICLE_LANG_URL': '{slug}-{lang}.html',\n                   'ARTICLE_LANG_SAVE_AS': '{slug}-{lang}.html',\n                   'PAGE_URL': 'pages/{slug}.html',\n                   'PAGE_SAVE_AS': 'pages/{slug}.html',\n                   'PAGE_LANG_URL': 'pages/{slug}-{lang}.html',\n                   'PAGE_LANG_SAVE_AS': 'pages/{slug}-{lang}.html',\n                   'CATEGORY_URL': 'category/{slug}.html',\n                   'CATEGORY_SAVE_AS': 'category/{slug}.html',\n                   'TAG_URL': 'tag/{slug}.html',\n                   'TAG_SAVE_AS': 'tag/{slug}.html',\n                   'AUTHOR_URL': u'author/{slug}.html',\n                   'AUTHOR_SAVE_AS': u'author/{slug}.html',\n                   'RELATIVE_URLS': True,\n                   'DEFAULT_LANG': 'en',\n                   'TAG_CLOUD_STEPS': 4,\n                   'TAG_CLOUD_MAX_ITEMS': 100,\n                   'DIRECT_TEMPLATES': ('index', 'tags', 'categories', 'archives'),\n                   'PAGINATED_DIRECT_TEMPLATES': ('index', ),\n                   'PELICAN_CLASS': 'pelican.Pelican',\n                   'DEFAULT_DATE_FORMAT': '%a %d %B %Y',\n                   'DATE_FORMATS': {},\n                   'JINJA_EXTENSIONS': [],\n                   'LOCALE': '',  # default to user locale\n                   'DEFAULT_PAGINATION': False,\n                   'DEFAULT_ORPHANS': 0,\n                   'DEFAULT_METADATA': (),\n                   'FILES_TO_COPY': (),\n                   'DEFAULT_STATUS': 'published',\n                   'ARTICLE_PERMALINK_STRUCTURE': '',\n                   'TYPOGRIFY': False,\n                   'LESS_GENERATOR': False,\n                   'SUMMARY_MAX_LENGTH': 50,\n                   'WEBASSETS': False,\n                   'PLUGINS': [],\n                   }\n\n\ndef read_settings(filename=None):\n    if filename:\n        local_settings = get_settings_from_file(filename)\n    else:\n        local_settings = _DEFAULT_CONFIG\n    configured_settings = configure_settings(local_settings, None, filename)\n    return configured_settings\n\n\ndef get_settings_from_file(filename, default_settings=None):\n    \"\"\"Load a Python file into a dictionary.\n    \"\"\"\n    if default_settings == None:\n        default_settings = _DEFAULT_CONFIG\n    context = default_settings.copy()\n    if filename:\n        tempdict = {}\n        execfile(filename, tempdict)\n        for key in tempdict:\n            if key.isupper():\n                context[key] = tempdict[key]\n    return context\n\n\ndef configure_settings(settings, default_settings=None, filename=None):\n    \"\"\"Provide optimizations, error checking, and warnings for loaded settings\"\"\"\n    if default_settings is None:\n        default_settings = _DEFAULT_CONFIG\n\n    # Make the paths relative to the settings file\n    if filename:\n        for path in ['PATH', 'OUTPUT_PATH']:\n            if path in settings:\n                if settings[path] is not None and not isabs(settings[path]):\n                    settings[path] = os.path.abspath(os.path.normpath(\n                        os.path.join(os.path.dirname(filename), settings[path]))\n                    )\n\n    # if locales is not a list, make it one\n    locales = settings['LOCALE']\n\n    if isinstance(locales, basestring):\n        locales = [locales]\n\n    # try to set the different locales, fallback on the default.\n    if not locales:\n        locales = _DEFAULT_CONFIG['LOCALE']\n\n    for locale_ in locales:\n        try:\n            locale.setlocale(locale.LC_ALL, locale_)\n            break  # break if it is successfull\n        except locale.Error:\n            pass\n    else:\n        logger.warn(\"LOCALE option doesn't contain a correct value\")\n\n    if ('SITEURL' in settings):\n        # If SITEURL has a trailing slash, remove it and provide a warning\n        siteurl = settings['SITEURL']\n        if (siteurl.endswith('/')):\n            settings['SITEURL'] = siteurl[:-1]\n            logger.warn(\"Removed extraneous trailing slash from SITEURL.\")\n        # If SITEURL is defined but FEED_DOMAIN isn't, set FEED_DOMAIN = SITEURL\n        if not 'FEED_DOMAIN' in settings:\n            settings['FEED_DOMAIN'] = settings['SITEURL']\n\n    # Warn if feeds are generated with both SITEURL & FEED_DOMAIN undefined\n    if (('FEED_ATOM' in settings) or ('FEED_RSS' in settings)) and (not 'FEED_DOMAIN' in settings):\n        logger.warn(\"Since feed URLs should always be absolute, you should specify \"\n                 \"FEED_DOMAIN in your settings. (e.g., 'FEED_DOMAIN = \"\n                 \"http://www.example.com')\")\n\n    if not 'TIMEZONE' in settings:\n        logger.warn(\"No timezone information specified in the settings. Assuming\"\n                 \" your timezone is UTC for feed generation. Check \"\n                 \"http://docs.notmyidea.org/alexis/pelican/settings.html#timezone \"\n                 \"for more information\")\n\n    if 'WEBASSETS' in settings and settings['WEBASSETS'] is not False:\n        try:\n            from webassets.ext.jinja2 import AssetsExtension\n            settings['JINJA_EXTENSIONS'].append(AssetsExtension)\n        except ImportError:\n            logger.warn(\"You must install the webassets module to use WEBASSETS.\")\n            settings['WEBASSETS'] = False\n\n    return settings\n", "path": "pelican/settings.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\nimport imp\nimport inspect\nimport os\nimport locale\nimport logging\n\nfrom os.path import isabs\n\n\nlogger = logging.getLogger(__name__)\n\n\nDEFAULT_THEME = os.sep.join([os.path.dirname(os.path.abspath(__file__)),\n                              \"themes/notmyidea\"])\n_DEFAULT_CONFIG = {'PATH': '.',\n                   'ARTICLE_DIR': '',\n                   'ARTICLE_EXCLUDES': ('pages',),\n                   'PAGE_DIR': 'pages',\n                   'PAGE_EXCLUDES': (),\n                   'THEME': DEFAULT_THEME,\n                   'OUTPUT_PATH': 'output/',\n                   'MARKUP': ('rst', 'md'),\n                   'STATIC_PATHS': ['images', ],\n                   'THEME_STATIC_PATHS': ['static', ],\n                   'FEED_ATOM': 'feeds/all.atom.xml',\n                   'CATEGORY_FEED_ATOM': 'feeds/%s.atom.xml',\n                   'TRANSLATION_FEED': 'feeds/all-%s.atom.xml',\n                   'FEED_MAX_ITEMS': '',\n                   'SITEURL': '',\n                   'SITENAME': 'A Pelican Blog',\n                   'DISPLAY_PAGES_ON_MENU': True,\n                   'PDF_GENERATOR': False,\n                   'DEFAULT_CATEGORY': 'misc',\n                   'DEFAULT_DATE': 'fs',\n                   'WITH_FUTURE_DATES': True,\n                   'CSS_FILE': 'main.css',\n                   'NEWEST_FIRST_ARCHIVES': True,\n                   'REVERSE_CATEGORY_ORDER': False,\n                   'DELETE_OUTPUT_DIRECTORY': False,\n                   'ARTICLE_URL': '{slug}.html',\n                   'ARTICLE_SAVE_AS': '{slug}.html',\n                   'ARTICLE_LANG_URL': '{slug}-{lang}.html',\n                   'ARTICLE_LANG_SAVE_AS': '{slug}-{lang}.html',\n                   'PAGE_URL': 'pages/{slug}.html',\n                   'PAGE_SAVE_AS': 'pages/{slug}.html',\n                   'PAGE_LANG_URL': 'pages/{slug}-{lang}.html',\n                   'PAGE_LANG_SAVE_AS': 'pages/{slug}-{lang}.html',\n                   'CATEGORY_URL': 'category/{slug}.html',\n                   'CATEGORY_SAVE_AS': 'category/{slug}.html',\n                   'TAG_URL': 'tag/{slug}.html',\n                   'TAG_SAVE_AS': 'tag/{slug}.html',\n                   'AUTHOR_URL': u'author/{slug}.html',\n                   'AUTHOR_SAVE_AS': u'author/{slug}.html',\n                   'RELATIVE_URLS': True,\n                   'DEFAULT_LANG': 'en',\n                   'TAG_CLOUD_STEPS': 4,\n                   'TAG_CLOUD_MAX_ITEMS': 100,\n                   'DIRECT_TEMPLATES': ('index', 'tags', 'categories', 'archives'),\n                   'PAGINATED_DIRECT_TEMPLATES': ('index', ),\n                   'PELICAN_CLASS': 'pelican.Pelican',\n                   'DEFAULT_DATE_FORMAT': '%a %d %B %Y',\n                   'DATE_FORMATS': {},\n                   'JINJA_EXTENSIONS': [],\n                   'LOCALE': '',  # default to user locale\n                   'DEFAULT_PAGINATION': False,\n                   'DEFAULT_ORPHANS': 0,\n                   'DEFAULT_METADATA': (),\n                   'FILES_TO_COPY': (),\n                   'DEFAULT_STATUS': 'published',\n                   'ARTICLE_PERMALINK_STRUCTURE': '',\n                   'TYPOGRIFY': False,\n                   'LESS_GENERATOR': False,\n                   'SUMMARY_MAX_LENGTH': 50,\n                   'WEBASSETS': False,\n                   'PLUGINS': [],\n                   }\n\n\ndef read_settings(filename=None):\n    if filename:\n        local_settings = get_settings_from_file(filename)\n    else:\n        local_settings = _DEFAULT_CONFIG\n    configured_settings = configure_settings(local_settings, None, filename)\n    return configured_settings\n\n\ndef get_settings_from_module(module=None, default_settings=_DEFAULT_CONFIG):\n    \"\"\"\n    Load settings from a module, returning a dict.\n\n    \"\"\"\n\n    context = default_settings.copy()\n    if module is not None:\n         context.update(\n             (k, v) for k, v in inspect.getmembers(module) if k.isupper()\n         )\n    return context\n\n\ndef get_settings_from_file(filename, default_settings=_DEFAULT_CONFIG):\n    \"\"\"\n    Load settings from a file path, returning a dict.\n\n    \"\"\"\n\n    name = os.path.basename(filename).rpartition(\".\")[0]\n    module = imp.load_source(name, filename)\n    return get_settings_from_module(module, default_settings=default_settings)\n\n\ndef configure_settings(settings, default_settings=None, filename=None):\n    \"\"\"Provide optimizations, error checking, and warnings for loaded settings\"\"\"\n    if default_settings is None:\n        default_settings = _DEFAULT_CONFIG\n\n    # Make the paths relative to the settings file\n    if filename:\n        for path in ['PATH', 'OUTPUT_PATH']:\n            if path in settings:\n                if settings[path] is not None and not isabs(settings[path]):\n                    settings[path] = os.path.abspath(os.path.normpath(\n                        os.path.join(os.path.dirname(filename), settings[path]))\n                    )\n\n    # if locales is not a list, make it one\n    locales = settings['LOCALE']\n\n    if isinstance(locales, basestring):\n        locales = [locales]\n\n    # try to set the different locales, fallback on the default.\n    if not locales:\n        locales = _DEFAULT_CONFIG['LOCALE']\n\n    for locale_ in locales:\n        try:\n            locale.setlocale(locale.LC_ALL, locale_)\n            break  # break if it is successfull\n        except locale.Error:\n            pass\n    else:\n        logger.warn(\"LOCALE option doesn't contain a correct value\")\n\n    if ('SITEURL' in settings):\n        # If SITEURL has a trailing slash, remove it and provide a warning\n        siteurl = settings['SITEURL']\n        if (siteurl.endswith('/')):\n            settings['SITEURL'] = siteurl[:-1]\n            logger.warn(\"Removed extraneous trailing slash from SITEURL.\")\n        # If SITEURL is defined but FEED_DOMAIN isn't, set FEED_DOMAIN = SITEURL\n        if not 'FEED_DOMAIN' in settings:\n            settings['FEED_DOMAIN'] = settings['SITEURL']\n\n    # Warn if feeds are generated with both SITEURL & FEED_DOMAIN undefined\n    if (('FEED_ATOM' in settings) or ('FEED_RSS' in settings)) and (not 'FEED_DOMAIN' in settings):\n        logger.warn(\"Since feed URLs should always be absolute, you should specify \"\n                 \"FEED_DOMAIN in your settings. (e.g., 'FEED_DOMAIN = \"\n                 \"http://www.example.com')\")\n\n    if not 'TIMEZONE' in settings:\n        logger.warn(\"No timezone information specified in the settings. Assuming\"\n                 \" your timezone is UTC for feed generation. Check \"\n                 \"http://docs.notmyidea.org/alexis/pelican/settings.html#timezone \"\n                 \"for more information\")\n\n    if 'WEBASSETS' in settings and settings['WEBASSETS'] is not False:\n        try:\n            from webassets.ext.jinja2 import AssetsExtension\n            settings['JINJA_EXTENSIONS'].append(AssetsExtension)\n        except ImportError:\n            logger.warn(\"You must install the webassets module to use WEBASSETS.\")\n            settings['WEBASSETS'] = False\n\n    return settings\n", "path": "pelican/settings.py"}]}