remove builds from db if pkg is deleted

fix apibuilder interval refreshes refreshing widgets not visible
This commit is contained in:
lukas-heiligenbrunner 2024-01-01 17:11:05 +01:00
parent fca5df4c70
commit 02fda58db4
15 changed files with 110 additions and 68 deletions

View File

@ -1,9 +1,6 @@
use crate::repo::repo::{remove_pkg, remove_version};
use rocket::serde::json::Json;
use rocket::serde::Deserialize;
use rocket::{post, State};
use rocket_okapi::okapi::schemars;
use rocket_okapi::{openapi, JsonSchema};
use rocket_okapi::openapi;
use sea_orm::DatabaseConnection;
#[openapi(tag = "test")]

View File

@ -1,7 +1,7 @@
use crate::aur::aur::download_pkgbuild;
use crate::db::prelude::Packages;
use crate::db::prelude::Versions;
use crate::db::versions;
use crate::db::prelude::{Builds, Packages};
use crate::db::{builds, versions};
use crate::pkgbuild::build::build_pkgbuild;
use anyhow::anyhow;
use sea_orm::{ColumnTrait, DatabaseConnection, EntityTrait, ModelTrait, QueryFilter};
@ -39,6 +39,49 @@ pub async fn add_pkg(
Ok(pkg_file_name)
}
pub async fn remove_pkg(db: &DatabaseConnection, pkg_id: i32) -> anyhow::Result<()> {
let pkg = Packages::find_by_id(pkg_id)
.one(db)
.await?
.ok_or(anyhow!("id not found"))?;
fs::remove_dir_all(format!("./builds/{}", pkg.name))?;
let versions = Versions::find()
.filter(versions::Column::PackageId.eq(pkg.id))
.all(db)
.await?;
for v in versions {
rem_ver(db, v).await?;
}
// remove corresponding builds
let builds = Builds::find()
.filter(builds::Column::PkgId.eq(pkg.id))
.all(db)
.await?;
for b in builds {
b.delete(db).await?;
}
// remove package db entry
pkg.delete(db).await?;
Ok(())
}
pub async fn remove_version(db: &DatabaseConnection, version_id: i32) -> anyhow::Result<()> {
let version = Versions::find()
.filter(versions::Column::PackageId.eq(version_id))
.one(db)
.await?;
if let Some(version) = version {
rem_ver(db, version).await?;
}
Ok(())
}
fn repo_add(pkg_file_name: String) -> anyhow::Result<()> {
let db_file = format!("{REPO_NAME}.db.tar.gz");
@ -79,40 +122,6 @@ fn repo_remove(pkg_file_name: String) -> anyhow::Result<()> {
Ok(())
}
pub async fn remove_pkg(db: &DatabaseConnection, pkg_id: i32) -> anyhow::Result<()> {
let pkg = Packages::find_by_id(pkg_id)
.one(db)
.await?
.ok_or(anyhow!("id not found"))?;
fs::remove_dir_all(format!("./builds/{}", pkg.name))?;
let versions = Versions::find()
.filter(versions::Column::PackageId.eq(pkg.id))
.all(db)
.await?;
for v in versions {
rem_ver(db, v).await?;
}
// remove package db entry
pkg.delete(db).await?;
Ok(())
}
pub async fn remove_version(db: &DatabaseConnection, version_id: i32) -> anyhow::Result<()> {
let version = Versions::find()
.filter(versions::Column::PackageId.eq(version_id))
.one(db)
.await?;
if let Some(version) = version {
rem_ver(db, version).await?;
}
Ok(())
}
async fn rem_ver(db: &DatabaseConnection, version: versions::Model) -> anyhow::Result<()> {
if let Some(filename) = version.file_name.clone() {
// so repo-remove only supports passing a package name and removing the whole package

View File

@ -2,8 +2,9 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:visibility_detector/visibility_detector.dart';
import 'BaseProvider.dart';
import '../../providers/BaseProvider.dart';
class APIBuilder<T extends BaseProvider, K, DTO> extends StatefulWidget {
const APIBuilder(
@ -25,6 +26,7 @@ class APIBuilder<T extends BaseProvider, K, DTO> extends StatefulWidget {
class _APIBuilderState<T extends BaseProvider, K, DTO>
extends State<APIBuilder<T, K, DTO>> {
Timer? timer;
bool visible = true;
@override
void initState() {
@ -33,12 +35,10 @@ class _APIBuilderState<T extends BaseProvider, K, DTO>
if (widget.interval != null) {
timer = Timer.periodic(widget.interval!, (Timer t) {
final RenderObject? box = context.findRenderObject();
print(box);
print(context.mounted);
Provider.of<T>(context, listen: false)
.refresh(context, dto: widget.dto);
if (visible) {
Provider.of<T>(context, listen: false)
.refresh(context, dto: widget.dto);
}
});
}
}
@ -53,15 +53,30 @@ class _APIBuilderState<T extends BaseProvider, K, DTO>
Widget build(BuildContext context) {
final Future<K> fut = Provider.of<T>(context).data as Future<K>;
return FutureBuilder<K>(
future: fut,
builder: (context, snapshot) {
if (snapshot.hasData) {
return widget.onData(snapshot.data!);
} else {
return widget.onLoad();
return VisibilityDetector(
key: widget.key ?? const Key("APIBuilder"),
onVisibilityChanged: (visibilityInfo) {
var visiblePercentage = visibilityInfo.visibleFraction * 100;
if (mounted) {
setState(() {
visible = visiblePercentage != 0;
});
}
debugPrint(
'Widget ${visibilityInfo.key} is ${visiblePercentage}% visible');
},
child: FutureBuilder<K>(
future: fut,
builder: (context, snapshot) {
if (snapshot.hasData) {
return widget.onData(snapshot.data!);
} else {
return widget.onLoad();
}
},
),
);
}
}

View File

@ -4,7 +4,7 @@ import 'package:aurcache/api/builds.dart';
import 'package:aurcache/components/builds_table.dart';
import 'package:aurcache/models/build.dart';
import 'package:aurcache/components/dashboard/your_packages.dart';
import 'package:aurcache/providers/APIBuilder.dart';
import 'package:aurcache/components/api/APIBuilder.dart';
import 'package:aurcache/providers/builds_provider.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
@ -41,6 +41,7 @@ class _RecentBuildsState extends State<RecentBuilds> {
SizedBox(
width: double.infinity,
child: APIBuilder<BuildsProvider, List<Build>, BuildsDTO>(
key: const Key("Builds on dashboard"),
dto: BuildsDTO(limit: 10),
interval: const Duration(seconds: 10),
onLoad: () => const Text("no data"),

View File

@ -1,7 +1,7 @@
import 'dart:async';
import 'package:aurcache/api/packages.dart';
import 'package:aurcache/providers/APIBuilder.dart';
import 'package:aurcache/components/api/APIBuilder.dart';
import 'package:aurcache/providers/packages_provider.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
@ -44,7 +44,7 @@ class _YourPackagesState extends State<YourPackages> {
child: SizedBox(
width: double.infinity,
child: APIBuilder<PackagesProvider, List<Package>, Object>(
key: GlobalKey(),
key: Key("Packages on dashboard"),
interval: const Duration(seconds: 10),
onData: (data) {
return DataTable(

View File

@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import '../utils/responsive.dart';
import '../screens/dashboard_screen.dart';
import '../../utils/responsive.dart';
import '../../screens/dashboard_screen.dart';
import 'side_menu.dart';
class MenuShell extends StatelessWidget {

View File

@ -1,7 +1,7 @@
import 'package:aurcache/screens/build_screen.dart';
import 'package:aurcache/screens/builds_screen.dart';
import 'package:aurcache/screens/dashboard_screen.dart';
import 'package:aurcache/components/menu_shell.dart';
import 'package:aurcache/components/routing/menu_shell.dart';
import 'package:aurcache/screens/package_screen.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

View File

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:go_router/go_router.dart';
import '../constants/color_constants.dart';
import '../../constants/color_constants.dart';
class SideMenu extends StatelessWidget {
const SideMenu({
@ -86,7 +86,7 @@ class DrawerListTile extends StatelessWidget {
),
title: Text(
title,
style: TextStyle(color: Colors.white54),
style: const TextStyle(color: Colors.white54),
),
);
}

View File

@ -1,4 +1,4 @@
import 'package:aurcache/components/router.dart';
import 'package:aurcache/components/routing/router.dart';
import 'package:aurcache/providers/build_provider.dart';
import 'package:aurcache/providers/builds_provider.dart';
import 'package:aurcache/providers/package_provider.dart';

View File

@ -3,7 +3,7 @@ import 'dart:async';
import 'package:aurcache/api/builds.dart';
import 'package:aurcache/components/build_output.dart';
import 'package:aurcache/models/build.dart';
import 'package:aurcache/providers/APIBuilder.dart';
import 'package:aurcache/components/api/APIBuilder.dart';
import 'package:aurcache/providers/build_provider.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

View File

@ -1,5 +1,5 @@
import 'package:aurcache/components/builds_table.dart';
import 'package:aurcache/providers/APIBuilder.dart';
import 'package:aurcache/components/api/APIBuilder.dart';
import 'package:aurcache/providers/builds_provider.dart';
import 'package:flutter/material.dart';
import '../constants/color_constants.dart';

View File

@ -1,5 +1,5 @@
import 'package:aurcache/api/statistics.dart';
import 'package:aurcache/providers/APIBuilder.dart';
import 'package:aurcache/components/api/APIBuilder.dart';
import 'package:aurcache/providers/stats_provider.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

View File

@ -2,10 +2,11 @@ import 'dart:async';
import 'package:aurcache/api/builds.dart';
import 'package:aurcache/api/packages.dart';
import 'package:aurcache/providers/APIBuilder.dart';
import 'package:aurcache/components/api/APIBuilder.dart';
import 'package:aurcache/providers/builds_provider.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import '../api/API.dart';
import '../components/builds_table.dart';
@ -15,6 +16,7 @@ import '../models/build.dart';
import '../models/package.dart';
import '../providers/package_provider.dart';
import '../providers/packages_provider.dart';
import '../providers/stats_provider.dart';
class PackageScreen extends StatefulWidget {
const PackageScreen({super.key, required this.pkgID});
@ -61,6 +63,15 @@ class _PackageScreenState extends State<PackageScreen> {
final succ = await API.deletePackage(pkg.id);
if (succ) {
context.pop();
Provider.of<PackagesProvider>(context,
listen: false)
.refresh(context);
Provider.of<BuildsProvider>(context,
listen: false)
.refresh(context);
Provider.of<StatsProvider>(context, listen: false)
.refresh(context);
}
},
child: const Text(
@ -92,7 +103,7 @@ class _PackageScreenState extends State<PackageScreen> {
width: double.infinity,
child: APIBuilder<BuildsProvider, List<Build>,
BuildsDTO>(
key: GlobalKey(),
key: const Key("Builds on Package info"),
dto: BuildsDTO(pkgID: pkg.id),
interval: const Duration(seconds: 5),
onData: (data) {

View File

@ -405,6 +405,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
visibility_detector:
dependency: "direct main"
description:
name: visibility_detector
sha256: dd5cc11e13494f432d15939c3aa8ae76844c42b723398643ce9addb88a5ed420
url: "https://pub.dev"
source: hosted
version: "0.4.0+2"
web:
dependency: transitive
description:

View File

@ -41,6 +41,7 @@ dependencies:
dio: ^5.3.3
go_router: ^13.0.0
provider: ^6.1.1
visibility_detector: ^0.4.0+2
dev_dependencies:
flutter_test: