<commit_before>#include <fstream>
#include <sstream>
#include <iostream>

#include "allocore/ui/al_Composition.hpp"
#include "allocore/system/al_Time.hpp"
#include "allocore/io/al_File.hpp"

using namespace al;

Composition::Composition(std::string fileName, std::string path) :
    mPath(path), mCompositionName(fileName), mPlayThread(nullptr),
    mSequencer(nullptr)
{
	mCompositionSteps = loadCompositionSteps(mCompositionName);
}

Composition::~Composition()
{
	mPlaying = false;
	if (mPlayThread) {
		mPlayThread->join();
		delete mPlayThread;
	}
}

void Composition::play()
{
	stop();
	mPlaying = true;
	mPlayThread = new std::thread(Composition::playbackThread, this);
}

void Composition::stop()
{
	if (mPlayThread) {
		mPlaying = false;
		mPlayThread->join();
		delete mPlayThread;
		mPlayThread = nullptr;
	}
	mSequencer->stopSequence();
}

bool Composition::playArchive(std::string archiveName)
{

}

std::string Composition::getName()
{
	return mCompositionName;
}

bool Composition::archiveComposition()
{
	std::string path = mPath;
	std::string compositionName = mCompositionName;
	bool ok = true;

	if (path.back() != '/' && path.size() > 0) {
		path += "/";
	}
	std::string fullPath = path;
	fullPath += compositionName + ".composition";

	std::string archivePath = fullPath;
	if (archivePath.size() > 8 && archivePath.substr(archivePath.size() - 8) != "_archive") {
		archivePath += "_archive";
	}

	if (File::isDirectory(archivePath) ) {
		if (!Dir::removeRecursively(archivePath)) {
			std::cerr << "Error removing directory: " << fullPath << " aborting composition archiving." << std::endl;
			return false;
		}
		if (!Dir::make(archivePath)) {
			std::cerr << "Error creating composition archive directory " << fullPath << std::endl;
			return false;
		}

	} else if (!File::exists(archivePath)) {
		if (!Dir::make(archivePath)) {
			std::cerr << "Error creating compostion archive directory " << archivePath << std::endl;
			return false;
		}

	} else {
		// TODO generate new name instead of error
		std::cerr << "compostion directory name taken by file: " << archivePath << std::endl;
		return false;
	}

	auto steps = loadCompositionSteps(compositionName);

	for (auto step: steps) {
		std::cout << step.sequenceName << ":" << step.deltaTime << std::endl;
		PresetSequencer sequencer;
		sequencer.setDirectory(path);
		std::queue<PresetSequencer::Step> sequenceSteps = sequencer.loadSequence(step.sequenceName);
		if (!File::copy(path + step.sequenceName + ".sequence",
		                archivePath + "/" + step.sequenceName + ".sequence")) {
			std::cerr << "Error copying sequence: " << step.sequenceName << " when archiving composition." << std::endl;
			ok = false;
		}
		while(sequenceSteps.size() > 0) {
			PresetSequencer::Step &sequenceStep = sequenceSteps.front();
			if (!File::copy(path + sequenceStep.presetName + ".preset",
			                archivePath + "/" + sequenceStep.presetName + ".preset")) {<commit_msg>Check if file exists before copying in composition archiving<commit_after>#include <fstream>
#include <sstream>
#include <iostream>

#include "allocore/ui/al_Composition.hpp"
#include "allocore/system/al_Time.hpp"
#include "allocore/io/al_File.hpp"

using namespace al;

Composition::Composition(std::string fileName, std::string path) :
    mPath(path), mCompositionName(fileName), mPlayThread(nullptr),
    mSequencer(nullptr)
{
	mCompositionSteps = loadCompositionSteps(mCompositionName);
}

Composition::~Composition()
{
	mPlaying = false;
	if (mPlayThread) {
		mPlayThread->join();
		delete mPlayThread;
	}
}

void Composition::play()
{
	stop();
	mPlaying = true;
	mPlayThread = new std::thread(Composition::playbackThread, this);
}

void Composition::stop()
{
	if (mPlayThread) {
		mPlaying = false;
		mPlayThread->join();
		delete mPlayThread;
		mPlayThread = nullptr;
	}
	mSequencer->stopSequence();
}

bool Composition::playArchive(std::string archiveName)
{

}

std::string Composition::getName()
{
	return mCompositionName;
}

bool Composition::archiveComposition()
{
	std::string path = mPath;
	std::string compositionName = mCompositionName;
	bool ok = true;

	if (path.back() != '/' && path.size() > 0) {
		path += "/";
	}
	std::string fullPath = path;
	fullPath += compositionName + ".composition";

	std::string archivePath = fullPath;
	if (archivePath.size() > 8 && archivePath.substr(archivePath.size() - 8) != "_archive") {
		archivePath += "_archive";
	}

	if (File::isDirectory(archivePath) ) {
		if (!Dir::removeRecursively(archivePath)) {
			std::cerr << "Error removing directory: " << fullPath << " aborting composition archiving." << std::endl;
			return false;
		}
		if (!Dir::make(archivePath)) {
			std::cerr << "Error creating composition archive directory " << fullPath << std::endl;
			return false;
		}

	} else if (!File::exists(archivePath)) {
		if (!Dir::make(archivePath)) {
			std::cerr << "Error creating compostion archive directory " << archivePath << std::endl;
			return false;
		}

	} else {
		// TODO generate new name instead of error
		std::cerr << "compostion directory name taken by file: " << archivePath << std::endl;
		return false;
	}

	auto steps = loadCompositionSteps(compositionName);

	for (auto step: steps) {
		std::cout << step.sequenceName << ":" << step.deltaTime << std::endl;
		PresetSequencer sequencer;
		sequencer.setDirectory(path);
		std::queue<PresetSequencer::Step> sequenceSteps = sequencer.loadSequence(step.sequenceName);
		if (!File::copy(path + step.sequenceName + ".sequence",
		                archivePath + "/" + step.sequenceName + ".sequence")) {
			std::cerr << "Error copying sequence: " << step.sequenceName << " when archiving composition." << std::endl;
			ok = false;
		}
		while(sequenceSteps.size() > 0) {
			PresetSequencer::Step &sequenceStep = sequenceSteps.front();
			if (!File::exists(archivePath + "/" + sequenceStep.presetName + ".preset")
			        && !File::copy(path + sequenceStep.presetName + ".preset",
			                archivePath + "/" + sequenceStep.presetName + ".preset")) {
{'fraction_non_alphanumeric': 0.1554635761589404, 'fraction_numerical': 0.0013245033112582781, 'mean_word_length': 4.61953488372093, 'pattern_counts': {'":': 2, '<': 95, '<?xml version=': 0, '>': 23, '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': '1060383', 'n_tokens_mistral': 2067, 'n_tokens_neox': 1932, 'n_words': 415}