Exemple #1
0
def handle_sample_file(filename, file_id, user, band, callback=None):
    """
    creates the database entries necessary for filename as a sample.
    moves filename to storage or deletes it if there was a problem.
    increments the band's used space. be sure to save after calling.

    if callback is defined, it will be called with each UploadedSample created.
    """
    if band.is_read_only():
        os.remove(filename)
        return

    # check if it is a zip file
    skipExts = studio_extensions()
    _name, ext = os.path.splitext(filename)
    if ext.lower() == '.zip':
        def zipCallback(extracted_file):
            _path, title = os.path.split(extracted_file)

            # skip studio files when uploading sample zips
            _prefix, ext = os.path.splitext(title)
            if ext[1:].lower() in skipExts:
                os.remove(extracted_file)
                return

            handle_sample_file(extracted_file, title, user, band, callback)

        zip_walk(filename, zipCallback)
        os.remove(filename)
        return

    # check the hash
    md5sum = file_hash(filename)

    try:
        existing_sample = SampleFile.objects.get(hex_digest=md5sum)
    except SampleFile.DoesNotExist:
        existing_sample = None

    sample = UploadedSample()
    sample.title = file_id
    skip_byte_count = False
    if existing_sample is not None:
        sample.sample_file = existing_sample

        # if it already exists, don't create a duplicate
        existing_uploaded_samples = UploadedSample.objects.filter(user=user, band=band, sample_file=existing_sample)
        if existing_uploaded_samples.count() > 0:
            if callback is not None:
                existing_uploaded_sample = existing_uploaded_samples[0]
                callback(existing_uploaded_sample)
            os.remove(filename)
            return

        # if user or user's band already uploaded it, don't count it
        # against the band's quota.
        skip_byte_count = UploadedSample.objects.filter(title=sample.title).filter(Q(user=user)|Q(band=band)).count() > 0
    else:
        # pick a good path for the sample
        sample_path = os.path.join('sample', md5sum)

        # create the SampleFile
        sf = SampleFile()
        sf.hex_digest = md5sum
        sf.path = sample_path
        sf.save()

        # copy it to good path
        import storage
        storage.engine.store(filename, sample_path) 

        sample.sample_file = sf

    sample.user = user
    sample.band = band
    sample.save()

    if callback is not None:
        callback(sample)

    # if any songs of any of the user's bands are missing this sample,
    # resolve the dependency.
    user_bands = BandMember.objects.filter(user=user, role__in=[BandMember.BAND_MEMBER, BandMember.MANAGER]).values_list('band', flat=True)
    deps = SampleDependency.objects.filter(title=sample.title, song__band__in=user_bands)
    for dep in deps:
        dep.uploaded_sample = sample
        dep.save()

    if not skip_byte_count:
        # count it against the band's size quota
        band.used_space += os.path.getsize(filename)

    os.remove(filename)
Exemple #2
0
def handle_sample_file(filename, file_id, user, band, callback=None):
    """
    creates the database entries necessary for filename as a sample.
    moves filename to storage or deletes it if there was a problem.
    increments the band's used space. be sure to save after calling.

    if callback is defined, it will be called with each UploadedSample created.
    """
    if band.is_read_only():
        os.remove(filename)
        return

    # check if it is a zip file
    skipExts = studio_extensions()
    _name, ext = os.path.splitext(filename)
    if ext.lower() == '.zip':

        def zipCallback(extracted_file):
            _path, title = os.path.split(extracted_file)

            # skip studio files when uploading sample zips
            _prefix, ext = os.path.splitext(title)
            if ext[1:].lower() in skipExts:
                os.remove(extracted_file)
                return

            handle_sample_file(extracted_file, title, user, band, callback)

        zip_walk(filename, zipCallback)
        os.remove(filename)
        return

    # check the hash
    md5sum = file_hash(filename)

    try:
        existing_sample = SampleFile.objects.get(hex_digest=md5sum)
    except SampleFile.DoesNotExist:
        existing_sample = None

    sample = UploadedSample()
    sample.title = file_id
    skip_byte_count = False
    if existing_sample is not None:
        sample.sample_file = existing_sample

        # if it already exists, don't create a duplicate
        existing_uploaded_samples = UploadedSample.objects.filter(
            user=user, band=band, sample_file=existing_sample)
        if existing_uploaded_samples.count() > 0:
            if callback is not None:
                existing_uploaded_sample = existing_uploaded_samples[0]
                callback(existing_uploaded_sample)
            os.remove(filename)
            return

        # if user or user's band already uploaded it, don't count it
        # against the band's quota.
        skip_byte_count = UploadedSample.objects.filter(
            title=sample.title).filter(Q(user=user) | Q(band=band)).count() > 0
    else:
        # pick a good path for the sample
        sample_path = os.path.join('sample', md5sum)

        # create the SampleFile
        sf = SampleFile()
        sf.hex_digest = md5sum
        sf.path = sample_path
        sf.save()

        # copy it to good path
        import storage
        storage.engine.store(filename, sample_path)

        sample.sample_file = sf

    sample.user = user
    sample.band = band
    sample.save()

    if callback is not None:
        callback(sample)

    # if any songs of any of the user's bands are missing this sample,
    # resolve the dependency.
    user_bands = BandMember.objects.filter(
        user=user, role__in=[BandMember.BAND_MEMBER,
                             BandMember.MANAGER]).values_list('band',
                                                              flat=True)
    deps = SampleDependency.objects.filter(title=sample.title,
                                           song__band__in=user_bands)
    for dep in deps:
        dep.uploaded_sample = sample
        dep.save()

    if not skip_byte_count:
        # count it against the band's size quota
        band.used_space += os.path.getsize(filename)

    os.remove(filename)
