* merge migrations

* revert ocs change

* add migrations

* initialize english changelogs
This commit is contained in:
Bernhard Posselt 2016-10-05 17:49:40 +02:00 коммит произвёл GitHub
Родитель 3bd46b131b
Коммит b5e81ae899
14 изменённых файлов: 97 добавлений и 18 удалений

Просмотреть файл

@ -481,6 +481,8 @@ The version has to be equal to the version in your info.xml. If the parser can't
The changelog for nightlies will be taken from the **## [Unreleased]** block
Changelogs can be translated as well. To add a changelog for a specific translation, use **CHANGELOG.code.md**, e.g.: **CHANGELOG.fr.md**
.. _info-schema:
Schema Integration

Просмотреть файл

@ -301,7 +301,11 @@ This route will return all releases to display inside Nextcloud's apps admin are
],
"lastModified": "2016-06-25T16:49:25.319425Z",
"signature": "909377e1a695bbaa415c10ae087ae1cc48e88066d20a5a7a8beed149e9fad3d5",
"changelog": "* **Bugfix**: Pad API last modified timestamp to milliseconds in updated items API to return only new items. API users however need to re-sync their complete contents, #24\n* **Bugfix**: Do not pad milliseconds for non millisecond timestamps in API"
"translations": {
"en": {
"changelog": "* **Bugfix**: Pad API last modified timestamp to milliseconds in updated items API to return only new items. API users however need to re-sync their complete contents, #24\n* **Bugfix**: Do not pad milliseconds for non millisecond timestamps in API"
}
}
}
],
"screenshots": [

Просмотреть файл

@ -13,7 +13,7 @@ class PhpExtensionDependencyInline(admin.TabularInline):
extra = 1
class AppReleaseAdmin(admin.ModelAdmin):
class AppReleaseAdmin(TranslatableAdmin):
inlines = (DatabaseDependencyInline, PhpExtensionDependencyInline)

Просмотреть файл

@ -35,7 +35,7 @@ def apps(request):
if category is not None:
apps = filter(lambda app: in_category(app, category), apps)
return render_to_response('api/v0/apps.xml', {
'apps': apps,
'apps': list(apps),
'request': request,
'version': version
}, content_type='application/xml')

Просмотреть файл

@ -12,3 +12,4 @@ class ReleaseConfig:
self.info_schema = read_relative_file(__file__, 'info.xsd')
self.info_xslt = read_relative_file(__file__, 'info.xslt')
self.pre_info_xslt = read_relative_file(__file__, 'pre-info.xslt')
self.languages = settings.LANGUAGES

Просмотреть файл

@ -161,7 +161,8 @@ class AppReleaseImporter(Importer):
license_importer: LicenseImporter,
shell_command_importer: ShellCommandImporter,
string_attribute_importer: StringAttributeImporter,
integer_attribute_importer: IntegerAttributeImporter) -> None:
integer_attribute_importer: IntegerAttributeImporter,
l10n_importer: L10NImporter) -> None:
super().__init__({
'php_extensions': php_extension_importer,
'databases': database_importer,
@ -174,7 +175,7 @@ class AppReleaseImporter(Importer):
'shell_commands': shell_command_importer,
'signature': string_attribute_importer,
'download': string_attribute_importer,
'changelog': string_attribute_importer,
'changelog': l10n_importer,
}, {
'version',
'raw_version',

Просмотреть файл

@ -35,6 +35,9 @@ class XMLSyntaxError(APIException):
pass
Metadata = Tuple[str, str, Dict[str, str]]
class GunZipAppMetadataExtractor:
def __init__(self, config: ReleaseConfig) -> None:
"""
@ -43,7 +46,7 @@ class GunZipAppMetadataExtractor:
self.config = config
self.app_folder_regex = re.compile(r'^[a-z]+[a-z_]*(?:/.*)*$')
def extract_app_metadata(self, archive_path: str) -> Tuple[str, str, str]:
def extract_app_metadata(self, archive_path: str) -> Metadata:
"""
Extracts the info.xml from an tar.gz archive
:argument archive_path: the path to the tar.gz archive
@ -60,10 +63,19 @@ class GunZipAppMetadataExtractor:
result = self._parse_archive(tar)
return result
def _parse_archive(self, tar: Any) -> Tuple[str, str, str]:
def _parse_archive(self, tar: Any) -> Metadata:
app_id = self._find_app_id(tar)
info = self._get_contents('%s/appinfo/info.xml' % app_id, tar)
changelog = self._get_contents('%s/CHANGELOG.md' % app_id, tar, '')
changelog = {} # type: Dict[str, str]
changelog['en'] = self._get_contents('%s/CHANGELOG.md' % app_id, tar,
'')
for code, _ in self.config.languages:
trans_changelog = self._get_contents(
'%s/CHANGELOG.%s.md' % (app_id, code), tar, ''
)
if trans_changelog:
changelog[code] = trans_changelog
return info, app_id, changelog
def _get_contents(self, path: str, tar: Any, default: Any = None) -> str:

Просмотреть файл

@ -38,11 +38,13 @@ class AppReleaseProvider:
% (app_id, info_app_id)
raise InvalidAppDirectoryException(msg)
version = info['app']['release']['version']
release = info['app']['release']
version = release['version']
if is_nightly:
version += '-nightly'
info['app']['release']['changelog'] = parse_changelog(changelog,
version)
release['changelog'] = changelog
for code, value in changelog.items():
release['changelog'][code] = parse_changelog(value, version)
with open(download.filename, 'rb') as f:
data = f.read()

Просмотреть файл

@ -67,6 +67,7 @@ class AppReleaseSerializer(serializers.ModelSerializer):
raw_platform_version_spec = SerializerMethodField()
version = SerializerMethodField()
nightly = SerializerMethodField()
translations = TranslatedFieldsField(shared_model=AppRelease)
class Meta:
model = AppRelease
@ -75,7 +76,7 @@ class AppReleaseSerializer(serializers.ModelSerializer):
'php_version_spec', 'platform_version_spec', 'min_int_size',
'download', 'created', 'licenses', 'last_modified', 'nightly',
'raw_php_version_spec', 'raw_platform_version_spec', 'signature',
'changelog',
'translations',
)
def get_platform_version_spec(self, obj):

Просмотреть файл

@ -168,7 +168,7 @@ class ParserTest(TestCase):
extractor = GunZipAppMetadataExtractor(self.config)
full_extracted, app_id, changes = extractor.extract_app_metadata(path)
self.assertEqual('contacts', app_id)
self.assertEqual('', changes)
self.assertEqual('', changes['en'])
def test_extract_gunzip_info(self):
path = self.get_path('data/archives/full.tar.gz')
@ -176,7 +176,7 @@ class ParserTest(TestCase):
full_extracted, app_id, changes = extractor.extract_app_metadata(path)
full = self._get_contents('data/infoxmls/full.xml')
self.assertEqual(full, full_extracted)
self.assertEqual('', changes)
self.assertEqual('', changes['en'])
def test_extract_changelog(self):
path = self.get_path('data/archives/changelog.tar.gz')

Просмотреть файл

@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.2 on 2016-10-05 14:24
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
def create_default_changelogs(apps, schema_editor):
model = apps.get_model('core', 'AppRelease')
for release in model.objects.all():
release.set_current_language('en')
release.changelog = ''
release.save()
class Migration(migrations.Migration):
dependencies = [
('core', '0006_apprelease_changelog'),
]
operations = [
migrations.CreateModel(
name='AppReleaseTranslation',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('language_code', models.CharField(db_index=True, max_length=15, verbose_name='Language')),
('changelog', models.TextField(default='', help_text='The release changelog. Can contain Markdown', verbose_name='Changelog')),
],
options={
'default_permissions': (),
'verbose_name': 'App release Translation',
'db_table': 'core_apprelease_translation',
'db_tablespace': '',
'managed': True,
},
),
migrations.RemoveField(
model_name='apprelease',
name='changelog',
),
migrations.AddField(
model_name='appreleasetranslation',
name='master',
field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='translations', to='core.AppRelease'),
),
migrations.AlterUniqueTogether(
name='appreleasetranslation',
unique_together=set([('language_code', 'master')]),
),
migrations.RunPython(create_default_changelogs, migrations.RunPython.noop)
]

