--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2022 Pakfire development team #
+# #
+# 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 3 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, see <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <Python.h>
+#include <datetime.h>
+
+#include <pakfire/file.h>
+
+#include "file.h"
+#include "pakfire.h"
+
+PyObject* new_file(struct pakfire_file* file) {
+ PyTypeObject* type = &FileType;
+
+ FileObject* self = (FileObject *)type->tp_alloc(type, 0);
+ if (self) {
+ if (file)
+ self->file = pakfire_file_ref(file);
+ else
+ self->file = NULL;
+ }
+
+ return (PyObject *)self;
+}
+
+static PyObject* File_new(PyTypeObject* type, PyObject* args, PyObject* kwds) {
+ return new_file(NULL);
+}
+
+static void File_dealloc(FileObject* self) {
+ if (self->file)
+ pakfire_file_unref(self->file);
+
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static int File_init(FileObject* self, PyObject* args, PyObject* kwds) {
+ PakfireObject* pakfire = NULL;
+
+ if (!PyArg_ParseTuple(args, "O!", &PakfireType, &pakfire))
+ return -1;
+
+ // Create a new File object
+ int r = pakfire_file_create(&self->file, pakfire->pakfire);
+ if (r)
+ return -1;
+
+ return 0;
+}
+
+static PyObject* File_repr(FileObject* self) {
+ const char* path = pakfire_file_get_path(self->file);
+
+ return PyUnicode_FromFormat("<_pakfire.Problem %s>", path);
+}
+
+static PyObject* File_get_path(FileObject* self) {
+ const char* path = pakfire_file_get_path(self->file);
+
+ return PyUnicode_FromString(path);
+}
+
+static int File_set_path(FileObject* self, PyObject* value) {
+ const char* path = PyUnicode_AsUTF8(value);
+ if (!path)
+ return -1;
+
+ pakfire_file_set_path(self->file, path);
+ return 0;
+}
+
+static PyObject* File_get_size(FileObject* self) {
+ const size_t size = pakfire_file_get_size(self->file);
+
+ return PyLong_FromSize_t(size);
+}
+
+static int File_set_size(FileObject* self, PyObject* value) {
+ long size = PyLong_AsLong(value);
+ if (size < 0)
+ return -1;
+
+ pakfire_file_set_size(self->file, size);
+ return 0;
+}
+
+static PyObject* File_get_type(FileObject* self) {
+ int type = pakfire_file_get_type(self->file);
+
+ return PyLong_FromLong(type);
+}
+
+static PyObject* File_get_user(FileObject* self) {
+ const char* user = pakfire_file_get_user(self->file);
+
+ return PyUnicode_FromString(user);
+}
+
+static int File_set_user(FileObject* self, PyObject* value) {
+ const char* user = PyUnicode_AsUTF8(value);
+ if (!user)
+ return -1;
+
+ pakfire_file_set_user(self->file, user);
+ return 0;
+}
+
+static PyObject* File_get_group(FileObject* self) {
+ const char* group = pakfire_file_get_group(self->file);
+
+ return PyUnicode_FromString(group);
+}
+
+static int File_set_group(FileObject* self, PyObject* value) {
+ const char* group = PyUnicode_AsUTF8(value);
+ if (!group)
+ return -1;
+
+ pakfire_file_set_group(self->file, group);
+ return 0;
+}
+
+static PyObject* File_get_mode(FileObject* self) {
+ const mode_t mode = pakfire_file_get_mode(self->file);
+
+ return PyLong_FromLong(mode);
+}
+
+static int File_set_mode(FileObject* self, PyObject* value) {
+ const mode_t mode = PyLong_AsLong(value);
+
+ pakfire_file_set_mode(self->file, mode);
+ return 0;
+}
+
+static PyObject* PyDateTime_FromTime_t(const time_t* t) {
+ struct tm buffer;
+
+ struct tm* tm = gmtime_r(t, &buffer);
+ if (!tm)
+ return NULL;
+
+ PyDateTime_IMPORT;
+
+ return PyDateTime_FromDateAndTime(
+ 1900 + tm->tm_year,
+ 1 + tm->tm_mon,
+ tm->tm_mday,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec,
+ 0
+ );
+}
+
+static time_t PyDateTime_AsTime_t(PyObject* value) {
+ if (!PyDateTime_Check(value))
+ return -1;
+
+ PyDateTime_IMPORT;
+
+ // Convert from datetime to struct tm
+ struct tm tm = {
+ .tm_year = PyDateTime_GET_YEAR(value) - 1900,
+ .tm_mon = PyDateTime_GET_MONTH(value) - 1,
+ .tm_mday = PyDateTime_GET_DAY(value),
+ .tm_hour = PyDateTime_DATE_GET_HOUR(value),
+ .tm_min = PyDateTime_DATE_GET_MINUTE(value),
+ .tm_sec = PyDateTime_DATE_GET_SECOND(value),
+ .tm_isdst = 0,
+ };
+
+ // Convert into time_t
+ const time_t t = mktime(&tm);
+ if (t < 0) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ return -1;
+ }
+
+ return t;
+}
+
+static PyObject* File_get_ctime(FileObject* self) {
+ const time_t t = pakfire_file_get_ctime(self->file);
+
+ return PyDateTime_FromTime_t(&t);
+}
+
+static int File_set_ctime(FileObject* self, PyObject* value) {
+ const time_t t = PyDateTime_AsTime_t(value);
+ if (t < 0)
+ return -1;
+
+ pakfire_file_set_ctime(self->file, t);
+ return 0;
+}
+
+static PyObject* File_get_mtime(FileObject* self) {
+ const time_t t = pakfire_file_get_mtime(self->file);
+
+ return PyDateTime_FromTime_t(&t);
+}
+
+static int File_set_mtime(FileObject* self, PyObject* value) {
+ const time_t t = PyDateTime_AsTime_t(value);
+ if (t < 0)
+ return -1;
+
+ pakfire_file_set_mtime(self->file, t);
+ return 0;
+}
+
+static struct PyGetSetDef File_getsetters[] = {
+ {
+ "ctime",
+ (getter)File_get_ctime,
+ (setter)File_set_ctime,
+ NULL,
+ NULL,
+ },
+ {
+ "group",
+ (getter)File_get_group,
+ (setter)File_set_group,
+ NULL,
+ NULL,
+ },
+ {
+ "mode",
+ (getter)File_get_mode,
+ (setter)File_set_mode,
+ NULL,
+ NULL,
+ },
+ {
+ "mtime",
+ (getter)File_get_mtime,
+ (setter)File_set_mtime,
+ NULL,
+ NULL,
+ },
+ {
+ "path",
+ (getter)File_get_path,
+ (setter)File_set_path,
+ NULL,
+ NULL,
+ },
+ {
+ "size",
+ (getter)File_get_size,
+ (setter)File_set_size,
+ NULL,
+ NULL,
+ },
+ {
+ "type",
+ (getter)File_get_type,
+ NULL,
+ NULL,
+ NULL,
+ },
+ {
+ "user",
+ (getter)File_get_user,
+ (setter)File_set_user,
+ NULL,
+ NULL,
+ },
+ { NULL },
+};
+
+PyTypeObject FileType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ tp_name: "_pakfire.File",
+ tp_basicsize: sizeof(FileObject),
+ tp_flags: Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
+ tp_new: File_new,
+ tp_dealloc: (destructor)File_dealloc,
+ tp_init: (initproc)File_init,
+ tp_doc: "File object",
+ tp_getset: File_getsetters,
+ tp_repr: (reprfunc)File_repr,
+ tp_str: (reprfunc)File_get_path,
+};