<commit_before>/*
 *  alarmcalendar.cpp  -  KAlarm calendar file access
 *  Program:  kalarm
 *  (C) 2001, 2002 by <NAME>  <EMAIL>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  As a special exception, permission is given to link this program
 *  with any edition of Qt, and distribute the resulting executable,
 *  without including the source code for Qt in the source distribution.
 */

#include "kalarm.h"
#include <unistd.h>
#include <time.h>

#include <qfile.h>
#include <qtextstream.h>

#include <kmessagebox.h>
#include <klocale.h>
#include <kstandarddirs.h>
#include <kconfig.h>
#include <kaboutdata.h>
#include <kio/netaccess.h>
#include <kfileitem.h>
#include <ktempfile.h>
#include <dcopclient.h>
#include <kdebug.h>

extern "C" {
#include <libical/ical.h>
}

#include <libkcal/vcaldrag.h>
#include <libkcal/vcalformat.h>
#include <libkcal/icalformat.h>

#include "kalarmapp.h"
#include "alarmcalendar.h"


AlarmCalendar::AlarmCalendar(const QString& path, KAlarmEvent::Status type)
	: mCalendar(0),
	  mType(type),
	  mKAlarmVersion(-1),
	  mKAlarmVersion057_UTC(false)
{
	mUrl.setPath(path);    // N.B. constructor mUrl(path) doesn't work with UNIX paths
}

/******************************************************************************
* Open the calendar file and load it into memory.
*/
bool AlarmCalendar::open()
{
	if (mCalendar)
		return true;
	if (!mUrl.isValid())
		return false;
	kdDebug(5950) << "AlarmCalendar::open(" << mUrl.prettyURL() << ")\n";
	mCalendar = new CalendarLocal();
	mCalendar->setLocalTime();    // write out using local time (i.e. no time zone)

	// Find out whether the calendar is ICal or VCal format
	QString ext = mUrl.filename().right(4);
	mVCal = (ext == QString::fromLatin1(".vcs"));

	if (!KIO::NetAccess::exists(mUrl))
	{
		if (!create())      // create the calendar file
		{
			delete mCalendar;
			mCalendar = 0;
			return false;
		}
	}

	// Load the calendar file
	switch (load())
	{
		case 1:         // success
			break;
		case 0:         // zero-length file
			if (!create()  ||  load() <= 0)
			{
				delete mCalendar;
				mCalendar = 0;
				return false;
			}
		case -1:        // failure
			delete mCalendar;
			mCalendar = 0;
			return false;
	}
	return true;
}

/******************************************************************************
* Private method to create a new calendar file.
*/
bool AlarmCalendar::create()
{
	// Create the calendar file
	KTempFile* tmpFile = 0;
	QString filename;
	if (mUrl.isLocalFile())
		filename = mUrl.path();
	else
	{
		tmpFile = new KTempFile;
		filename = tmpFile->name();
	}
	if (!save(filename))
	{
		delete tmpFile;
		return false;
	}
	delete tmpFile;
	return true;
}

