<commit_before>
import os
import json
import uuid
from zipfile import ZipFile, BadZipfile

import autoslug
import tagging
from django.contrib import auth
from django.db import models

# Create your models here.

class Extension(models.Model):
    name = models.CharField(max_length=200)
    uuid = models.TextField()
    slug = autoslug.AutoSlugField(populate_from="name", unique=True)
    creator = models.ForeignKey(auth.models.User)
    description = models.TextField()
    url = models.URLField()
    created = models.DateTimeField(auto_now_add=True)
    is_published = models.BooleanField(default=False)

    def get_version(self, version):
        if version in (None, 'latest'):
            return self.extensionversion_set.order_by('-version')[0]

        return self.extensionversion_set.get(version=int(version))

tagging.register(Extension)

class InvalidExtensionData(Exception):
    pass

class ExtensionVersion(models.Model):
    extension = models.ForeignKey(Extension)
    version = models.IntegerField(default=0)
    extra_json_fields = models.TextField()

    def make_filename(self, filename):
        return os.path.join(self.extension.uuid, str(self.version),
                            self.extension.slug + ".shell-extension.zip")

    source = models.FileField(upload_to=make_filename)

    def make_metadata_json(self):
        """
        Return generated contents of metadata.json
        """
        data = json.loads(self.extra_json_fields)
        data['_generated']  = "Generated by SweetTooth, do not edit"
        data['name']        = self.extension.name
        data['description'] = self.extension.description
        data['url']         = self.extension.url
        data['uuid']        = self.extension.uuid
        data['version']     = self.version
        return json.dumps(data, sort_keys=True, indent=2)

    def replace_metadata_json(self):
        """
        In the uploaded extension zipfile, edit metadata.json
        to reflect the new contents.
        """
        zipfile = ZipFile(self.source.storage.path(self.source.name), "a")
        zipfile.writestr("metadata.json", self.make_metadata_json())
        zipfile.close()

    @classmethod
    def from_metadata_json(cls, metadata, extension=None):
        """
        Given the contents of a metadata.json file, create an extension
        and version with its data and return them.
        """

        if extension is None:
            extension = Extension()
            extension.name = metadata.get('name', "")
            extension.description = metadata.get('description', "")
            extension.url = metadata.get('url', "")
            extension.uuid = metadata.get('uuid', str(uuid.uuid1()))

        version = ExtensionVersion(extension=extension)
        version.extra_json_fields = json.dumps(metadata)
        return extension, version

    @classmethod
    def from_zipfile(cls, uploaded_file, extension=None):
        """
        Given a file, create an extension and version, populated
        with the data from the metadata.json and return them.
        """
        try:
            zipfile = ZipFile(uploaded_file, 'r')
        except BadZipfile:
            raise InvalidExtensionData("Invalid zip file")

        try:
            metadata = json.load(zipfile.open('metadata.json', 'r'))
        except KeyError:
            # no metadata.json in archive, use web editor
            metadata = {}
        except ValueError:
            # invalid JSON file, raise error
            raise InvalidExtensionData("Invalid JSON data")

        extension, version = cls.from_metadata_json(metadata, extension)
        zipfile.close()
        return extension, version

    def save(self, **kw):
        # autoincrement version
        if self.version == 0:
            versions = type(self).objects.filter(extension=self.extension)
            versions = versions.order_by('-version')
            try:
                self.version_number = versions[0]
            except IndexError:
                # New extension, no versions yes
                self.version_number = 1

        super(ExtensionVersion, self).save(**kw)<commit_msg>Remove auto-incrementing approach in favor of explicit approach.<commit_after>
import os
import json
import uuid
from zipfile import ZipFile, BadZipfile

import autoslug
import tagging
from django.contrib import auth
from django.db import models

# Create your models here.

class Extension(models.Model):
    name = models.CharField(max_length=200)
    uuid = models.TextField()
    slug = autoslug.AutoSlugField(populate_from="name", unique=True)
    creator = models.ForeignKey(auth.models.User)
    description = models.TextField()
    url = models.URLField()
    created = models.DateTimeField(auto_now_add=True)
    is_published = models.BooleanField(default=False)

    def get_version(self, version):
        if version in (None, 'latest'):
            return self.extensionversion_set.order_by('-version')[0]

        return self.extensionversion_set.get(version=int(version))

tagging.register(Extension)

class InvalidExtensionData(Exception):
    pass

class ExtensionVersion(models.Model):
    extension = models.ForeignKey(Extension)
    version = models.IntegerField(default=0)
    extra_json_fields = models.TextField()

    def make_filename(self, filename):
        return os.path.join(self.extension.uuid, str(self.version),
                            self.extension.slug + ".shell-extension.zip")

    source = models.FileField(upload_to=make_filename)

    def make_metadata_json(self):
        """
        Return generated contents of metadata.json
        """
        data = json.loads(self.extra_json_fields)
        data['_generated']  = "Generated by SweetTooth, do not edit"
        data['name']        = self.extension.name
        data['description'] = self.extension.description
        data['url']         = self.extension.url
        data['uuid']        = self.extension.uuid
        data['version']     = self.version
        return json.dumps(data, sort_keys=True, indent=2)

    def replace_metadata_json(self):
        """
        In the uploaded extension zipfile, edit metadata.json
        to reflect the new contents.
        """
        zipfile = ZipFile(self.source.storage.path(self.source.name), "a")
        zipfile.writestr("metadata.json", self.make_metadata_json())
        zipfile.close()

    @classmethod
    def from_metadata_json(cls, metadata, extension=None):
        """
        Given the contents of a metadata.json file, create an extension
        and version with its data and return them.
        """

        if extension is None:
            extension = Extension()
            extension.name = metadata.get('name', "")
            extension.description = metadata.get('description', "")
            extension.url = metadata.get('url', "")
            extension.uuid = metadata.get('uuid', str(uuid.uuid1()))

        version = ExtensionVersion(extension=extension)
        version.extra_json_fields = json.dumps(metadata)

        # get version number
        ver_ids = extension.extensionversion_set.order_by('-version')
        try:
            ver_id = ver_ids[0].version + 1
        except IndexError:
            # New extension, no versions yet
            ver_id = 1

        version.version = ver_id
        return extension, version

    @classmethod
    def from_zipfile(cls, uploaded_file, extension=None):
        """
        Given a file, create an extension and version, populated
        with the data from the metadata.json and return them.
        """
        try:
            zipfile = ZipFile(uploaded_file, 'r')
        except BadZipfile:
            raise InvalidExtensionData("Invalid zip file")

        try:
            metadata = json.load(zipfile.open('metadata.json', 'r'))
        except KeyError:
            # no metadata.json in archive, use web editor
            metadata = {}
        except ValueError:
            # invalid JSON file, raise error
            raise InvalidExtensionData("Invalid JSON data")

        extension, version = cls.from_metadata_json(metadata, extension)
        zipfile.close()
        return extension, version
{'fraction_non_alphanumeric': 0.09935310631026487, 'fraction_numerical': 0.0024411082631514707, 'mean_word_length': 2.5533391153512577, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, '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': '3605631', 'n_tokens_mistral': 2186, 'n_tokens_neox': 2140, 'n_words': 536}