# Path: weechat/common/path.py
# def files_path_join(*args):
#     """Join multiple paths after settings.FILES_ROOT."""
#     return __path_join(settings.FILES_ROOT, *args)
# 
# def media_path_join(*args):
#     """Join multiple paths after settings.MEDIA_ROOT."""
#     return __path_join(settings.MEDIA_ROOT, *args)
# 
# Path: weechat/common/templatetags/version.py
# @register.filter()
# def version_as_int(version):
#     """
#     Return a string with number of version, for example: 0.4.1 gives:
#     262400 (0x00040100).
#     """
#     try:
#         items = version.split('.', 3)
#         value = [0, 0, 0, 0]
#         for i in range(0, 4):
#             if i < len(items):
#                 value[i] = int(re.sub('[^0-9].*', '', items[i]))
#                 if value[i] < 0:
#                     value[i] = 0
#                 elif value[i] > 0xFF:
#                     value[i] = 0xFF
#         return (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3]
#     except:  # noqa: E722  pylint: disable=bare-except
#         return 0
# 
# Path: weechat/dev/models.py
# class Task(models.Model):
#     """A task (a new feature or bug to fix)."""
#     visible = models.BooleanField(default=True)
#     version = models.ForeignKey(Release, on_delete=models.CASCADE)
#     tracker = models.CharField(max_length=64, blank=True)
#     spec = models.CharField(max_length=512, blank=True)
#     status = models.IntegerField(default=0)
#     commits = models.CharField(max_length=1024, blank=True)
#     component = models.CharField(max_length=64, default='core')
#     description = models.CharField(max_length=512)
#     priority = models.IntegerField(default=0)
# 
#     def __str__(self):
#         desc = (self.description
#                 if len(self.description) < 100
#                 else f'{self.description[0:100]}…')
#         version = (f'({self.version.version})' if self.visible
#                    else self.version.version)
#         tracker = self.tracker if self.tracker else '-'
#         return (f'{version}, {tracker}, {self.status}%, {self.component}: '
#                 f'{desc} ({self.priority})')
# 
#     def version_date(self):
#         """Return the date of version.
# 
#         It is prefixed with "≈ " if the date is in the future.
#         """
#         try:
#             if self.version.date > date.today():
#                 return mark_safe(f'&asymp; {localdate(self.version.date)}')
#             return localdate(self.version.date)
#         except:  # noqa: E722  pylint: disable=bare-except
#             return ''
# 
#     def url_tracker(self):
#         """Return the tracker URL using keyword(s) in string."""
#         return tracker_links(self.tracker) or '-'
# 
#     def status_remaining(self):
#         """Return the remaining status as % (100 - status)."""
#         return 100 - self.status
# 
#     def url_commits(self):
#         """Return the URL for commit(s), as HTML."""
#         return commits_links(self.commits)
# 
#     class Meta:
#         ordering = ['-version__date', 'priority']
# 
# Path: weechat/download/models.py
# class Release(models.Model):
#     """A WeeChat release."""
#     version = models.CharField(max_length=64, primary_key=True)
#     description = models.CharField(max_length=64, blank=True)
#     date = models.DateField(blank=True, null=True)
#     security_issues_fixed = models.IntegerField(default=0)
#     securityfix = models.CharField(max_length=256, blank=True)
# 
#     def __str__(self):
#         security_fix = (f', {self.security_issues_fixed} SECURITY FIX'
#                         if self.security_issues_fixed > 0 else '')
#         fixed_in = (f', fix in: {", ".join(self.securityfix.split(","))}'
#                     if self.securityfix else '')
#         return f'{self.version} ({self.date}){security_fix}{fixed_in}'
# 
#     def date_l10n(self):
#         """Return the release date formatted with localized date format."""
#         return localdate(self.date)
# 
#     def security_fixed_versions(self):
#         """Return the list of versions fixing security issues."""
#         return self.securityfix.split(',')
# 
#     @property
#     def is_released(self):
#         """Return True if the version is released."""
#         stable_version = Release.objects.get(version='stable').description
#         stable_version_tuple = version_to_tuple(stable_version)
#         return version_to_tuple(self.version) <= stable_version_tuple
# 
#     class Meta:
#         ordering = ['-date']


import re
from django.core.exceptions import ObjectDoesNotExist
from django.http import HttpResponse
from django.shortcuts import render
from django.utils.translation import gettext, gettext_lazy
from weechat.common.path import files_path_join, media_path_join
from weechat.common.templatetags.version import version_as_int
from weechat.dev.models import Task
from weechat.download.models import Release
        gettext_lazy('Debian/Ubuntu repository signing key '
                     '(format: PGP public key).'),
    ),
    (
        'all',
        gettext_lazy('All non-binary infos '
                     '(one info by line, format: "info:value").'),
    ),
)

BINARY_INFO_KEYS = ('release_signing_key', 'debian_repository_signing_key')

PGP_KEYS = {
    'release_signing': 'A9AB5AB778FA5C3522FD0378F82F4B16DEC408F8',
    'debian_repository_signing': '11E9DE8848F2B65222AA75B8D1820DB22A11534E'
}


def roadmap(request, versions='future'):
    """Page with roadmap for future or all versions."""
    task_list = None
    try:
        if versions == 'future':
            # future versions
            task_list = (Task.objects.all().filter(visible=1)
                         .filter(version__gt=Release.objects.get(
                             version='stable').description)
                         .order_by('version__date', 'priority'))
        else:
            # already released versions

