<commit_before># -*- coding: utf-8 -*-
"""Module to determine the pywikibot version (tag, revision and date)."""
#
# (C) Merlijn 'valhallasw' <NAME>, 2007-2014
# (C) xqt, 2010-2016
# (C) Pywikibot team, 2007-2016
#
# Distributed under the terms of the MIT license.
#
from __future__ import absolute_import, unicode_literals

import codecs
import datetime
import json
import os
import socket
import subprocess
import sys
import time
import xml.dom.minidom

from distutils import log
from distutils.sysconfig import get_python_lib
from io import BytesIO
from warnings import warn

try:
    from setuptools import svn_utils
except ImportError:
    try:
        from setuptools_svn import svn_utils
    except ImportError as e:
        svn_utils = e

import pywikibot

from pywikibot import config2 as config
from pywikibot.tools import deprecated, PY2, PYTHON_VERSION

if not PY2:
    basestring = (str, )

cache = None
_logger = 'version'


class ParseError(Exception):

    """Parsing went wrong."""


def _get_program_dir():
    _program_dir = os.path.normpath(os.path.split(os.path.dirname(__file__))[0])
    return _program_dir


def get_toolforge_hostname():
    """Get hostname of the current Toolforge host.

    @return: The hostname of the currently running host,
             if it is in Wikimedia Toolforge; otherwise return None.
    @rtype: str or None
    """
    if socket.getfqdn().endswith('.tools.eqiad.wmflabs'):
        return socket.gethostname()
    return None


def getversion(online=True):
    """Return a pywikibot version string.

    @param online: (optional) Include information obtained online
    """
    data = dict(getversiondict())  # copy dict to prevent changes in 'cache'
    data['cmp_ver'] = 'n/a'

    if online:
        try:
            hsh2 = getversion_onlinerepo()
            hsh1 = data['hsh']
            data['cmp_ver'] = 'OUTDATED' if hsh1 != hsh2 else 'ok'
        except Exception:
            pass

    data['hsh'] = data['hsh'][:7]  # make short hash from full hash
    return '%(tag)s (%(hsh)s, %(rev)s, %(date)s, %(cmp_ver)s)' % data


def getversiondict():
    """Get version info for the package.

    @return:
        - tag (name for the repository),
        - rev (current revision identifier),
        - date (date of current revision),
        - hash (git hash for the current revision)
    @rtype: C{dict} of four C{str}
    """
    global cache
    if cache:
        return cache

    _program_dir = _get_program_dir()
    exceptions = {}

    for vcs_func in (getversion_git,
                     getversion_svn_setuptools,
                     getversion_svn,
                     getversion_nightly,
                     getversion_package):
        try:
            (tag, rev, date, hsh) = vcs_func(_program_dir)<commit_msg>pywikibot.version.getversion: Display UNKNOWN status when there is no hash<commit_after># -*- coding: utf-8 -*-
"""Module to determine the pywikibot version (tag, revision and date)."""
#
# (C) Merlijn 'valhallasw' <NAME>, 2007-2014
# (C) xqt, 2010-2016
# (C) Pywikibot team, 2007-2016
#
# Distributed under the terms of the MIT license.
#
from __future__ import absolute_import, unicode_literals

import codecs
import datetime
import json
import os
import socket
import subprocess
import sys
import time
import xml.dom.minidom

from distutils import log
from distutils.sysconfig import get_python_lib
from io import BytesIO
from warnings import warn

try:
    from setuptools import svn_utils
except ImportError:
    try:
        from setuptools_svn import svn_utils
    except ImportError as e:
        svn_utils = e

import pywikibot

from pywikibot import config2 as config
from pywikibot.tools import deprecated, PY2, PYTHON_VERSION

if not PY2:
    basestring = (str, )

cache = None
_logger = 'version'


class ParseError(Exception):

    """Parsing went wrong."""


def _get_program_dir():
    _program_dir = os.path.normpath(os.path.split(os.path.dirname(__file__))[0])
    return _program_dir


def get_toolforge_hostname():
    """Get hostname of the current Toolforge host.

    @return: The hostname of the currently running host,
             if it is in Wikimedia Toolforge; otherwise return None.
    @rtype: str or None
    """
    if socket.getfqdn().endswith('.tools.eqiad.wmflabs'):
        return socket.gethostname()
    return None


def getversion(online=True):
    """Return a pywikibot version string.

    @param online: (optional) Include information obtained online
    """
    data = dict(getversiondict())  # copy dict to prevent changes in 'cache'
    data['cmp_ver'] = 'n/a'

    if online:
        try:
            hsh2 = getversion_onlinerepo()
            hsh1 = data['hsh']
            data['cmp_ver'] = 'UNKNOWN' if not hsh1 else (
                'OUTDATED' if hsh1 != hsh2 else 'ok')
        except Exception:
            pass

    data['hsh'] = data['hsh'][:7]  # make short hash from full hash
    return '%(tag)s (%(hsh)s, %(rev)s, %(date)s, %(cmp_ver)s)' % data


def getversiondict():
    """Get version info for the package.

    @return:
        - tag (name for the repository),
        - rev (current revision identifier),
        - date (date of current revision),
        - hash (git hash for the current revision)
    @rtype: C{dict} of four C{str}
    """
    global cache
    if cache:
        return cache

    _program_dir = _get_program_dir()
    exceptions = {}

    for vcs_func in (getversion_git,
                     getversion_svn_setuptools,
                     getversion_svn,
                     getversion_nightly,
                     getversion_package):
        try:
            (tag, rev, date, hsh) = vcs_func(_program_dir)
{'fraction_non_alphanumeric': 0.0969217238346526, 'fraction_numerical': 0.012137203166226913, 'mean_word_length': 2.76805831676607, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4399578', 'n_tokens_mistral': 1841, 'n_tokens_neox': 1750, 'n_words': 562}