Exemple #3
0
def handle_project_file(filename, user, song, filename_appendix=""):
    """
    creates the database entries necessary for filename as the project for song.
    moves filename to storage or deletes it if there is a problem.
    increments the band's used space. be sure to save song and song.band after calling.
    """
    _prefix, ext = os.path.splitext(filename)
    profile = user.get_profile()

    # handle zip files
    if ext.lower() == '.zip':
        studioExts = studio_extensions()
        song.studio = None
        def zipCallback(extracted_filename):
            _path, title = os.path.split(extracted_filename)
            _prefix, ext = os.path.splitext(extracted_filename)
            if ext[1:].lower() in studioExts:
                if song.studio is None:
                    handle_project_file(extracted_filename, user, song, filename_appendix=filename_appendix)
            else:
                handle_sample_file(extracted_filename, title, user, song.band)

        zip_walk(filename, zipCallback)
        os.remove(filename)
        return

    # read the project file with the daw
    source_file_title = song.displayString()
    profile_save_required = False
    try:
        dawProject = daw.load(filename)
        dawExt = dawProject.extension() 

        # assign the correct studio
        try:
            song.studio = Studio.objects.get(identifier=dawProject.identifier)

            # assume the user owns the studio
            profile.studios.add(song.studio)
            profile_save_required = True
        except Studio.DoesNotExist:
            pass

        stuff = (
            (dawProject.generators(), PluginDepenency.GENERATOR),
            (dawProject.effects(), PluginDepenency.EFFECT),
        )
        for plugins, plugin_type in stuff:
            for plugin in plugins:
                # if it's an invalid name, ignore
                if plugin.strip() == '':
                    continue

                if plugin in IGNORED_PLUGINS:
                    continue

                # see if it already exists
                deps = PluginDepenency.objects.filter(title=plugin)
                if deps.count() == 0:
                    # create it
                    dep = PluginDepenency()
                    dep.title = plugin
                    dep.plugin_type = plugin_type
                    dep.save()
                else:
                    dep = deps[0]

                # add it as a dependency
                song.plugins.add(dep)

                # assume that the user owns this dependency
                if profile.assume_uploaded_plugins_owned:
                    profile.plugins.add(dep)
                    profile_save_required = True

        samples = dawProject.samples()
        for sample in samples:
            # if it's an invalid name, ignore
            if sample.strip() == '':
                continue

            _path, title = os.path.split(sample)

            # create the dependency
            dep = SampleDependency()
            dep.title = title
            dep.song = song
                
            # if the title matches anthing the user or band has already uploaded,
            # establish a link.
            existing_samples = UploadedSample.objects.filter(title=title).filter(Q(user=user)|Q(band=song.band))

            if existing_samples.count() > 0:
                # TODO: handle title ambiguity
                # copy the dependency to this song
                existing_sample = existing_samples[0]
                dep.uploaded_sample = existing_sample

            dep.save()

        if dawExt:
            source_file_title += filename_appendix + "." + dawExt

        usingDaw = True
    except daw.exceptions.LoadError:
        usingDaw = False
        # ok forget about processing it with the daw
        # add the extension from before
        source_file_title += filename_appendix + ext
    finally:
        if profile_save_required:
            profile.save()

    song.source_file = os.path.join(obfuscated_url(song.band), clean_filename(source_file_title))

    if usingDaw:
        out_handle = tempfile.NamedTemporaryFile(mode='r+b')
        dawProject.save(out_handle.name)

        # count it against the band's size quota
        song.band.used_space += os.path.getsize(out_handle.name)

        # move to storage
        import storage
        storage.engine.store(out_handle.name, song.source_file)
        out_handle.close()

        os.remove(filename)
    else:
        # count it against the band's size quota
        song.band.used_space += os.path.getsize(filename)
        # move to storage
        move_to_storage(filename, song.source_file)

    song.save()