# Path: weechat/common/path.py
# def files_path_join(*args):
#     """Join multiple paths after settings.FILES_ROOT."""
#     return __path_join(settings.FILES_ROOT, *args)
# 
# def media_path_join(*args):
#     """Join multiple paths after settings.MEDIA_ROOT."""
#     return __path_join(settings.MEDIA_ROOT, *args)
# 
# Path: weechat/common/templatetags/version.py
# @register.filter()
# def version_as_int(version):
#     """
#     Return a string with number of version, for example: 0.4.1 gives:
#     262400 (0x00040100).
#     """
#     try:
#         items = version.split('.', 3)
#         value = [0, 0, 0, 0]
#         for i in range(0, 4):
#             if i < len(items):
#                 value[i] = int(re.sub('[^0-9].*', '', items[i]))
#                 if value[i] < 0:
#                     value[i] = 0
#                 elif value[i] > 0xFF:
#                     value[i] = 0xFF
#         return (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3]
#     except:  # noqa: E722  pylint: disable=bare-except
#         return 0
# 
# Path: weechat/dev/models.py
# class Task(models.Model):
#     """A task (a new feature or bug to fix)."""
#     visible = models.BooleanField(default=True)
#     version = models.ForeignKey(Release, on_delete=models.CASCADE)
#     tracker = models.CharField(max_length=64, blank=True)
#     spec = models.CharField(max_length=512, blank=True)
#     status = models.IntegerField(default=0)
#     commits = models.CharField(max_length=1024, blank=True)
#     component = models.CharField(max_length=64, default='core')
#     description = models.CharField(max_length=512)
#     priority = models.IntegerField(default=0)
# 
#     def __str__(self):
#         desc = (self.description
#                 if len(self.description) < 100
#                 else f'{self.description[0:100]}…')
#         version = (f'({self.version.version})' if self.visible
#                    else self.version.version)
#         tracker = self.tracker if self.tracker else '-'
#         return (f'{version}, {tracker}, {self.status}%, {self.component}: '
#                 f'{desc} ({self.priority})')
# 
#     def version_date(self):
#         """Return the date of version.
# 
#         It is prefixed with "≈ " if the date is in the future.
#         """
#         try:
#             if self.version.date > date.today():
#                 return mark_safe(f'&asymp; {localdate(self.version.date)}')
#             return localdate(self.version.date)
#         except:  # noqa: E722  pylint: disable=bare-except
#             return ''
# 
#     def url_tracker(self):
#         """Return the tracker URL using keyword(s) in string."""
#         return tracker_links(self.tracker) or '-'
# 
#     def status_remaining(self):
#         """Return the remaining status as % (100 - status)."""
#         return 100 - self.status
# 
#     def url_commits(self):
#         """Return the URL for commit(s), as HTML."""
#         return commits_links(self.commits)
# 
#     class Meta:
#         ordering = ['-version__date', 'priority']
# 
# Path: weechat/download/models.py
# class Release(models.Model):
#     """A WeeChat release."""
#     version = models.CharField(max_length=64, primary_key=True)
#     description = models.CharField(max_length=64, blank=True)
#     date = models.DateField(blank=True, null=True)
#     security_issues_fixed = models.IntegerField(default=0)
#     securityfix = models.CharField(max_length=256, blank=True)
# 
#     def __str__(self):
#         security_fix = (f', {self.security_issues_fixed} SECURITY FIX'
#                         if self.security_issues_fixed > 0 else '')
#         fixed_in = (f', fix in: {", ".join(self.securityfix.split(","))}'
#                     if self.securityfix else '')
#         return f'{self.version} ({self.date}){security_fix}{fixed_in}'
# 
#     def date_l10n(self):
#         """Return the release date formatted with localized date format."""
#         return localdate(self.date)
# 
#     def security_fixed_versions(self):
#         """Return the list of versions fixing security issues."""
#         return self.securityfix.split(',')
# 
#     @property
#     def is_released(self):
#         """Return True if the version is released."""
#         stable_version = Release.objects.get(version='stable').description
#         stable_version_tuple = version_to_tuple(stable_version)
#         return version_to_tuple(self.version) <= stable_version_tuple
# 
#     class Meta:
#         ordering = ['-date']


# Path: weechat/dev/views.py
import re
from django.core.exceptions import ObjectDoesNotExist
from django.http import HttpResponse
from django.shortcuts import render
from django.utils.translation import gettext, gettext_lazy
from weechat.common.path import files_path_join, media_path_join
from weechat.common.templatetags.version import version_as_int
from weechat.dev.models import Task
from weechat.download.models import Release

        gettext_lazy('Debian/Ubuntu repository signing key '
                     '(format: PGP public key).'),
    ),
    (
        'all',
        gettext_lazy('All non-binary infos '
                     '(one info by line, format: "info:value").'),
    ),
)

BINARY_INFO_KEYS = ('release_signing_key', 'debian_repository_signing_key')

PGP_KEYS = {
    'release_signing': 'A9AB5AB778FA5C3522FD0378F82F4B16DEC408F8',
    'debian_repository_signing': '11E9DE8848F2B65222AA75B8D1820DB22A11534E'
}


def roadmap(request, versions='future'):
    """Page with roadmap for future or all versions."""
    task_list = None
    try:
        if versions == 'future':
            # future versions
            task_list = (Task.objects.all().filter(visible=1)
                         .filter(version__gt=Release.objects.get(
                             version='stable').description)
                         .order_by('version__date', 'priority'))
        else:
            # already released versions

            task_list = (Task.objects.all().filter(visible=1)