mirror of
https://github.com/KDE/kasts.git
synced 2024-12-10 07:36:07 +01:00
Initial Commit
This commit is contained in:
commit
5ae34b56f7
88
.clang-format
Normal file
88
.clang-format
Normal file
@ -0,0 +1,88 @@
|
||||
---
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
# Copyright (C) 2019 Christoph Cullmann <cullmann@kde.org>
|
||||
# Copyright (C) 2019 Gernot Gebhard <gebhard@absint.com>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
# Style for C++
|
||||
Language: Cpp
|
||||
|
||||
# base is WebKit coding style: https://webkit.org/code-style-guidelines/
|
||||
# below are only things set that diverge from this style!
|
||||
BasedOnStyle: WebKit
|
||||
|
||||
# enforce C++11 (e.g. for std::vector<std::vector<lala>>
|
||||
Standard: Cpp11
|
||||
|
||||
# 4 spaces indent
|
||||
TabWidth: 4
|
||||
|
||||
# 3 * 80 wide lines
|
||||
ColumnLimit: 240
|
||||
|
||||
# sort includes inside line separated groups
|
||||
SortIncludes: true
|
||||
|
||||
# break before braces on function, namespace and class definitions.
|
||||
BreakBeforeBraces: Linux
|
||||
|
||||
# CrlInstruction *a;
|
||||
PointerAlignment: Right
|
||||
|
||||
# horizontally aligns arguments after an open bracket.
|
||||
AlignAfterOpenBracket: Align
|
||||
|
||||
# align trailing comments
|
||||
AlignTrailingComments: true
|
||||
|
||||
# don't move all parameters to new line
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
|
||||
# no single line functions
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
|
||||
# always break before you encounter multi line strings
|
||||
AlwaysBreakBeforeMultilineStrings: true
|
||||
|
||||
# don't move arguments to own lines if they are not all on the same
|
||||
BinPackArguments: false
|
||||
|
||||
# don't move parameters to own lines if they are not all on the same
|
||||
BinPackParameters: false
|
||||
|
||||
# don't break binary ops
|
||||
BreakBeforeBinaryOperators: None
|
||||
|
||||
# format C++11 braced lists like function calls
|
||||
Cpp11BracedListStyle: true
|
||||
|
||||
# remove empty lines
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
|
||||
# no namespace indentation to keep indent level low
|
||||
NamespaceIndentation: None
|
||||
|
||||
# we use template< without space.
|
||||
SpaceAfterTemplateKeyword: false
|
||||
|
||||
# macros for which the opening brace stays attached.
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, forever, Q_FOREVER, QBENCHMARK, QBENCHMARK_ONCE ]
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
build/
|
33
CMakeLists.txt
Executable file
33
CMakeLists.txt
Executable file
@ -0,0 +1,33 @@
|
||||
project(Alligator)
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
set(KF5_MIN_VERSION "5.18.0")
|
||||
set(QT_MIN_VERSION "5.5.0")
|
||||
|
||||
if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
|
||||
message(FATAL_ERROR "This application requires an out of source build. Please create a separate build directory.")
|
||||
endif()
|
||||
|
||||
include(FeatureSummary)
|
||||
|
||||
find_package(ECM 5.67.0 REQUIRED NO_MODULE)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
|
||||
|
||||
include(ECMSetupVersion)
|
||||
include(ECMGenerateHeaders)
|
||||
include(KDEInstallDirs)
|
||||
include(KDECMakeSettings)
|
||||
include(ECMPoQmTools)
|
||||
include(KDECompilerSettings NO_POLICY_SCOPE)
|
||||
|
||||
find_package(Qt5 ${QT_MIN_VERSION} REQUIRED NO_MODULE COMPONENTS Core Quick Test Gui Svg QuickControls2 Sql)
|
||||
find_package(KF5Kirigami2 ${KF5_MIN_VERSION} REQUIRED)
|
||||
find_package(KF5Syndication ${KF5_MIN_VERSION} REQUIRED)
|
||||
find_package(KF5KIO ${KF5_MIN_VERSION} REQUIRED)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
add_subdirectory(src)
|
||||
|
||||
feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)
|
4
README.md
Executable file
4
README.md
Executable file
@ -0,0 +1,4 @@
|
||||
# Alligator
|
||||
|
||||
Alligator is an RSS/Atom feed reader, currently under development.
|
||||
|
14
src/CMakeLists.txt
Executable file
14
src/CMakeLists.txt
Executable file
@ -0,0 +1,14 @@
|
||||
set(alligator_SRCS
|
||||
main.cpp
|
||||
feedListModel.cpp
|
||||
entryListModel.cpp
|
||||
fetcher.cpp
|
||||
feed.cpp
|
||||
entry.cpp
|
||||
resources.qrc
|
||||
)
|
||||
|
||||
add_executable(alligator ${alligator_SRCS} ${RESOURCES})
|
||||
target_link_libraries(alligator Qt5::Core Qt5::Qml Qt5::Quick Qt5::Svg Qt5::Sql KF5::KIOCore KF5::KIOFileWidgets KF5::KIONTLM KF5::Syndication)
|
||||
|
||||
install(TARGETS alligator ${KF5_INSTALL_TARGETS_DEFAULT_ARGS})
|
80
src/contents/ui/EntryListPage.qml
Executable file
80
src/contents/ui/EntryListPage.qml
Executable file
@ -0,0 +1,80 @@
|
||||
/**
|
||||
* Copyright 2020 Tobias Fella <fella@posteo.de>
|
||||
*
|
||||
* 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) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 2.10 as Controls
|
||||
|
||||
import org.kde.kirigami 2.4 as Kirigami
|
||||
|
||||
import org.kde.alligator 1.0
|
||||
|
||||
Kirigami.ScrollablePage {
|
||||
id: page
|
||||
property string name
|
||||
property string url
|
||||
title: name
|
||||
|
||||
contextualActions: [
|
||||
Kirigami.Action {
|
||||
text: "Details"
|
||||
onTriggered: ;//pageStack.push("qrc:/qml/FeedDetailsPage.qml", {"modelData": atomModel})
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
Component.onCompleted: {
|
||||
entryListModel.fetch(url);
|
||||
}
|
||||
|
||||
ListView {
|
||||
model: EntryListModel {
|
||||
id: entryListModel
|
||||
feed: url
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: entryListModel
|
||||
}
|
||||
|
||||
delegate: Kirigami.SwipeListItem {
|
||||
Controls.Label {
|
||||
id: postTitle
|
||||
width: parent.width
|
||||
text: model.display
|
||||
color: model.read ? Kirigami.Theme.disabledTextColor : Kirigami.Theme.textColor
|
||||
}
|
||||
|
||||
actions: [
|
||||
Kirigami.Action {
|
||||
icon.name: model.bookmark ? "bookmark-remove" : "bookmark-new"
|
||||
text: "Bookmark"
|
||||
onTriggered: {
|
||||
model.bookmark = !model.bookmark
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
onClicked: {
|
||||
model.read = true;
|
||||
//pageStack.push("qrc:/qml/EntryDetailsPage.qml", {"modelData": model})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
97
src/contents/ui/FeedListPage.qml
Normal file
97
src/contents/ui/FeedListPage.qml
Normal file
@ -0,0 +1,97 @@
|
||||
/**
|
||||
* Copyright 2020 Tobias Fella <fella@posteo.de>
|
||||
*
|
||||
* 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) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Controls 2.10 as Controls
|
||||
import QtQuick.Layouts 1.12
|
||||
|
||||
import org.kde.kirigami 2.4 as Kirigami
|
||||
|
||||
import org.kde.alligator 1.0
|
||||
|
||||
Component {
|
||||
Kirigami.ScrollablePage {
|
||||
title: "Alligator"
|
||||
|
||||
contextualActions: [
|
||||
Kirigami.Action {
|
||||
text: "Add feed"
|
||||
onTriggered: {
|
||||
addSheet.open()
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
Kirigami.OverlaySheet {
|
||||
id: addSheet
|
||||
contentItem: Kirigami.FormLayout {
|
||||
Controls.TextField {
|
||||
id: urlField
|
||||
Layout.fillWidth: true
|
||||
//placeholderText: "https://example.org/feed.xml"
|
||||
text: "https://rss.golem.de/rss.php?feed=RSS2.0"
|
||||
Kirigami.FormData.label: "Url"
|
||||
}
|
||||
Controls.Button {
|
||||
text: "Add"
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
enabled: urlField.text
|
||||
onClicked: {
|
||||
feedListModel.add_feed(urlField.text)
|
||||
addSheet.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
anchors.fill: parent
|
||||
model: FeedListModel {
|
||||
id: feedListModel
|
||||
}
|
||||
|
||||
delegate: Kirigami.SwipeListItem {
|
||||
Controls.Label {
|
||||
text: model.display
|
||||
}
|
||||
|
||||
onTextChanged: console.log(model.display)
|
||||
|
||||
width: parent.width
|
||||
height: Kirigami.Units.gridUnit * 2
|
||||
actions: [
|
||||
Kirigami.Action {
|
||||
icon.name: "list-remove"
|
||||
text: "Remove"
|
||||
onTriggered: feedListModel.remove_feed(index)
|
||||
},
|
||||
Kirigami.Action {
|
||||
icon.name: "document-edit"
|
||||
text: "Edit"
|
||||
onTriggered:; //TODO
|
||||
}
|
||||
]
|
||||
onClicked: {
|
||||
pageStack.push("qrc:/EntryListPage.qml", {"name": model.display, "url": model.url})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
40
src/contents/ui/main.qml
Executable file
40
src/contents/ui/main.qml
Executable file
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Copyright 2020 Tobias Fella <fella@posteo.de>
|
||||
*
|
||||
* 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) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import QtQuick 2.1
|
||||
import QtQuick.Controls 2.0 as Controls
|
||||
|
||||
import org.kde.kirigami 2.4 as Kirigami
|
||||
|
||||
Kirigami.ApplicationWindow {
|
||||
id: root
|
||||
|
||||
title: "Alligator"
|
||||
|
||||
pageStack.initialPage: feedList
|
||||
|
||||
contextDrawer: Kirigami.ContextDrawer {
|
||||
id: contextDrawer
|
||||
}
|
||||
|
||||
FeedListPage {
|
||||
id: feedList
|
||||
}
|
||||
}
|
60
src/entry.cpp
Normal file
60
src/entry.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
/**
|
||||
* Copyright 2020 Tobias Fella <fella@posteo.de>
|
||||
*
|
||||
* 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) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "entry.h"
|
||||
|
||||
Entry::Entry(const QString title, const bool bookmark, const bool read)
|
||||
: m_title(title)
|
||||
, m_bookmark(bookmark)
|
||||
, m_read(read)
|
||||
{
|
||||
}
|
||||
|
||||
Entry::Entry(const Entry &other)
|
||||
: m_title(other.title())
|
||||
, m_bookmark(other.isBookmark())
|
||||
, m_read(other.isRead())
|
||||
{
|
||||
}
|
||||
|
||||
bool Entry::isRead() const
|
||||
{
|
||||
return m_read;
|
||||
}
|
||||
|
||||
bool Entry::isBookmark() const
|
||||
{
|
||||
return m_bookmark;
|
||||
}
|
||||
|
||||
QString Entry::title() const
|
||||
{
|
||||
return m_title;
|
||||
}
|
||||
|
||||
void Entry::setRead(bool read)
|
||||
{
|
||||
m_read = read;
|
||||
}
|
||||
|
||||
void Entry::setBookmark(bool bookmark)
|
||||
{
|
||||
m_bookmark = bookmark;
|
||||
}
|
42
src/entry.h
Normal file
42
src/entry.h
Normal file
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Copyright 2020 Tobias Fella <fella@posteo.de>
|
||||
*
|
||||
* 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) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
|
||||
class Entry
|
||||
{
|
||||
public:
|
||||
Entry(const Entry &);
|
||||
Entry(const QString title, const bool bookmark, const bool read);
|
||||
|
||||
QString title() const;
|
||||
bool isBookmark() const;
|
||||
bool isRead() const;
|
||||
|
||||
void setRead(bool read);
|
||||
void setBookmark(bool bookmark);
|
||||
|
||||
private:
|
||||
QString m_title;
|
||||
bool m_bookmark;
|
||||
bool m_read;
|
||||
};
|
92
src/entryListModel.cpp
Normal file
92
src/entryListModel.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Copyright 2020 Tobias Fella <fella@posteo.de>
|
||||
*
|
||||
* 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) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <QSqlDatabase>
|
||||
#include <QSqlQuery>
|
||||
#include <QVector>
|
||||
|
||||
#include <syndication.h>
|
||||
|
||||
#include "entryListModel.h"
|
||||
#include "fetcher.h"
|
||||
|
||||
EntryListModel::EntryListModel(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QVariant EntryListModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (role == Bookmark)
|
||||
return QVariant(m_entries[index.row()].isBookmark());
|
||||
if (role == Read)
|
||||
return QVariant(m_entries[index.row()].isRead());
|
||||
if (role == Qt::DisplayRole)
|
||||
return m_entries[index.row()].title();
|
||||
return QVariant(index.row());
|
||||
}
|
||||
int EntryListModel::rowCount(const QModelIndex &index) const
|
||||
{
|
||||
return m_entries.size();
|
||||
}
|
||||
QHash<int, QByteArray> EntryListModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roleNames;
|
||||
roleNames[Qt::DisplayRole] = "display";
|
||||
roleNames[Bookmark] = "bookmark";
|
||||
roleNames[Read] = "read";
|
||||
return roleNames;
|
||||
}
|
||||
bool EntryListModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (role == Bookmark) {
|
||||
m_entries[index.row()].setBookmark(value.toBool());
|
||||
} else if (role == Read) {
|
||||
m_entries[index.row()].setRead(value.toBool());
|
||||
}
|
||||
emit dataChanged(index, index, QVector<int>({role}));
|
||||
return true;
|
||||
}
|
||||
|
||||
void EntryListModel::fetch()
|
||||
{
|
||||
connect(&Fetcher::instance(), &Fetcher::finished, this, [this]() {
|
||||
beginResetModel();
|
||||
QSqlQuery query = QSqlQuery(QSqlDatabase::database());
|
||||
query.prepare(QStringLiteral("SELECT id, title, content FROM Entries WHERE feed=:feed;"));
|
||||
query.bindValue(QStringLiteral(":feed"), m_feed);
|
||||
query.exec();
|
||||
while (query.next()) {
|
||||
m_entries.append(Entry(query.value(1).toString(), false, false));
|
||||
}
|
||||
endResetModel();
|
||||
});
|
||||
Fetcher::instance().fetch(m_feed);
|
||||
}
|
||||
|
||||
QString EntryListModel::feed() const
|
||||
{
|
||||
return m_feed;
|
||||
}
|
||||
|
||||
void EntryListModel::setFeed(QString feed)
|
||||
{
|
||||
m_feed = feed;
|
||||
}
|
56
src/entryListModel.h
Normal file
56
src/entryListModel.h
Normal file
@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright 2020 Tobias Fella <fella@posteo.de>
|
||||
*
|
||||
* 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) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QObject>
|
||||
|
||||
#include <syndication.h>
|
||||
|
||||
#include "entry.h"
|
||||
|
||||
class EntryListModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString feed READ feed WRITE setFeed NOTIFY feedChanged)
|
||||
public:
|
||||
enum DataRole {
|
||||
Bookmark = Qt::UserRole + 1,
|
||||
Read,
|
||||
};
|
||||
explicit EntryListModel(QObject *parent = nullptr);
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
int rowCount(const QModelIndex &index) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
|
||||
|
||||
QString feed() const;
|
||||
void setFeed(QString feed);
|
||||
|
||||
Q_INVOKABLE void fetch();
|
||||
|
||||
Q_SIGNALS:
|
||||
void feedChanged(QString);
|
||||
|
||||
private:
|
||||
QVector<Entry> m_entries;
|
||||
QString m_feed;
|
||||
};
|
54
src/feed.cpp
Normal file
54
src/feed.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Copyright 2020 Tobias Fella <fella@posteo.de>
|
||||
*
|
||||
* 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) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "feed.h"
|
||||
|
||||
Feed::Feed(const QString url)
|
||||
: m_url(url)
|
||||
, m_name(url)
|
||||
{
|
||||
}
|
||||
|
||||
Feed::Feed(const QString url, const QString name)
|
||||
: m_url(url)
|
||||
, m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
Feed::Feed(const Feed &other)
|
||||
: m_url(other.url())
|
||||
, m_name(other.name())
|
||||
{
|
||||
}
|
||||
|
||||
QString Feed::url() const
|
||||
{
|
||||
return m_url;
|
||||
}
|
||||
|
||||
QString Feed::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void Feed::setName(QString name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
45
src/feed.h
Normal file
45
src/feed.h
Normal file
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Copyright 2020 Tobias Fella <fella@posteo.de>
|
||||
*
|
||||
* 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) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
class Feed : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Feed(const QString url);
|
||||
Feed(const Feed &other);
|
||||
Feed(const QString url, const QString name);
|
||||
|
||||
QString name() const;
|
||||
QString url() const;
|
||||
|
||||
void setName(QString name);
|
||||
|
||||
Q_SIGNALS:
|
||||
void nameChanged(const QString &name);
|
||||
|
||||
private:
|
||||
QString m_url;
|
||||
QString m_name;
|
||||
};
|
87
src/feedListModel.cpp
Normal file
87
src/feedListModel.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
/**
|
||||
* Copyright 2020 Tobias Fella <fella@posteo.de>
|
||||
*
|
||||
* 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) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <QSqlDatabase>
|
||||
#include <QSqlQuery>
|
||||
#include <QUrl>
|
||||
|
||||
#include <syndication.h>
|
||||
|
||||
#include "feedListModel.h"
|
||||
#include "fetcher.h"
|
||||
|
||||
FeedListModel::FeedListModel(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
{
|
||||
QSqlQuery query = QSqlQuery(QSqlDatabase::database());
|
||||
query.exec(QStringLiteral("SELECT name, url FROM Feeds"));
|
||||
beginInsertRows(QModelIndex(), 0, query.size());
|
||||
while (query.next()) {
|
||||
feeds += Feed(query.value(1).toString(), query.value(0).toString());
|
||||
}
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> FeedListModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roleNames;
|
||||
roleNames[Qt::DisplayRole] = "display";
|
||||
roleNames[Url] = "url";
|
||||
return roleNames;
|
||||
}
|
||||
|
||||
QVariant FeedListModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (role == Url)
|
||||
return QVariant(this->feeds[index.row()].url());
|
||||
if (role == Qt::DisplayRole)
|
||||
return QVariant(this->feeds[index.row()].name());
|
||||
return QVariant();
|
||||
}
|
||||
int FeedListModel::rowCount(const QModelIndex &index) const
|
||||
{
|
||||
return this->feeds.size();
|
||||
}
|
||||
|
||||
void FeedListModel::add_feed(QString url)
|
||||
{
|
||||
Fetcher::instance().fetch(QUrl(url));
|
||||
beginInsertRows(QModelIndex(), feeds.size(), feeds.size());
|
||||
feeds.append(Feed(url));
|
||||
endInsertRows();
|
||||
QSqlQuery query = QSqlQuery(QSqlDatabase::database());
|
||||
query.prepare(QStringLiteral("INSERT INTO Feeds VALUES (:url, :name);"));
|
||||
query.bindValue(QStringLiteral(":url"), url);
|
||||
query.bindValue(QStringLiteral(":name"), url);
|
||||
query.exec();
|
||||
}
|
||||
|
||||
void FeedListModel::remove_feed(int index)
|
||||
{
|
||||
Feed toRemove = feeds[index];
|
||||
QSqlQuery query = QSqlQuery(QSqlDatabase::database());
|
||||
query.prepare(QStringLiteral("DELETE FROM Feeds WHERE name=:name AND url=url;"));
|
||||
query.bindValue(QStringLiteral(":url"), toRemove.url());
|
||||
query.bindValue(QStringLiteral(":name"), toRemove.name());
|
||||
query.exec();
|
||||
beginRemoveRows(QModelIndex(), index, index);
|
||||
feeds.remove(index);
|
||||
endRemoveRows();
|
||||
}
|
48
src/feedListModel.h
Normal file
48
src/feedListModel.h
Normal file
@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Copyright 2020 Tobias Fella <fella@posteo.de>
|
||||
*
|
||||
* 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) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QUrl>
|
||||
#include <QVector>
|
||||
|
||||
#include "feed.h"
|
||||
#include "fetcher.h"
|
||||
|
||||
class FeedListModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum DataRole {
|
||||
Url = Qt::UserRole + 1,
|
||||
};
|
||||
explicit FeedListModel(QObject *parent = nullptr);
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
int rowCount(const QModelIndex &index) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
Q_INVOKABLE void add_feed(QString url);
|
||||
Q_INVOKABLE void remove_feed(int index);
|
||||
|
||||
private:
|
||||
QVector<Feed> feeds;
|
||||
};
|
69
src/fetcher.cpp
Normal file
69
src/fetcher.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
/**
|
||||
* Copyright 2020 Tobias Fella <fella@posteo.de>
|
||||
*
|
||||
* 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) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QSqlDatabase>
|
||||
#include <QSqlQuery>
|
||||
|
||||
#include <syndication.h>
|
||||
|
||||
#include "fetcher.h"
|
||||
|
||||
Fetcher::Fetcher() {
|
||||
}
|
||||
|
||||
void Fetcher::fetch(QUrl url)
|
||||
{
|
||||
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
|
||||
manager->setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
|
||||
manager->setStrictTransportSecurityEnabled(true);
|
||||
manager->enableStrictTransportSecurityStore(true);
|
||||
QNetworkRequest request = QNetworkRequest(QUrl(url));
|
||||
QNetworkReply *reply = manager->get(request);
|
||||
connect(reply, &QNetworkReply::finished, this, [this, url, reply]() {
|
||||
QByteArray data = reply->readAll();
|
||||
Syndication::DocumentSource *document = new Syndication::DocumentSource(data, url.toString());
|
||||
Syndication::FeedPtr feed = Syndication::parserCollection()->parse(*document, QStringLiteral("Atom"));
|
||||
|
||||
QSqlDatabase db = QSqlDatabase::database();
|
||||
QSqlQuery query = QSqlQuery(db);
|
||||
|
||||
for (const auto &entry : feed->items()) {
|
||||
query = QSqlQuery(db);
|
||||
query.prepare(QStringLiteral("INSERT INTO Entries VALUES (:feed, :id, :title, :contents);"));
|
||||
query.bindValue(QStringLiteral(":feed"), url.toString());
|
||||
query.bindValue(QStringLiteral(":id"), entry->id());
|
||||
query.bindValue(QStringLiteral(":title"), entry->title());
|
||||
query.bindValue(QStringLiteral(":contents"), entry->content());
|
||||
query.exec();
|
||||
for (const auto &author : entry->authors()) {
|
||||
query = QSqlQuery(db);
|
||||
query.prepare(QStringLiteral("INSERT INTO Authors VALUES(:id, :name, :uri, :email);"));
|
||||
query.bindValue(QStringLiteral(":id"), entry->id());
|
||||
query.bindValue(QStringLiteral(":name"), author->name());
|
||||
query.bindValue(QStringLiteral(":uri"), author->uri());
|
||||
query.bindValue(QStringLiteral(":email"), author->email());
|
||||
query.exec();
|
||||
}
|
||||
}
|
||||
emit finished();
|
||||
});
|
||||
}
|
43
src/fetcher.h
Normal file
43
src/fetcher.h
Normal file
@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Copyright 2020 Tobias Fella <fella@posteo.de>
|
||||
*
|
||||
* 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) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QUrl>
|
||||
|
||||
class Fetcher : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static Fetcher &instance()
|
||||
{
|
||||
static Fetcher _instance;
|
||||
return _instance;
|
||||
}
|
||||
void fetch(QUrl);
|
||||
|
||||
private:
|
||||
Fetcher();
|
||||
Fetcher(const Fetcher &);
|
||||
|
||||
Q_SIGNALS:
|
||||
void finished();
|
||||
};
|
65
src/main.cpp
Normal file
65
src/main.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Copyright 2020 Tobias Fella <fella@posteo.de>
|
||||
*
|
||||
* 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) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <QApplication>
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QQuickView>
|
||||
#include <QSqlDatabase>
|
||||
#include <QSqlQuery>
|
||||
#include <QUrl>
|
||||
#include <QStandardPaths>
|
||||
#include <QDir>
|
||||
|
||||
#include "entryListModel.h"
|
||||
#include "feedListModel.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QApplication app(argc, argv);
|
||||
QCoreApplication::setOrganizationName(QStringLiteral("KDE"));
|
||||
QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org"));
|
||||
QCoreApplication::setApplicationName(QStringLiteral("Alligator"));
|
||||
QCoreApplication::setApplicationVersion(QStringLiteral("0.1"));
|
||||
|
||||
qmlRegisterType<FeedListModel>("org.kde.alligator", 1, 0, "FeedListModel");
|
||||
qmlRegisterType<EntryListModel>("org.kde.alligator", 1, 0, "EntryListModel");
|
||||
|
||||
QQmlApplicationEngine engine;
|
||||
|
||||
QSqlDatabase db = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"));
|
||||
QString databasePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
|
||||
QDir(databasePath).mkpath(databasePath);
|
||||
db.setDatabaseName(databasePath + "/database.db3");
|
||||
db.open();
|
||||
|
||||
QSqlQuery query = QSqlQuery(db);
|
||||
query.exec(QStringLiteral("CREATE TABLE IF NOT EXISTS Feeds (name TEXT, url TEXT);"));
|
||||
query.exec(QStringLiteral("CREATE TABLE IF NOT EXISTS Entries (feed TEXT, id TEXT UNIQUE, title TEXT, content TEXT);"));
|
||||
query.exec(QStringLiteral("CREATE TABLE IF NOT EXISTS Authors (id TEXT, name TEXT, uri TEXT, email TEXT);"));
|
||||
|
||||
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
|
||||
|
||||
if (engine.rootObjects().isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return app.exec();
|
||||
}
|
7
src/resources.qrc
Executable file
7
src/resources.qrc
Executable file
@ -0,0 +1,7 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file alias="main.qml">contents/ui/main.qml</file>
|
||||
<file alias="EntryListPage.qml">contents/ui/EntryListPage.qml</file>
|
||||
<file alias="FeedListPage.qml">contents/ui/FeedListPage.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
Loading…
Reference in New Issue
Block a user