Exemple #4
0
def handle_project_file(filename, user, song, filename_appendix=""):
    """
    creates the database entries necessary for filename as the project for song.
    moves filename to storage or deletes it if there is a problem.
    increments the band's used space. be sure to save song and song.band after calling.
    """
    _prefix, ext = os.path.splitext(filename)
    profile = user.get_profile()

    # handle zip files
    if ext.lower() == '.zip':
        studioExts = studio_extensions()
        song.studio = None

        def zipCallback(extracted_filename):
            _path, title = os.path.split(extracted_filename)
            _prefix, ext = os.path.splitext(extracted_filename)
            if ext[1:].lower() in studioExts:
                if song.studio is None:
                    handle_project_file(extracted_filename,
                                        user,
                                        song,
                                        filename_appendix=filename_appendix)
            else:
                handle_sample_file(extracted_filename, title, user, song.band)

        zip_walk(filename, zipCallback)
        os.remove(filename)
        return

    # read the project file with the daw
    source_file_title = song.displayString()
    profile_save_required = False
    try:
        dawProject = daw.load(filename)
        dawExt = dawProject.extension()

        # assign the correct studio
        try:
            song.studio = Studio.objects.get(identifier=dawProject.identifier)

            # assume the user owns the studio
            profile.studios.add(song.studio)
            profile_save_required = True
        except Studio.DoesNotExist:
            pass

        stuff = (
            (dawProject.generators(), PluginDepenency.GENERATOR),
            (dawProject.effects(), PluginDepenency.EFFECT),
        )
        for plugins, plugin_type in stuff:
            for plugin in plugins:
                # if it's an invalid name, ignore
                if plugin.strip() == '':
                    continue

                if plugin in IGNORED_PLUGINS:
                    continue

                # see if it already exists
                deps = PluginDepenency.objects.filter(title=plugin)
                if deps.count() == 0:
                    # create it
                    dep = PluginDepenency()
                    dep.title = plugin
                    dep.plugin_type = plugin_type
                    dep.save()
                else:
                    dep = deps[0]

                # add it as a dependency
                song.plugins.add(dep)

                # assume that the user owns this dependency
                if profile.assume_uploaded_plugins_owned:
                    profile.plugins.add(dep)
                    profile_save_required = True

        samples = dawProject.samples()
        for sample in samples:
            # if it's an invalid name, ignore
            if sample.strip() == '':
                continue

            _path, title = os.path.split(sample)

            # create the dependency
            dep = SampleDependency()
            dep.title = title
            dep.song = song

            # if the title matches anthing the user or band has already uploaded,
            # establish a link.
            existing_samples = UploadedSample.objects.filter(
                title=title).filter(Q(user=user) | Q(band=song.band))

            if existing_samples.count() > 0:
                # TODO: handle title ambiguity
                # copy the dependency to this song
                existing_sample = existing_samples[0]
                dep.uploaded_sample = existing_sample

            dep.save()

        if dawExt:
            source_file_title += filename_appendix + "." + dawExt

        usingDaw = True
    except daw.exceptions.LoadError:
        usingDaw = False
        # ok forget about processing it with the daw
        # add the extension from before
        source_file_title += filename_appendix + ext
    finally:
        if profile_save_required:
            profile.save()

    song.source_file = os.path.join(obfuscated_url(song.band),
                                    clean_filename(source_file_title))

    if usingDaw:
        out_handle = tempfile.NamedTemporaryFile(mode='r+b')
        dawProject.save(out_handle.name)

        # count it against the band's size quota
        song.band.used_space += os.path.getsize(out_handle.name)

        # move to storage
        import storage
        storage.engine.store(out_handle.name, song.source_file)
        out_handle.close()

        os.remove(filename)
    else:
        # count it against the band's size quota
        song.band.used_space += os.path.getsize(filename)
        # move to storage
        move_to_storage(filename, song.source_file)

    song.save()