/******************************************************************************
* Load the calendar file into memory.
* Reply = 1 if success, -2 if failure, 0 if zero-length file exists.
*/
int AlarmCalendar::load()
{
	if (!mCalendar)
		return -2;

	kdDebug(5950) << "AlarmCalendar::load(): " << mUrl.prettyURL() << endl;
	QString tmpFile;
	if (!KIO::NetAccess::download(mUrl, tmpFile))
	{
		kdError(5950) << "AlarmCalendar::load(): Load failure" << endl;
		KMessageBox::error(0, i18n("Cannot open calendar:\n%1").arg(mUrl.prettyURL()), kapp->aboutData()->programName());
		return -1;
	}
	kdDebug(5950) << "AlarmCalendar::load(): --- Downloaded to " << tmpFile << endl;
	mKAlarmVersion        = -1;
	mKAlarmVersion057_UTC = false;
	mCalendar->setTimeZoneId(QString::null);   // default to the local time zone for reading
	bool loaded = mCalendar->load(tmpFile);
	mCalendar->setLocalTime();                 // write using local time (i.e. no time zone)
	if (!loaded)
	{
		// Check if the file is zero length
		KIO::NetAccess::removeTempFile(tmpFile);
		KIO::UDSEntry uds;
		KIO::NetAccess::stat(mUrl, uds);
		KFileItem fi(uds, mUrl);
		if (!fi.size())
			return 0;     // file is zero length
		kdError(5950) << "AlarmCalendar::load(): Error loading calendar file '" << tmpFile << "'" << endl;
		KMessageBox::error(0, i18n("Error loading calendar:\n%1\n\nPlease fix or delete the file.").arg(mUrl.prettyURL()),
		                   kapp->aboutData()->programName());
		return -1;
	}
	if (!mLocalFile.isEmpty())
		KIO::NetAccess::removeTempFile(mLocalFile);
	mLocalFile = tmpFile;

	// Find the version of KAlarm which wrote the calendar file, and do<commit_msg>Clear out calendar on load failure<commit_after>/*
 *  alarmcalendar.cpp  -  KAlarm calendar file access
 *  Program:  kalarm
 *  (C) 2001, 2002 by <NAME>  <EMAIL>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  As a special exception, permission is given to link this program
 *  with any edition of Qt, and distribute the resulting executable,
 *  without including the source code for Qt in the source distribution.
 */

#include "kalarm.h"
#include <unistd.h>
#include <time.h>

#include <qfile.h>
#include <qtextstream.h>

#include <kmessagebox.h>
#include <klocale.h>
#include <kstandarddirs.h>
#include <kconfig.h>
#include <kaboutdata.h>
#include <kio/netaccess.h>
#include <kfileitem.h>
#include <ktempfile.h>
#include <dcopclient.h>
#include <kdebug.h>

extern "C" {
#include <libical/ical.h>
}

#include <libkcal/vcaldrag.h>
#include <libkcal/vcalformat.h>
#include <libkcal/icalformat.h>

#include "kalarmapp.h"
#include "alarmcalendar.h"


AlarmCalendar::AlarmCalendar(const QString& path, KAlarmEvent::Status type)
	: mCalendar(0),
	  mType(type),
	  mKAlarmVersion(-1),
	  mKAlarmVersion057_UTC(false)
{
	mUrl.setPath(path);    // N.B. constructor mUrl(path) doesn't work with UNIX paths
}

/******************************************************************************
* Open the calendar file and load it into memory.
*/
bool AlarmCalendar::open()
{
	if (mCalendar)
		return true;
	if (!mUrl.isValid())
		return false;
	kdDebug(5950) << "AlarmCalendar::open(" << mUrl.prettyURL() << ")\n";
	mCalendar = new CalendarLocal();
	mCalendar->setLocalTime();    // write out using local time (i.e. no time zone)

	// Find out whether the calendar is ICal or VCal format
	QString ext = mUrl.filename().right(4);
	mVCal = (ext == QString::fromLatin1(".vcs"));

	if (!KIO::NetAccess::exists(mUrl))
	{
		if (!create())      // create the calendar file
		{
			delete mCalendar;
			mCalendar = 0;
			return false;
		}
	}

	// Load the calendar file
	switch (load())
	{
		case 1:         // success
			break;
		case 0:         // zero-length file
			if (!create()  ||  load() <= 0)
			{
				delete mCalendar;
				mCalendar = 0;
				return false;
			}
		case -1:        // failure
			delete mCalendar;
			mCalendar = 0;
			return false;
	}
	return true;
}

/******************************************************************************
* Private method to create a new calendar file.
*/
bool AlarmCalendar::create()
{
	// Create the calendar file
	KTempFile* tmpFile = 0;
	QString filename;
	if (mUrl.isLocalFile())
		filename = mUrl.path();
	else
	{
		tmpFile = new KTempFile;
		filename = tmpFile->name();
	}
	if (!save(filename))
	{
		delete tmpFile;
		return false;
	}
	delete tmpFile;
	return true;
}

/******************************************************************************
* Load the calendar file into memory.
* Reply = 1 if success, -2 if failure, 0 if zero-length file exists.
*/
int AlarmCalendar::load()
{
	if (!mCalendar)
		return -2;

	kdDebug(5950) << "AlarmCalendar::load(): " << mUrl.prettyURL() << endl;
	QString tmpFile;
	if (!KIO::NetAccess::download(mUrl, tmpFile))
	{
		kdError(5950) << "AlarmCalendar::load(): Load failure" << endl;
		KMessageBox::error(0, i18n("Cannot open calendar:\n%1").arg(mUrl.prettyURL()), kapp->aboutData()->programName());
		return -1;
	}
	kdDebug(5950) << "AlarmCalendar::load(): --- Downloaded to " << tmpFile << endl;
	mKAlarmVersion        = -1;
	mKAlarmVersion057_UTC = false;
	mCalendar->setTimeZoneId(QString::null);   // default to the local time zone for reading
	bool loaded = mCalendar->load(tmpFile);
	mCalendar->setLocalTime();                 // write using local time (i.e. no time zone)
	if (!loaded)
	{
		// Check if the file is zero length
		KIO::NetAccess::removeTempFile(tmpFile);
		KIO::UDSEntry uds;
		KIO::NetAccess::stat(mUrl, uds);
		KFileItem fi(uds, mUrl);
		if (!fi.size())
			return 0;     // file is zero length
		kdError(5950) << "AlarmCalendar::load(): Error loading calendar file '" << tmpFile << "'" << endl;
		KMessageBox::error(0, i18n("Error loading calendar:\n%1\n\nPlease fix or delete the file.").arg(mUrl.prettyURL()),
		                   kapp->aboutData()->programName());
		// load() could have partially populated the calendar, so clear it out
		mCalendar->close();
		delete mCalendar;
		mCalendar = 0;
		return -1;
	}
	if (!mLocalFile.isEmpty())
		KIO::NetAccess::removeTempFile(mLocalFile);
	mLocalFile = tmpFile;

	// Find the version of KAlarm which wrote the calendar file, and do
{'fraction_non_alphanumeric': 0.1736350221347762, 'fraction_numerical': 0.014067879980324643, 'mean_word_length': 3.847877920839294, 'pattern_counts': {'":': 0, '<': 105, '<?xml version=': 0, '>': 62, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '888457', 'n_tokens_mistral': 3538, 'n_tokens_neox': 3269, 'n_words': 1014}