Просмотреть файл

@ -32,6 +32,7 @@ class AppManager(TranslatableManager):
def get_compatible(self, platform_version, inclusive=False):
apps = App.objects.prefetch_related(
'releases',
'releases__translations',
'releases__databases',
'releases__licenses',
'releases__phpextensiondependencies__php_extension',
@ -298,7 +299,7 @@ class AppAuthor(Model):
verbose_name_plural = _('App authors')
class AppRelease(Model):
class AppRelease(TranslatableModel):
version = CharField(max_length=256, verbose_name=_('Version'),
help_text=_('Version follows Semantic Versioning'))
app = ForeignKey('App', on_delete=CASCADE, verbose_name=_('App'),
@ -335,8 +336,10 @@ class AppRelease(Model):
verbose_name=_('Updated at'))
signature = TextField(verbose_name=_('Signature'), help_text=_(
'A signature using SHA512 and the app\'s certificate'))
changelog = TextField(verbose_name=_('Changelog'), help_text=_(
'The release changelog. Can contain Markdown'), default='')
translations = TranslatedFields(
changelog=TextField(verbose_name=_('Changelog'), help_text=_(
'The release changelog. Can contain Markdown'), default='')
)
class Meta:
verbose_name = _('App release')

Просмотреть файл

@ -5,7 +5,7 @@
<statuscode>100</statuscode>
<message></message>
<totalitems>{{ apps|length }}</totalitems>
<itemsperpage>1000000</itemsperpage>
<itemsperpage>{{ apps|length }}</itemsperpage>
</meta>
<data>
{% for app in apps %}

Просмотреть файл

@ -5,6 +5,7 @@
<statuscode>100</statuscode>
<message></message>
<totalitems>{{ categories|length }}</totalitems>
<itemsperpage>{{ categories|length }}</itemsperpage>
</meta>
<data>
{% for cat in categories %}