Repository: getnikola/nikola

Issue:
new_port fails with AttributeError (locale.nl_langinfo missing)
Just installed Nikola, your handbook claims that you support Windows. However you use locale.nl_langinfo which is not available there, resulting in crashes.

```
> python -m nikola new_post
[2014-06-01T21:13:50Z] WARNING: Nikola: In order to USE_BUNDLES, you must install the "webassets" Python package.
[2014-06-01T21:13:50Z] WARNING: Nikola: Setting USE_BUNDLES to False.
Creating New Post
-----------------

Title: This is starting to feel like home
Scanning posts....done!
Traceback (most recent call last):
  File "C:\Python2.7.6\lib\site-packages\doit\doit_cmd.py", line 120, in run
    return command.parse_execute(args)
  File "C:\Python2.7.6\lib\site-packages\doit\cmd_base.py", line 78, in parse_execute
    return self.execute(params, args)
  File "C:\Python2.7.6\lib\site-packages\nikola\plugin_categories.py", line 98, in execute
    self._execute(options, args)
  File "C:\Python2.7.6\lib\site-packages\nikola\plugins\command\new_post.py", line 290, in _execute
    date = get_date(schedule, rule, last_date, self.site.tzinfo, self.site.config['FORCE_ISO8601'])
  File "C:\Python2.7.6\lib\site-packages\nikola\plugins\command\new_post.py", line 138, in get_date
    locale.nl_langinfo(locale.D_FMT),
AttributeError: 'module' object has no attribute 'nl_langinfo'
```

Is Windows actually supported (i.e. tested) or should I move on to another website generator? I know docs can easily become inaccurate :)



Discussion:
The situation is
- Nikola around version 6.3 was working right in Windows, tests passing and all.
- core developers and most contributors use Linux
- Continuous Integration in Travis don't support test runs in Windows (albeit it is supposed to come at some time)
- So some incompatibilities had slipped into the codebase between 6.4 and 7.0

About the bug:

Module locale has no nl_langinfo in python 2.7 and 3.3 in Windows
The python docs for locale in 2.7 and 3.3 tells :
"""
[nl_langinfo] ... This function is not available on all systems, and the set of possible options might also vary across platforms. 
"""

See also: #1284.  So, we’re back to forcing a date format on our users for the next release.

@remram44, temporary workaround: set `FORCE_ISO8601 = True` in your config.

@Kwpolska Got the same bug, and the workaround results in this:

```
Creating New Post
-----------------

Title: Test Post
Scanning posts....done!
Traceback (most recent call last):
  File "C:\Python34\lib\site-packages\doit\doit_cmd.py", line 120, in run
    return command.parse_execute(args)
  File "C:\Python34\lib\site-packages\doit\cmd_base.py", line 78, in parse_execute
    return self.execute(params, args)
  File "C:\Python34\lib\site-packages\nikola\plugin_categories.py", line 98, in execute
    self._execute(options, args)
  File "C:\Python34\lib\site-packages\nikola\plugins\command\new_post.py", line 290, in _execute
    date = get_date(schedule, rule, last_date, self.site.tzinfo, self.site.config['FORCE_ISO8601'])
  File "C:\Python34\lib\site-packages\nikola\plugins\command\new_post.py", line 131, in get_date
    return date.strftime('%Y-%m-%dT%T') + tz_str
ValueError: Invalid format string
```

I changed the python file to `return date.strftime("%Y-%m-%d %H:%M:%S") + tz_str` and it works now.

Oh, that’s broken, too.  Thanks for the report, @ishamf!  Will fix it soon.

What if we delegate date-time to some library that have it's own databases, meaning it will not link with some semi-ramdom implementation of a C library ?

Looking in pypi and the web two possible candidates are

#### Babel

Pure python, includes database from CLDR (Common Locale Data Repository) .
It does more than dates, but less that is needed to, in a long term, drop the 'install OS locales for each languaje desired"
Size: 3MB
Last release: 2013 07
link to date and time  doc's section: http://babel.pocoo.org/docs/api/dates/

#### PyICU

Python bindings to the ICU library , http://site.icu-project.org/ , includes its own databases.

Not pure python, I suspect will be not pip friendly in unix-like systems (installation mentions to adjust some path, probably it would be better to install from a distro package manager)

Interesting because long term it could handle all the localization needs for Nikola, without need to install OS locale support for extra languajes. It also provides  conversion between posix locale names and windows locale names.

Size: 12MB the windows binaries + bindings

Also: current PyICU mantainer is very responsive, I asked for certain function not present in the binding at in a few hours was added to the svn repo. 

#### So what ?

I think pyICU is a bit heavy-weight just now, at least for unix-like systems.
But Babel seems doable in the near term.

I can give it a try to Babel if Nikola honchos think is an acceptable dependency.

A question: in new_post.py , function get_date(), do we need to mimic **exactly** the current  output format ? 

@ccanepa We don’t need to mimic any previous format.  It just has to be usable by everyone (including `dateutil.parser` — the default English one isn’t, for instance).  We can just do one, human-friendly format for everyone.  Like ISO 8601, for instance.

About the other things we do with locales, we might try with Babel, if it works out for Nikola’s needs…


Resolving patch:
diff --git a/nikola/plugins/command/new_post.py b/nikola/plugins/command/new_post.py
--- a/nikola/plugins/command/new_post.py
+++ b/nikola/plugins/command/new_post.py
@@ -27,7 +27,6 @@
 from __future__ import unicode_literals, print_function
 import codecs
 import datetime
-import locale
 import os
 import sys
 import subprocess
@@ -129,16 +128,13 @@ def get_date(schedule=False, rule=None, last_date=None, tz=None, iso8601=False):
     offset_min = offset_sec % 3600
     if iso8601:
         tz_str = '{0:+03d}:{1:02d}'.format(offset_hrs, offset_min // 60)
-        return date.strftime('%Y-%m-%dT%T') + tz_str
     else:
         if offset:
             tz_str = ' UTC{0:+03d}:{1:02d}'.format(offset_hrs, offset_min // 60)
         else:
             tz_str = ' UTC'
-        return date.strftime('{0} {1}'.format(
-            locale.nl_langinfo(locale.D_FMT),
-            locale.nl_langinfo(locale.T_FMT),
-        )) + tz_str
+
+    return date.strftime('%Y-%m-%d %H:%M:%S') + tz_str
 
 
 class CommandNewPost(Command):


Test patch:
diff --git a/tests/test_scheduling.py b/tests/test_scheduling.py
--- a/tests/test_scheduling.py
+++ b/tests/test_scheduling.py
@@ -46,9 +46,7 @@ def tearDown(cls):
     def test_get_date(self):
         from nikola.plugins.command.new_post import get_date
 
-        # This is now locale-dependent, so do it here, where
-        # locale is set.
-        FMT = '{0} {1} %Z'.format(
+        FMT = '%Y-%m-%d %H:%M:%S %Z'.format(
             locale.nl_langinfo(locale.D_FMT),
             locale.nl_langinfo(locale.T_FMT),
         )