diff --git a/Cargo.lock b/Cargo.lock index 50861b4f..2f810421 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,6 +15,8 @@ dependencies = [ "academy_core_coin_impl", "academy_core_config_impl", "academy_core_contact_impl", + "academy_core_course_contracts", + "academy_core_course_impl", "academy_core_finance_contracts", "academy_core_finance_impl", "academy_core_health_impl", @@ -29,6 +31,7 @@ dependencies = [ "academy_core_session_impl", "academy_core_user_contracts", "academy_core_user_impl", + "academy_data", "academy_demo", "academy_di", "academy_email_contracts", @@ -68,6 +71,7 @@ dependencies = [ "academy_core_coin_contracts", "academy_core_config_contracts", "academy_core_contact_contracts", + "academy_core_course_contracts", "academy_core_finance_contracts", "academy_core_health_contracts", "academy_core_heart_contracts", @@ -244,6 +248,35 @@ dependencies = [ "tracing", ] +[[package]] +name = "academy_core_course_contracts" +version = "0.0.0" +dependencies = [ + "academy_models", + "anyhow", + "thiserror 2.0.12", +] + +[[package]] +name = "academy_core_course_impl" +version = "0.0.0" +dependencies = [ + "academy_auth_contracts", + "academy_core_coin_contracts", + "academy_core_course_contracts", + "academy_data", + "academy_demo", + "academy_di", + "academy_email_contracts", + "academy_models", + "academy_persistence_contracts", + "academy_templates_contracts", + "academy_utils", + "anyhow", + "tokio", + "tracing", +] + [[package]] name = "academy_core_finance_contracts" version = "0.0.0" @@ -549,6 +582,18 @@ dependencies = [ "tracing", ] +[[package]] +name = "academy_data" +version = "0.0.0" +dependencies = [ + "academy_models", + "anyhow", + "chrono", + "serde", + "serde_yaml", + "tracing", +] + [[package]] name = "academy_demo" version = "0.0.0" @@ -3763,6 +3808,19 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_yaml" +version = "0.9.34+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + [[package]] name = "sha1" version = "0.10.6" @@ -4451,6 +4509,12 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "323402cff2dd658f39ca17c789b502021b3f18707c91cdf22e3838e1b4023817" +[[package]] +name = "unsafe-libyaml" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + [[package]] name = "untrusted" version = "0.9.0" diff --git a/Cargo.nix b/Cargo.nix index 9eb24bf0..7d40adde 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -177,6 +177,26 @@ rec { # File a bug if you depend on any for non-debug work! debug = internal.debugCrate { inherit packageId; }; }; + "academy_core_course_contracts" = rec { + packageId = "academy_core_course_contracts"; + build = internal.buildRustCrateWithFeatures { + packageId = "academy_core_course_contracts"; + }; + + # Debug support which might change between releases. + # File a bug if you depend on any for non-debug work! + debug = internal.debugCrate { inherit packageId; }; + }; + "academy_core_course_impl" = rec { + packageId = "academy_core_course_impl"; + build = internal.buildRustCrateWithFeatures { + packageId = "academy_core_course_impl"; + }; + + # Debug support which might change between releases. + # File a bug if you depend on any for non-debug work! + debug = internal.debugCrate { inherit packageId; }; + }; "academy_core_finance_contracts" = rec { packageId = "academy_core_finance_contracts"; build = internal.buildRustCrateWithFeatures { @@ -377,6 +397,16 @@ rec { # File a bug if you depend on any for non-debug work! debug = internal.debugCrate { inherit packageId; }; }; + "academy_data" = rec { + packageId = "academy_data"; + build = internal.buildRustCrateWithFeatures { + packageId = "academy_data"; + }; + + # Debug support which might change between releases. + # File a bug if you depend on any for non-debug work! + debug = internal.debugCrate { inherit packageId; }; + }; "academy_demo" = rec { packageId = "academy_demo"; build = internal.buildRustCrateWithFeatures { @@ -642,6 +672,14 @@ rec { name = "academy_core_contact_impl"; packageId = "academy_core_contact_impl"; } + { + name = "academy_core_course_contracts"; + packageId = "academy_core_course_contracts"; + } + { + name = "academy_core_course_impl"; + packageId = "academy_core_course_impl"; + } { name = "academy_core_finance_contracts"; packageId = "academy_core_finance_contracts"; @@ -698,6 +736,10 @@ rec { name = "academy_core_user_impl"; packageId = "academy_core_user_impl"; } + { + name = "academy_data"; + packageId = "academy_data"; + } { name = "academy_demo"; packageId = "academy_demo"; @@ -883,6 +925,10 @@ rec { name = "academy_core_contact_contracts"; packageId = "academy_core_contact_contracts"; } + { + name = "academy_core_course_contracts"; + packageId = "academy_core_course_contracts"; + } { name = "academy_core_finance_contracts"; packageId = "academy_core_finance_contracts"; @@ -1597,6 +1643,123 @@ rec { } ]; + }; + "academy_core_course_contracts" = rec { + crateName = "academy_core_course_contracts"; + version = "0.0.0"; + edition = "2024"; + src = lib.cleanSourceWith { filter = sourceFilter; src = ./academy_core/course/contracts; }; + dependencies = [ + { + name = "academy_models"; + packageId = "academy_models"; + } + { + name = "anyhow"; + packageId = "anyhow"; + usesDefaultFeatures = false; + features = [ "std" ]; + } + { + name = "thiserror"; + packageId = "thiserror 2.0.12"; + usesDefaultFeatures = false; + } + ]; + + }; + "academy_core_course_impl" = rec { + crateName = "academy_core_course_impl"; + version = "0.0.0"; + edition = "2024"; + src = lib.cleanSourceWith { filter = sourceFilter; src = ./academy_core/course/impl; }; + dependencies = [ + { + name = "academy_auth_contracts"; + packageId = "academy_auth_contracts"; + } + { + name = "academy_core_coin_contracts"; + packageId = "academy_core_coin_contracts"; + } + { + name = "academy_core_course_contracts"; + packageId = "academy_core_course_contracts"; + } + { + name = "academy_data"; + packageId = "academy_data"; + } + { + name = "academy_di"; + packageId = "academy_di"; + } + { + name = "academy_email_contracts"; + packageId = "academy_email_contracts"; + } + { + name = "academy_models"; + packageId = "academy_models"; + } + { + name = "academy_persistence_contracts"; + packageId = "academy_persistence_contracts"; + } + { + name = "academy_templates_contracts"; + packageId = "academy_templates_contracts"; + } + { + name = "academy_utils"; + packageId = "academy_utils"; + } + { + name = "anyhow"; + packageId = "anyhow"; + usesDefaultFeatures = false; + features = [ "std" ]; + } + { + name = "tracing"; + packageId = "tracing"; + usesDefaultFeatures = false; + features = [ "attributes" ]; + } + ]; + devDependencies = [ + { + name = "academy_auth_contracts"; + packageId = "academy_auth_contracts"; + features = [ "mock" ]; + } + { + name = "academy_core_coin_contracts"; + packageId = "academy_core_coin_contracts"; + features = [ "mock" ]; + } + { + name = "academy_demo"; + packageId = "academy_demo"; + } + { + name = "academy_email_contracts"; + packageId = "academy_email_contracts"; + features = [ "mock" ]; + } + { + name = "academy_persistence_contracts"; + packageId = "academy_persistence_contracts"; + features = [ "mock" ]; + } + { + name = "tokio"; + packageId = "tokio"; + usesDefaultFeatures = false; + features = [ "rt-multi-thread" "macros" "sync" "fs" "process" ]; + } + ]; + }; "academy_core_finance_contracts" = rec { crateName = "academy_core_finance_contracts"; @@ -2989,6 +3152,48 @@ rec { } ]; + }; + "academy_data" = rec { + crateName = "academy_data"; + version = "0.0.0"; + edition = "2024"; + src = lib.cleanSourceWith { filter = sourceFilter; src = ./academy_data; }; + dependencies = [ + { + name = "academy_models"; + packageId = "academy_models"; + } + { + name = "anyhow"; + packageId = "anyhow"; + usesDefaultFeatures = false; + features = [ "std" ]; + } + { + name = "chrono"; + packageId = "chrono"; + usesDefaultFeatures = false; + features = [ "serde" "clock" ]; + } + { + name = "serde"; + packageId = "serde"; + usesDefaultFeatures = false; + features = [ "derive" "std" ]; + } + { + name = "serde_yaml"; + packageId = "serde_yaml"; + usesDefaultFeatures = false; + } + { + name = "tracing"; + packageId = "tracing"; + usesDefaultFeatures = false; + features = [ "attributes" ]; + } + ]; + }; "academy_demo" = rec { crateName = "academy_demo"; @@ -13569,6 +13774,38 @@ rec { } ]; + }; + "serde_yaml" = rec { + crateName = "serde_yaml"; + version = "0.9.34+deprecated"; + edition = "2021"; + sha256 = "0isba1fjyg3l6rxk156k600ilzr8fp7crv82rhal0rxz5qd1m2va"; + authors = [ + "David Tolnay " + ]; + dependencies = [ + { + name = "indexmap"; + packageId = "indexmap"; + } + { + name = "itoa"; + packageId = "itoa"; + } + { + name = "ryu"; + packageId = "ryu"; + } + { + name = "serde"; + packageId = "serde"; + } + { + name = "unsafe-libyaml"; + packageId = "unsafe-libyaml"; + } + ]; + }; "sha1" = rec { crateName = "sha1"; @@ -15733,6 +15970,18 @@ rec { }; resolvedDefaultFeatures = [ "default" "std" ]; }; + "unsafe-libyaml" = rec { + crateName = "unsafe-libyaml"; + version = "0.2.11"; + edition = "2021"; + crateBin = []; + sha256 = "0qdq69ffl3v5pzx9kzxbghzn0fzn266i1xn70y88maybz9csqfk7"; + libName = "unsafe_libyaml"; + authors = [ + "David Tolnay " + ]; + + }; "untrusted" = rec { crateName = "untrusted"; version = "0.9.0"; diff --git a/Cargo.toml b/Cargo.toml index d2020ae8..d334b722 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ members = [ "academy_cache/*", "academy_config", "academy_core/*/*", + "academy_data", "academy_demo", "academy_di", "academy_di_derive", @@ -57,6 +58,8 @@ academy_core_config_contracts.path = "academy_core/config/contracts" academy_core_config_impl.path = "academy_core/config/impl" academy_core_contact_contracts.path = "academy_core/contact/contracts" academy_core_contact_impl.path = "academy_core/contact/impl" +academy_core_course_contracts.path = "academy_core/course/contracts" +academy_core_course_impl.path = "academy_core/course/impl" academy_core_finance_contracts.path = "academy_core/finance/contracts" academy_core_finance_impl.path = "academy_core/finance/impl" academy_core_health_contracts.path = "academy_core/health/contracts" @@ -77,6 +80,7 @@ academy_core_session_contracts.path = "academy_core/session/contracts" academy_core_session_impl.path = "academy_core/session/impl" academy_core_user_contracts.path = "academy_core/user/contracts" academy_core_user_impl.path = "academy_core/user/impl" +academy_data.path = "academy_data" academy_demo.path = "academy_demo" academy_di.path = "academy_di" academy_di_derive.path = "academy_di_derive" diff --git a/academy/Cargo.toml b/academy/Cargo.toml index a759aee5..b1ecc646 100644 --- a/academy/Cargo.toml +++ b/academy/Cargo.toml @@ -20,6 +20,8 @@ academy_core_coin_contracts.workspace = true academy_core_coin_impl.workspace = true academy_core_config_impl.workspace = true academy_core_contact_impl.workspace = true +academy_core_course_contracts.workspace = true +academy_core_course_impl.workspace = true academy_core_finance_contracts.workspace = true academy_core_finance_impl.workspace = true academy_core_health_impl.workspace = true @@ -34,6 +36,7 @@ academy_core_session_contracts.workspace = true academy_core_session_impl.workspace = true academy_core_user_contracts.workspace = true academy_core_user_impl.workspace = true +academy_data.workspace = true academy_demo.workspace = true academy_di.workspace = true academy_email_contracts.workspace = true diff --git a/academy/src/commands/serve.rs b/academy/src/commands/serve.rs index ea7aedba..fa577e9f 100644 --- a/academy/src/commands/serve.rs +++ b/academy/src/commands/serve.rs @@ -1,9 +1,11 @@ use academy_cache_contracts::CacheService; use academy_config::Config; +use academy_data::course::CourseDataRepository; use academy_di::Provide; use academy_email_contracts::EmailService; use academy_persistence_contracts::Database; use academy_persistence_postgres::MigrationStatus; +use anyhow::Context; use tracing::{info, warn}; use crate::{ @@ -54,8 +56,11 @@ pub async fn serve(config: Config) -> anyhow::Result<()> { let email = email::connect(&config.email).await?; email.ping().await?; + let course_repository = CourseDataRepository::load(&config.course.course_dir) + .context("Failed to load course repository")?; + let config_provider = ConfigProvider::new(&config)?; - let mut provider = Provider::new(config_provider, database, cache, email); + let mut provider = Provider::new(config_provider, database, cache, email, course_repository); let server: RestServer = provider.provide(); server.serve().await diff --git a/academy/src/environment/mod.rs b/academy/src/environment/mod.rs index 3a351045..e85da85b 100644 --- a/academy/src/environment/mod.rs +++ b/academy/src/environment/mod.rs @@ -12,6 +12,7 @@ use academy_core_paypal_impl::PaypalFeatureConfig; use academy_core_premium_impl::PremiumFeatureConfig; use academy_core_session_impl::SessionFeatureConfig; use academy_core_user_impl::UserFeatureConfig; +use academy_data::course::CourseDataRepository; use academy_di::provider; use academy_extern_impl::{ paypal::PaypalApiServiceConfig, recaptcha::RecaptchaApiServiceConfig, @@ -34,6 +35,7 @@ provider! { database: Database, cache: Cache, email: Email, + course_repository: CourseDataRepository, ..config: ConfigProvider { // API RestServerConfig, @@ -67,13 +69,20 @@ provider! { } impl Provider { - pub fn new(config: ConfigProvider, database: Database, cache: Cache, email: Email) -> Self { + pub fn new( + config: ConfigProvider, + database: Database, + cache: Cache, + email: Email, + course_repository: CourseDataRepository, + ) -> Self { Self { _cache: Default::default(), database, cache, email, config, + course_repository, } } @@ -89,8 +98,16 @@ impl Provider { let email = crate::email::connect(&config.email) .await .context("Failed to connect to email server")?; + let course_repository = CourseDataRepository::load(&config.course.course_dir) + .context("Failed to load course repository")?; - Ok(Self::new(config_provider, database, cache, email)) + Ok(Self::new( + config_provider, + database, + cache, + email, + course_repository, + )) } } @@ -318,8 +335,10 @@ mod tests { let database = PostgresDatabase::dummy().await; let cache = ValkeyCache::dummy().await; let email = EmailServiceImpl::dummy().await; + let course_repository = CourseDataRepository::default(); - let mut provider = Provider::new(config_provider, database, cache, email); + let mut provider = + Provider::new(config_provider, database, cache, email, course_repository); let _: RestServer = provider.provide(); } } diff --git a/academy/src/environment/types.rs b/academy/src/environment/types.rs index a9bcb02b..5cdf88fa 100644 --- a/academy/src/environment/types.rs +++ b/academy/src/environment/types.rs @@ -8,6 +8,7 @@ use academy_cache_valkey::ValkeyCache; use academy_core_coin_impl::{CoinFeatureServiceImpl, coin::CoinServiceImpl}; use academy_core_config_impl::ConfigFeatureServiceImpl; use academy_core_contact_impl::ContactFeatureServiceImpl; +use academy_core_course_impl::CourseFeatureServiceImpl; use academy_core_finance_impl::{ FinanceFeatureServiceImpl, coin::FinanceCoinServiceImpl, invoice::FinanceInvoiceServiceImpl, }; @@ -42,10 +43,10 @@ use academy_extern_impl::{ render::RenderApiServiceImpl, vat::VatApiServiceImpl, }; use academy_persistence_postgres::{ - PostgresDatabase, coin::PostgresCoinRepository, heart::PostgresHeartRepository, - mfa::PostgresMfaRepository, oauth2::PostgresOAuth2Repository, paypal::PostgresPaypalRepository, - premium::PostgresPremiumRepository, session::PostgresSessionRepository, - user::PostgresUserRepository, + PostgresDatabase, coin::PostgresCoinRepository, course::PostgresCourseRepository, + heart::PostgresHeartRepository, mfa::PostgresMfaRepository, oauth2::PostgresOAuth2Repository, + paypal::PostgresPaypalRepository, premium::PostgresPremiumRepository, + session::PostgresSessionRepository, user::PostgresUserRepository, }; use academy_shared_impl::{ captcha::CaptchaServiceImpl, fs::FsServiceImpl, hash::HashServiceImpl, id::IdServiceImpl, @@ -68,6 +69,7 @@ pub type RestServer = academy_api_rest::RestServer< FinanceFeature, HeartFeature, PremiumFeature, + CourseFeature, Internal, >; @@ -111,6 +113,7 @@ pub type CoinRepo = PostgresCoinRepository; pub type PaypalRepo = PostgresPaypalRepository; pub type HeartRepo = PostgresHeartRepository; pub type PremiumRepo = PostgresPremiumRepository; +pub type CourseRepo = PostgresCourseRepository; // Auth pub type Auth = @@ -231,4 +234,7 @@ pub type PremiumPlan = PremiumPlanServiceImpl; pub type Premium = PremiumServiceImpl; pub type PremiumPurchase = PremiumPurchaseServiceImpl; +pub type CourseFeature = + CourseFeatureServiceImpl; + pub type Internal = InternalServiceImpl; diff --git a/academy_api/rest/Cargo.toml b/academy_api/rest/Cargo.toml index 5062ac5b..63fcb169 100644 --- a/academy_api/rest/Cargo.toml +++ b/academy_api/rest/Cargo.toml @@ -15,6 +15,7 @@ academy_auth_contracts.workspace = true academy_core_coin_contracts.workspace = true academy_core_config_contracts.workspace = true academy_core_contact_contracts.workspace = true +academy_core_course_contracts.workspace = true academy_core_finance_contracts.workspace = true academy_core_health_contracts.workspace = true academy_core_heart_contracts.workspace = true diff --git a/academy_api/rest/src/lib.rs b/academy_api/rest/src/lib.rs index 2147f96e..672bc603 100644 --- a/academy_api/rest/src/lib.rs +++ b/academy_api/rest/src/lib.rs @@ -6,6 +6,7 @@ use std::{ use academy_core_coin_contracts::CoinFeatureService; use academy_core_config_contracts::ConfigFeatureService; use academy_core_contact_contracts::ContactFeatureService; +use academy_core_course_contracts::CourseFeatureService; use academy_core_finance_contracts::FinanceFeatureService; use academy_core_health_contracts::HealthFeatureService; use academy_core_heart_contracts::HeartFeatureService; @@ -57,6 +58,7 @@ pub struct RestServer< Finance, Heart, Premium, + Course, Internal, > { _config: RestServerConfig, @@ -72,6 +74,7 @@ pub struct RestServer< finance: Finance, heart: Heart, premium: Premium, + course: Course, internal: Internal, } @@ -101,6 +104,7 @@ impl< Finance, Heart, Premium, + Course, Internal, > RestServer< @@ -116,6 +120,7 @@ impl< Finance, Heart, Premium, + Course, Internal, > where @@ -131,6 +136,7 @@ where Finance: FinanceFeatureService, Heart: HeartFeatureService, Premium: PremiumFeatureService, + Course: CourseFeatureService, Internal: InternalService, { pub async fn serve(self) -> anyhow::Result<()> { @@ -162,6 +168,7 @@ where routes::finance::TAG, routes::heart::TAG, routes::premium::TAG, + routes::course::TAG, routes::internal::TAG, ] .into_iter() @@ -239,6 +246,7 @@ where .merge(routes::finance::router(self.finance.into())) .merge(routes::heart::router(self.heart.into())) .merge(routes::premium::router(self.premium.into())) + .merge(routes::course::router(self.course.into())) .merge(routes::internal::router(self.internal.into())) } } diff --git a/academy_api/rest/src/models/course.rs b/academy_api/rest/src/models/course.rs new file mode 100644 index 00000000..c112e857 --- /dev/null +++ b/academy_api/rest/src/models/course.rs @@ -0,0 +1,117 @@ +use academy_models::{ + SearchTerm, + course::{ + CourseAuthor, CourseAuthorName, CourseDescription, CourseFilter, CourseId, + CourseLectureTitle, CourseLectureUserSummary, CourseSectionTitle, CourseSectionUserSummary, + CourseTitle, CourseUserSummary, + }, + url::Url, +}; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, JsonSchema)] +pub struct ApiCourseUserSummary { + pub id: CourseId, + pub title: CourseTitle, + pub description: CourseDescription, + pub category: Option, + pub language: Option<&'static str>, + pub image: Option, + pub authors: Vec, + pub price: u64, + pub learnings_goals: Vec, + pub requirements: Vec, + pub last_update: i64, + pub sections: Vec, + pub completed: Option, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, JsonSchema)] +pub struct ApiCourseAuthor { + pub name: CourseAuthorName, + pub url: Option, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, JsonSchema)] +pub struct ApiCourseSectionUserSummary { + pub title: CourseSectionTitle, + pub lectures: Vec, + pub completed: Option, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, JsonSchema)] +pub struct ApiCourseLectureUserSummary { + pub title: CourseLectureTitle, + pub duration: u64, + pub completed: Option, +} + +#[derive(Debug, Clone, PartialEq, Eq, Deserialize, JsonSchema)] +pub struct ApiCourseFilter { + /// Search in `title` + pub search_term: Option, + /// Filter by author + pub author: Option, + /// Return only free (`true`) or unfree (`false`) courses + pub free: Option, +} + +impl From for ApiCourseUserSummary { + fn from(value: CourseUserSummary) -> Self { + Self { + id: value.base.id, + title: value.base.title, + description: value.base.description, + category: None, + language: Some("de"), + image: value.base.image_url, + authors: value.base.authors.into_iter().map(Into::into).collect(), + price: value.base.price, + learnings_goals: vec![], + requirements: vec![], + last_update: value.base.last_update.timestamp(), + sections: value.sections.into_iter().map(Into::into).collect(), + completed: value.completed, + } + } +} + +impl From for ApiCourseAuthor { + fn from(value: CourseAuthor) -> Self { + Self { + name: value.name, + url: value.url, + } + } +} + +impl From for ApiCourseSectionUserSummary { + fn from(value: CourseSectionUserSummary) -> Self { + Self { + title: value.title, + lectures: value.lectures.into_iter().map(Into::into).collect(), + completed: value.completed, + } + } +} + +impl From for ApiCourseLectureUserSummary { + fn from(value: CourseLectureUserSummary) -> Self { + Self { + title: value.title, + duration: value.duration.as_secs(), + completed: value.completed, + } + } +} + +impl From for CourseFilter { + fn from(value: ApiCourseFilter) -> Self { + Self { + search_term: value.search_term, + author: value.author, + free: value.free, + } + } +} diff --git a/academy_api/rest/src/models/mod.rs b/academy_api/rest/src/models/mod.rs index e4cc9c74..afb54511 100644 --- a/academy_api/rest/src/models/mod.rs +++ b/academy_api/rest/src/models/mod.rs @@ -8,6 +8,7 @@ use crate::const_schema; pub mod coin; pub mod contact; +pub mod course; pub mod heart; pub mod oauth2; pub mod premium; diff --git a/academy_api/rest/src/routes/course.rs b/academy_api/rest/src/routes/course.rs new file mode 100644 index 00000000..5cfd2d42 --- /dev/null +++ b/academy_api/rest/src/routes/course.rs @@ -0,0 +1,104 @@ +use std::sync::Arc; + +use academy_core_course_contracts::{CourseFeatureService, CoursePurchaseError}; +use academy_models::course::CourseId; +use aide::{ + axum::{ApiRouter, routing}, + transform::TransformOperation, +}; +use axum::{ + Json, + extract::{Path, Query, State}, + http::StatusCode, + response::{IntoResponse, Response}, +}; +use schemars::JsonSchema; +use serde::Deserialize; + +use crate::{ + docs::TransformOperationExt, + error_code, + errors::{auth_error, auth_error_docs, internal_server_error, internal_server_error_docs}, + extractors::auth::ApiToken, + models::{ + OkResponse, + course::{ApiCourseFilter, ApiCourseUserSummary}, + }, + routes::coin::NotEnoughCoinsError, +}; + +pub const TAG: &str = "Courses"; + +pub fn router(service: Arc) -> ApiRouter<()> { + ApiRouter::new() + .api_route("/skills/courses", routing::get_with(list, list_docs)) + .api_route( + "/skills/course_access/{course_id}", + routing::post_with(purchase, purchase_docs), + ) + .with_state(service) + .with_path_items(|op| op.tag(TAG)) +} + +async fn list( + service: State>, + Query(filter): Query, +) -> Response { + match service.list(filter.into()).await { + Ok(courses) => Json( + courses + .into_iter() + .map(Into::into) + .collect::>(), + ) + .into_response(), + Err(err) => internal_server_error(err), + } +} + +fn list_docs(op: TransformOperation) -> TransformOperation { + op.summary("Return summaries of all courses") + .add_response::>(StatusCode::OK, None) + .with(internal_server_error_docs) +} + +#[derive(Deserialize, JsonSchema)] +struct PurchasePath { + course_id: CourseId, +} + +async fn purchase( + service: State>, + token: ApiToken, + Path(PurchasePath { course_id }): Path, +) -> Response { + match service.purchase(&token.0, course_id).await { + Ok(()) => Json(OkResponse).into_response(), + Err(CoursePurchaseError::CourseNotFound) => CourseNotFoundError.into_response(), + Err(CoursePurchaseError::CourseIsFree) => CourseIsFreeError.into_response(), + Err(CoursePurchaseError::AlreadyPurchased) => AlreadyPurchasedError.into_response(), + Err(CoursePurchaseError::NotEnoughCoins) => NotEnoughCoinsError.into_response(), + Err(CoursePurchaseError::Auth(err)) => auth_error(err), + Err(CoursePurchaseError::Other(err)) => internal_server_error(err), + } +} + +fn purchase_docs(op: TransformOperation) -> TransformOperation { + op.summary("Purchase a course for the authenticated user") + .add_response::(StatusCode::OK, "The course has been purchased.") + .add_error::() + .add_error::() + .add_error::() + .add_error::() + .with(auth_error_docs) + .with(internal_server_error_docs) +} + +error_code! { + /// The course does not exist. + CourseNotFoundError(NOT_FOUND, "Course not found"); + /// The course is free. + CourseIsFreeError(FORBIDDEN, "Course is free"); + /// The user has already purchased this course. + AlreadyPurchasedError(FORBIDDEN, "Already purchased course"); +} diff --git a/academy_api/rest/src/routes/mod.rs b/academy_api/rest/src/routes/mod.rs index 4c68f943..d4204bcf 100644 --- a/academy_api/rest/src/routes/mod.rs +++ b/academy_api/rest/src/routes/mod.rs @@ -1,6 +1,7 @@ pub mod coin; pub mod config; pub mod contact; +pub mod course; pub mod finance; pub mod health; pub mod heart; diff --git a/academy_assets/assets/templates/course_purchase_confirmation.html b/academy_assets/assets/templates/course_purchase_confirmation.html new file mode 100644 index 00000000..0897564a --- /dev/null +++ b/academy_assets/assets/templates/course_purchase_confirmation.html @@ -0,0 +1,8 @@ +{% extends "base" %} +{% block title %}Kaufbestätigung{% endblock title %} +{% block content %} +

+ Danke für den Kauf des Kurses "{{ title }}"! + Wir wünschen dir viel Spaß und Erfolg damit. +

+{% endblock content %} diff --git a/academy_config/src/lib.rs b/academy_config/src/lib.rs index 432d7f13..715e9ae3 100644 --- a/academy_config/src/lib.rs +++ b/academy_config/src/lib.rs @@ -95,6 +95,7 @@ pub struct Config { pub coin: CoinConfig, pub heart: HeartConfig, pub premium: PremiumConfig, + pub course: CourseConfig, pub render: RenderConfig, pub finance: FinanceConfig, pub sentry: Option, @@ -237,6 +238,11 @@ pub struct PremiumConfig { pub yearly_price: u64, } +#[derive(Debug, Deserialize)] +pub struct CourseConfig { + pub course_dir: PathBuf, +} + #[derive(Debug, Deserialize)] pub struct RenderConfig { pub daemon_url: Url, @@ -297,6 +303,7 @@ mod tests { "recaptcha.secret = \"\"", "paypal.client_id = \"\"", "paypal.client_secret = \"\"", + "course.course_dir = \"\"", "render.daemon_url = \"http://localhost:8001\"", "finance.invoices_archive = \"\"", "finance.credit_notes_archive = \"\"", diff --git a/academy_core/course/contracts/Cargo.toml b/academy_core/course/contracts/Cargo.toml new file mode 100644 index 00000000..76751da8 --- /dev/null +++ b/academy_core/course/contracts/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "academy_core_course_contracts" +version.workspace = true +edition.workspace = true +publish.workspace = true +homepage.workspace = true +repository.workspace = true + +[lints] +workspace = true + +[dependencies] +academy_models.workspace = true +anyhow.workspace = true +thiserror.workspace = true diff --git a/academy_core/course/contracts/src/lib.rs b/academy_core/course/contracts/src/lib.rs new file mode 100644 index 00000000..37cb63e4 --- /dev/null +++ b/academy_core/course/contracts/src/lib.rs @@ -0,0 +1,38 @@ +use academy_models::{ + auth::{AccessToken, AuthError}, + course::{CourseFilter, CourseId, CourseUserSummary}, +}; +use thiserror::Error; + +pub trait CourseFeatureService: Send + Sync + 'static { + /// Return summaries of all courses. + fn list( + &self, + filter: CourseFilter, + ) -> impl Future>> + Send; + + /// Purchase a course for the authenticated user. + /// + /// Requires a verified email address. + fn purchase( + &self, + token: &AccessToken, + course_id: CourseId, + ) -> impl Future> + Send; +} + +#[derive(Debug, Error)] +pub enum CoursePurchaseError { + #[error("The course does not exist.")] + CourseNotFound, + #[error("The user has already purchased this course.")] + AlreadyPurchased, + #[error("The course is free.")] + CourseIsFree, + #[error("The user does not have enough coins.")] + NotEnoughCoins, + #[error(transparent)] + Auth(#[from] AuthError), + #[error(transparent)] + Other(#[from] anyhow::Error), +} diff --git a/academy_core/course/impl/Cargo.toml b/academy_core/course/impl/Cargo.toml new file mode 100644 index 00000000..a04cad61 --- /dev/null +++ b/academy_core/course/impl/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "academy_core_course_impl" +version.workspace = true +edition.workspace = true +publish.workspace = true +homepage.workspace = true +repository.workspace = true + +[lints] +workspace = true + +[dependencies] +academy_auth_contracts.workspace = true +academy_core_coin_contracts.workspace = true +academy_core_course_contracts.workspace = true +academy_data.workspace = true +academy_di.workspace = true +academy_email_contracts.workspace = true +academy_models.workspace = true +academy_persistence_contracts.workspace = true +academy_templates_contracts.workspace = true +academy_utils.workspace = true +anyhow.workspace = true +tracing.workspace = true + +[dev-dependencies] +academy_auth_contracts = { workspace = true, features = ["mock"] } +academy_core_coin_contracts = { workspace = true, features = ["mock"] } +academy_demo.workspace = true +academy_email_contracts = { workspace = true, features = ["mock"] } +academy_persistence_contracts = { workspace = true, features = ["mock"] } +tokio.workspace = true diff --git a/academy_core/course/impl/src/lib.rs b/academy_core/course/impl/src/lib.rs new file mode 100644 index 00000000..65297e49 --- /dev/null +++ b/academy_core/course/impl/src/lib.rs @@ -0,0 +1,155 @@ +use academy_auth_contracts::{AuthResultExt, AuthService}; +use academy_core_coin_contracts::coin::{CoinAddCoinsError, CoinService}; +use academy_core_course_contracts::{CourseFeatureService, CoursePurchaseError}; +use academy_data::course::CourseDataRepository; +use academy_di::Build; +use academy_email_contracts::template::TemplateEmailService; +use academy_models::{ + auth::AccessToken, + course::{CourseFilter, CourseId, CourseUserPatchRef, CourseUserSummary}, +}; +use academy_persistence_contracts::{ + Database, Transaction, course::CourseRepository, user::UserRepository, +}; +use academy_templates_contracts::CoursePurchaseConfirmationTemplate; +use academy_utils::{patch::PatchValue, trace_instrument}; +use anyhow::{Context, anyhow}; + +#[cfg(test)] +mod tests; + +#[derive(Debug, Clone, Default, Build)] +pub struct CourseFeatureServiceImpl { + db: Db, + auth: Auth, + coin: Coin, + template_email: TemplateEmail, + user_repo: UserRepo, + course_repo: CourseRepo, + course_data_repo: CourseDataRepository, +} + +impl CourseFeatureService + for CourseFeatureServiceImpl +where + Db: Database, + Auth: AuthService, + Coin: CoinService, + TemplateEmail: TemplateEmailService, + UserRepo: UserRepository, + CourseRepo: CourseRepository, +{ + #[trace_instrument(no_ret, skip(self))] + async fn list(&self, filter: CourseFilter) -> anyhow::Result> { + let mut courses = self + .course_data_repo + .values() + .filter(|&course| { + filter.search_term.as_ref().is_none_or(|search_term| { + course + .base + .title + .to_lowercase() + .contains(&search_term.to_lowercase()) + }) && filter.author.as_ref().is_none_or(|author| { + course + .base + .authors + .iter() + .any(|a| a.name.to_lowercase().contains(&author.to_lowercase())) + }) && filter + .free + .is_none_or(|free| (course.base.price == 0) == free) + }) + .cloned() + .map(Into::into) + .collect::>(); + + if filter.search_term.is_some() { + courses.sort_unstable_by_key(|c| c.base.title.len()); + } else { + courses.sort_unstable_by(|a, b| a.base.title.cmp(&b.base.title)); + } + + Ok(courses) + } + + #[trace_instrument(skip(self))] + async fn purchase( + &self, + token: &AccessToken, + course_id: CourseId, + ) -> Result<(), CoursePurchaseError> { + let auth = self.auth.authenticate(token).await.map_auth_err()?; + auth.ensure_email_verified().map_auth_err()?; + + let course = self + .course_data_repo + .get(&course_id) + .ok_or(CoursePurchaseError::CourseNotFound)?; + + if course.base.price == 0 { + return Err(CoursePurchaseError::CourseIsFree); + } + + let mut txn = self.db.begin_transaction().await?; + + let course_user = self + .course_repo + .get_course_user(&mut txn, &course_id, auth.user_id) + .await?; + if course_user.purchased { + return Err(CoursePurchaseError::AlreadyPurchased); + } + + let transaction_description = format!("Course \"{}\"", *course.base.title) + .try_into() + .map_err(anyhow::Error::from)?; + self.coin + .add_coins( + &mut txn, + auth.user_id, + -(course.base.price as i64), + false, + Some(transaction_description), + false, + ) + .await + .map_err(|err| match err { + CoinAddCoinsError::NotEnoughCoins => CoursePurchaseError::NotEnoughCoins, + CoinAddCoinsError::Other(err) => err.into(), + })?; + + self.course_repo + .update_course_user( + &mut txn, + &course_id, + auth.user_id, + CourseUserPatchRef { + purchased: PatchValue::Update(&true), + }, + ) + .await?; + + let user_composite = self + .user_repo + .get_composite(&mut txn, auth.user_id) + .await? + .ok_or_else(|| anyhow!("Failed to fetch authenticated user"))?; + if let Some(email) = user_composite.user.email { + self.template_email + .send_course_purchase_confirmation_email( + email.with_name(user_composite.profile.display_name.into_inner()), + &CoursePurchaseConfirmationTemplate { + title: course.base.title.clone().into_inner(), + }, + ) + .await + .context("Failed to send course purchase confirmation email")?; + } + + txn.commit().await?; + + Ok(()) + } +} diff --git a/academy_core/course/impl/src/tests/list.rs b/academy_core/course/impl/src/tests/list.rs new file mode 100644 index 00000000..e452a8a3 --- /dev/null +++ b/academy_core/course/impl/src/tests/list.rs @@ -0,0 +1,62 @@ +use academy_core_course_contracts::CourseFeatureService; +use academy_demo::course::{COURSE1, COURSE2}; +use academy_models::course::{CourseFilter, CourseUserSummary}; + +use crate::{ + CourseFeatureServiceImpl, + tests::{Sut, course_data_repo}, +}; + +#[tokio::test] +async fn ok() { + // Arrange + let c1_summary = CourseUserSummary { + base: COURSE1.base.clone(), + sections: vec![], + completed: None, + }; + let c2_summary = CourseUserSummary { + base: COURSE2.base.clone(), + sections: vec![], + completed: None, + }; + + let sut = CourseFeatureServiceImpl { + course_data_repo: course_data_repo(), + ..Sut::default() + }; + + for (filter, expected) in [ + ( + CourseFilter::default(), + vec![c1_summary.clone(), c2_summary.clone()], + ), + ( + CourseFilter { + search_term: Some("course 1".try_into().unwrap()), + ..Default::default() + }, + vec![c1_summary.clone()], + ), + ( + CourseFilter { + author: Some("author 2".try_into().unwrap()), + ..Default::default() + }, + vec![c2_summary.clone()], + ), + ( + CourseFilter { + free: Some(true), + ..Default::default() + }, + vec![c1_summary.clone()], + ), + ] { + // Act + let result = sut.list(filter).await; + + // Assert + assert_eq!(result.unwrap(), expected); + } +} diff --git a/academy_core/course/impl/src/tests/mod.rs b/academy_core/course/impl/src/tests/mod.rs new file mode 100644 index 00000000..0f138c3b --- /dev/null +++ b/academy_core/course/impl/src/tests/mod.rs @@ -0,0 +1,26 @@ +use academy_auth_contracts::MockAuthService; +use academy_core_coin_contracts::coin::MockCoinService; +use academy_data::course::CourseDataRepository; +use academy_demo::course::ALL_COURSES; +use academy_email_contracts::template::MockTemplateEmailService; +use academy_persistence_contracts::{ + MockDatabase, MockTransaction, course::MockCourseRepository, user::MockUserRepository, +}; + +use crate::CourseFeatureServiceImpl; + +mod list; +mod purchase; + +type Sut = CourseFeatureServiceImpl< + MockDatabase, + MockAuthService, + MockCoinService, + MockTemplateEmailService, + MockUserRepository, + MockCourseRepository, +>; + +fn course_data_repo() -> CourseDataRepository { + ALL_COURSES.iter().copied().cloned().collect() +} diff --git a/academy_core/course/impl/src/tests/purchase.rs b/academy_core/course/impl/src/tests/purchase.rs new file mode 100644 index 00000000..69f765ee --- /dev/null +++ b/academy_core/course/impl/src/tests/purchase.rs @@ -0,0 +1,243 @@ +use academy_auth_contracts::MockAuthService; +use academy_core_coin_contracts::coin::{CoinAddCoinsError, MockCoinService}; +use academy_core_course_contracts::{CourseFeatureService, CoursePurchaseError}; +use academy_demo::{ + course::{COURSE1, COURSE2}, + session::{BAR_1, FOO_1}, + user::{BAR, FOO}, +}; +use academy_email_contracts::template::MockTemplateEmailService; +use academy_models::{ + auth::{AuthError, AuthenticateError, AuthorizeError}, + coin::Balance, + course::{CourseUser, CourseUserPatch}, +}; +use academy_persistence_contracts::{ + MockDatabase, course::MockCourseRepository, user::MockUserRepository, +}; +use academy_templates_contracts::CoursePurchaseConfirmationTemplate; +use academy_utils::{assert_matches, patch::PatchValue}; + +use crate::{ + CourseFeatureServiceImpl, + tests::{Sut, course_data_repo}, +}; + +#[tokio::test] +async fn unauthenticated() { + // Arrange + let auth = MockAuthService::new().with_authenticate(None); + + let sut = CourseFeatureServiceImpl { + auth, + ..Sut::default() + }; + + // Act + let result = sut.purchase(&"token".into(), COURSE1.base.id.clone()).await; + + // Assert + assert_matches!( + result, + Err(CoursePurchaseError::Auth(AuthError::Authenticate( + AuthenticateError::InvalidToken + ))) + ); +} + +#[tokio::test] +async fn email_not_verified() { + // Arrange + let auth = MockAuthService::new().with_authenticate(Some((BAR.user.clone(), BAR_1.clone()))); + + let sut = CourseFeatureServiceImpl { + auth, + ..Sut::default() + }; + + // Act + let result = sut.purchase(&"token".into(), COURSE1.base.id.clone()).await; + + // Assert + assert_matches!( + result, + Err(CoursePurchaseError::Auth(AuthError::Authorize( + AuthorizeError::EmailVerified + ))) + ); +} + +#[tokio::test] +async fn course_not_found() { + // Arrange + let auth = MockAuthService::new().with_authenticate(Some((FOO.user.clone(), FOO_1.clone()))); + + let sut = CourseFeatureServiceImpl { + auth, + ..Sut::default() + }; + + // Act + let result = sut.purchase(&"token".into(), COURSE1.base.id.clone()).await; + + // Assert + assert_matches!(result, Err(CoursePurchaseError::CourseNotFound)); +} + +#[tokio::test] +async fn course_is_free() { + // Arrange + let auth = MockAuthService::new().with_authenticate(Some((FOO.user.clone(), FOO_1.clone()))); + + let sut = CourseFeatureServiceImpl { + auth, + course_data_repo: course_data_repo(), + ..Sut::default() + }; + + // Act + let result = sut.purchase(&"token".into(), COURSE1.base.id.clone()).await; + + // Assert + assert_matches!(result, Err(CoursePurchaseError::CourseIsFree)); +} + +#[tokio::test] +async fn already_purchased() { + // Arrange + let auth = MockAuthService::new().with_authenticate(Some((FOO.user.clone(), FOO_1.clone()))); + + let db = MockDatabase::build(false); + + let course_repo = MockCourseRepository::new().with_get_course_user( + COURSE2.base.id.clone(), + FOO.user.id, + CourseUser { + course_id: COURSE2.base.id.clone(), + user_id: FOO.user.id, + purchased: true, + }, + ); + + let sut = CourseFeatureServiceImpl { + auth, + db, + course_data_repo: course_data_repo(), + course_repo, + ..Sut::default() + }; + + // Act + let result = sut.purchase(&"token".into(), COURSE2.base.id.clone()).await; + + // Assert + assert_matches!(result, Err(CoursePurchaseError::AlreadyPurchased)); +} + +#[tokio::test] +async fn not_enough_coins() { + // Arrange + let auth = MockAuthService::new().with_authenticate(Some((FOO.user.clone(), FOO_1.clone()))); + + let db = MockDatabase::build(false); + + let course_repo = MockCourseRepository::new().with_get_course_user( + COURSE2.base.id.clone(), + FOO.user.id, + CourseUser { + course_id: COURSE2.base.id.clone(), + user_id: FOO.user.id, + purchased: false, + }, + ); + + let coin = MockCoinService::new().with_add_coins( + FOO.user.id, + -42, + false, + Some("Course \"Course 2\"".try_into().unwrap()), + false, + Err(CoinAddCoinsError::NotEnoughCoins), + ); + + let sut = CourseFeatureServiceImpl { + auth, + db, + coin, + course_data_repo: course_data_repo(), + course_repo, + ..Sut::default() + }; + + // Act + let result = sut.purchase(&"token".into(), COURSE2.base.id.clone()).await; + + // Assert + assert_matches!(result, Err(CoursePurchaseError::NotEnoughCoins)); +} + +#[tokio::test] +async fn ok() { + // Arrange + let auth = MockAuthService::new().with_authenticate(Some((FOO.user.clone(), FOO_1.clone()))); + + let db = MockDatabase::build(true); + + let course_repo = MockCourseRepository::new() + .with_get_course_user( + COURSE2.base.id.clone(), + FOO.user.id, + CourseUser { + course_id: COURSE2.base.id.clone(), + user_id: FOO.user.id, + purchased: false, + }, + ) + .with_update_course_user( + COURSE2.base.id.clone(), + FOO.user.id, + CourseUserPatch { + purchased: PatchValue::Update(true), + }, + ); + + let coin = MockCoinService::new().with_add_coins( + FOO.user.id, + -42, + false, + Some("Course \"Course 2\"".try_into().unwrap()), + false, + Ok(Balance::default()), + ); + + let user_repo = MockUserRepository::new().with_get_composite(FOO.user.id, Some(FOO.clone())); + + let template_email = MockTemplateEmailService::new() + .with_send_course_purchase_confirmation_email( + FOO.user + .email + .clone() + .unwrap() + .with_name(FOO.profile.display_name.clone().into_inner()), + CoursePurchaseConfirmationTemplate { + title: "Course 2".into(), + }, + true, + ); + + let sut = CourseFeatureServiceImpl { + auth, + db, + coin, + template_email, + user_repo, + course_data_repo: course_data_repo(), + course_repo, + }; + + // Act + let result = sut.purchase(&"token".into(), COURSE2.base.id.clone()).await; + + // Assert + result.unwrap(); +} diff --git a/academy_data/Cargo.toml b/academy_data/Cargo.toml new file mode 100644 index 00000000..2094121c --- /dev/null +++ b/academy_data/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "academy_data" +version.workspace = true +edition.workspace = true +publish.workspace = true +homepage.workspace = true +repository.workspace = true + +[lints] +workspace = true + +[dependencies] +academy_models.workspace = true +anyhow.workspace = true +chrono.workspace = true +serde.workspace = true +serde_yaml = { version = "0.9.34", default-features = false } +tracing.workspace = true diff --git a/academy_data/courses/algorithmen_und_datenstrukturen.yml b/academy_data/courses/algorithmen_und_datenstrukturen.yml new file mode 100644 index 00000000..4deedfc5 --- /dev/null +++ b/academy_data/courses/algorithmen_und_datenstrukturen.yml @@ -0,0 +1,272 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7q2hZHyLJS6IeHQIlyEgKqf +title: "Algorithmen und Datenstrukturen einfach erklärt" +description: | + Dieser Kurs ist ein Must-Have für alle Informatiker. Im Studium eines der Pflichtfächer, mittlerweile sogar in vielen Schulen unterrichtet, so ist Algorithmik und algorithmisches Denken so wichtig wie nie zuvor, denn Algorithmen bestimmen unser Leben. Suchalgorithmen bestimmen, welche Plattformen wir nutzen, welche Inhalte wir sehen und welche Filme und Serien wir konsumieren. Doch wie funktionieren sie? Das lernt ihr hier! + Der Kurs umfasst nicht nur ausgiebige und anschaulich visualisierte Theorie-Lektionen, sondern auch häufige Python Implementierungen der Algorithmen. +category: +language: de +image: https://static.bootstrap.academy/thumbnails/algorithmen.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506775 +sections: + - id: section + title: "Algorithmen und Datenstrukturen einfach erklärt" + description: + lectures: + - id: "eXjay16RMw0" + title: "Einleitung" + description: + type: youtube + video_id: "eXjay16RMw0" + duration: 474 + - id: "pqd6wZVGiPQ" + title: "Bedingungen und ein erstes Beispiel" + description: + type: youtube + video_id: "pqd6wZVGiPQ" + duration: 488 + - id: "grq-eNELcQI" + title: "Algorithmisches Denken und Schleifen" + description: + type: youtube + video_id: "grq-eNELcQI" + duration: 258 + - id: "dwqhrgBQ7vU" + title: "Datenstrukturen" + description: + type: youtube + video_id: "dwqhrgBQ7vU" + duration: 316 + - id: "J9GloHYNkDE" + title: "Laufzeitanalyse und Landau Notation aka O-Notation" + description: + type: youtube + video_id: "J9GloHYNkDE" + duration: 382 + - id: "JH8oogtBd4g" + title: "Das Array" + description: + type: youtube + video_id: "JH8oogtBd4g" + duration: 355 + - id: "i2v_Ve9PUCw" + title: "verkettete Listen: Linked Lists und Double Linked Lists" + description: + type: youtube + video_id: "i2v_Ve9PUCw" + duration: 532 + - id: "wgwLdEg8728" + title: "Queues aka FIFOs und Stacks aka LIFOs" + description: + type: youtube + video_id: "wgwLdEg8728" + duration: 268 + - id: "Z4LjCOr3EC4" + title: "Sets" + description: + type: youtube + video_id: "Z4LjCOr3EC4" + duration: 211 + - id: "CRVHUhW_TeQ" + title: "Maps und HashMaps" + description: + type: youtube + video_id: "CRVHUhW_TeQ" + duration: 486 + - id: "qvi_BND2Kt4" + title: "Die binäre Suche" + description: + type: youtube + video_id: "qvi_BND2Kt4" + duration: 440 + - id: "IrdCeluHpXA" + title: "Die binäre Suche in Python" + description: + type: youtube + video_id: "IrdCeluHpXA" + duration: 826 + - id: "nHYmMvIJsVI" + title: "Selection Sort" + description: + type: youtube + video_id: "nHYmMvIJsVI" + duration: 315 + - id: "AMEr6ikGWPo" + title: "Selection Sort in Python" + description: + type: youtube + video_id: "AMEr6ikGWPo" + duration: 703 + - id: "ZHFxDXSkWNA" + title: "Insertion Sort" + description: + type: youtube + video_id: "ZHFxDXSkWNA" + duration: 247 + - id: "YryPvBq9QZU" + title: "Insertion Sort in Python" + description: + type: youtube + video_id: "YryPvBq9QZU" + duration: 467 + - id: "XMu1Kq69EhU" + title: "Bubble Sort" + description: + type: youtube + video_id: "XMu1Kq69EhU" + duration: 332 + - id: "DAl04rkP5Zg" + title: "Bubble Sort in Python" + description: + type: youtube + video_id: "DAl04rkP5Zg" + duration: 506 + - id: "KjAbdlWYpz8" + title: "Brute Force Algorithmen" + description: + type: youtube + video_id: "KjAbdlWYpz8" + duration: 246 + - id: "JVQoD9YGbV8" + title: "Divide and Conquer Verfahren" + description: + type: youtube + video_id: "JVQoD9YGbV8" + duration: 330 + - id: "lh8Kuu-9Oqc" + title: "Merge Sort: Rekursives Divide and Conquer" + description: + type: youtube + video_id: "lh8Kuu-9Oqc" + duration: 679 + - id: "-aBRB48ug_s" + title: "BogoSort / StupidSort in Python" + description: + type: youtube + video_id: "-aBRB48ug_s" + duration: 624 + - id: "ZSQ7LoQ_u4U" + title: "Merge Sort in Python" + description: + type: youtube + video_id: "ZSQ7LoQ_u4U" + duration: 911 + - id: "EYuVDe2S4Fw" + title: "Quick Sort" + description: + type: youtube + video_id: "EYuVDe2S4Fw" + duration: 590 + - id: "f7D1B0CEleA" + title: "Quick Sort in Python" + description: + type: youtube + video_id: "f7D1B0CEleA" + duration: 1013 + - id: "PUOrROkt3mE" + title: "Big O Notation visualisiert" + description: + type: youtube + video_id: "PUOrROkt3mE" + duration: 613 + - id: "wiogRuZwSVY" + title: "Theta und Omega Notation" + description: + type: youtube + video_id: "wiogRuZwSVY" + duration: 299 + - id: "fLv6wlNGMZg" + title: "Empirische Korrektheitsbeweise" + description: + type: youtube + video_id: "fLv6wlNGMZg" + duration: 384 + - id: "YB6F9d0Udcw" + title: "Mathematische Korrektheitsbeweise: Vollständige Induktion" + description: + type: youtube + video_id: "YB6F9d0Udcw" + duration: 1043 + - id: "hs6MNddIUtw" + title: "Greedy Algorithmen" + description: + type: youtube + video_id: "hs6MNddIUtw" + duration: 169 + - id: "Gdljj8ma2z0" + title: "vorläufiger Abschluss" + description: + type: youtube + video_id: "Gdljj8ma2z0" + duration: 260 + - id: "x0FNeXIGrP8" + title: "Radix LSD Sort - Erklärung" + description: + type: youtube + video_id: "x0FNeXIGrP8" + duration: 523 + - id: "1nMgT0L9b5M" + title: "Radix Sort in Python" + description: + type: youtube + video_id: "1nMgT0L9b5M" + duration: 677 + - id: "zl0ZjOu1Yp8" + title: "Binary Radix Sort in Python" + description: + type: youtube + video_id: "zl0ZjOu1Yp8" + duration: 794 + - id: "nCo7oeLR9qo" + title: "Counting Radix Sort in Python" + description: + type: youtube + video_id: "nCo7oeLR9qo" + duration: 904 + - id: "oJY1FFvLCJA" + title: "Heap Sort - Erklärung" + description: + type: youtube + video_id: "oJY1FFvLCJA" + duration: 499 + - id: "q0TUoijB7wU" + title: "Heap Sort in Python (auf 2 Arten)" + description: + type: youtube + video_id: "q0TUoijB7wU" + duration: 1622 + - id: "h7aOfpFM8DY" + title: "Binary Quicksort / Radix MSD Sort in Python" + description: + type: youtube + video_id: "h7aOfpFM8DY" + duration: 1103 + - id: "NLlSJR5tUok" + title: "Zyklische Listen" + description: + type: youtube + video_id: "NLlSJR5tUok" + duration: 225 + - id: "94AOU1NPPVQ" + title: "Zyklische Listen in Python" + description: + type: youtube + video_id: "94AOU1NPPVQ" + duration: 715 + - id: "R4KrS0joTBQ" + title: "Wie funktionieren eigentlich Suchmaschinen?" + description: + type: youtube + video_id: "R4KrS0joTBQ" + duration: 685 + - id: "JadxmmYkn2E" + title: "Beliebig vs Beliebig aber fest" + description: + type: youtube + video_id: "JadxmmYkn2E" + duration: 738 diff --git a/academy_data/courses/angular_5.yml b/academy_data/courses/angular_5.yml new file mode 100644 index 00000000..1c29a43d --- /dev/null +++ b/academy_data/courses/angular_5.yml @@ -0,0 +1,306 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7pY65LXhI1_bIcOByRhP9Xb +title: "Angular 5" +description: "Angular, das Frontend-Framework von Google, ist überall im Einsatz. Ob mit TypeScript oder JavaScript alles ist möglich. Trotzdem gibt es eine Menge zu beachten!" +category: +language: de +image: https://static.bootstrap.academy/thumbnails/javascript.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1666715365 +sections: + - id: section + title: "Angular 5" + description: + lectures: + - id: "XvemczQn56U" + title: "Einleitung und Installation" + description: + type: youtube + video_id: "XvemczQn56U" + duration: 914 + - id: "eTEEoAFoNNE" + title: "Die IDE" + description: + type: youtube + video_id: "eTEEoAFoNNE" + duration: 241 + - id: "3ctRoI5OJEI" + title: "eine kostenlose IDE - VS-Code" + description: + type: youtube + video_id: "3ctRoI5OJEI" + duration: 738 + - id: "y1-5C0gKTYE" + title: "Konfigurationsparameter" + description: + type: youtube + video_id: "y1-5C0gKTYE" + duration: 711 + - id: "fAdqci1yFCA" + title: "Das App Modul" + description: + type: youtube + video_id: "fAdqci1yFCA" + duration: 318 + - id: "LRQkeCloKcQ" + title: "Bootstrapping" + description: + type: youtube + video_id: "LRQkeCloKcQ" + duration: 249 + - id: "e1BG-y0ffiw" + title: "Komponenten" + description: + type: youtube + video_id: "e1BG-y0ffiw" + duration: 611 + - id: "O4xURo7ze3I" + title: "Eigene Komponenten" + description: + type: youtube + video_id: "O4xURo7ze3I" + duration: 383 + - id: "9slcXcAfBro" + title: "Inline Styles und Inline Templates" + description: + type: youtube + video_id: "9slcXcAfBro" + duration: 242 + - id: "0gQPH2oXcVY" + title: "Interpolation" + description: + type: youtube + video_id: "0gQPH2oXcVY" + duration: 572 + - id: "RjLslYiQzp8" + title: "Events" + description: + type: youtube + video_id: "RjLslYiQzp8" + duration: 263 + - id: "8AH8waXsG9k" + title: "Der Event-Parameter" + description: + type: youtube + video_id: "8AH8waXsG9k" + duration: 629 + - id: "TtpcYbjwaPQ" + title: "Elementreferenzen" + description: + type: youtube + video_id: "TtpcYbjwaPQ" + duration: 313 + - id: "Y3PE6zJPmBI" + title: "Strukturdirektiven: ngFor" + description: + type: youtube + video_id: "Y3PE6zJPmBI" + duration: 400 + - id: "RN2e_eY7xwc" + title: "Strukturdirektiven: ngIf und Else" + description: + type: youtube + video_id: "RN2e_eY7xwc" + duration: 383 + - id: "eBzZSWc7w1g" + title: "Strukturdirektiven: ngSwitch" + description: + type: youtube + video_id: "eBzZSWc7w1g" + duration: 271 + - id: "7X-0ljjgVw8" + title: "einfache Pipes" + description: + type: youtube + video_id: "7X-0ljjgVw8" + duration: 213 + - id: "UjiBtMQvkD0" + title: "Class Bindings" + description: + type: youtube + video_id: "UjiBtMQvkD0" + duration: 446 + - id: "GCdlwTsn3nQ" + title: "Style Bindings" + description: + type: youtube + video_id: "GCdlwTsn3nQ" + duration: 216 + - id: "lXlxk2tcr5A" + title: "Eigene Properties" + description: + type: youtube + video_id: "lXlxk2tcr5A" + duration: 467 + - id: "kTWu_fbN4KY" + title: "Mehr zu Input Properties" + description: + type: youtube + video_id: "kTWu_fbN4KY" + duration: 164 + - id: "ka6h8RG-vbg" + title: "EventEmitter" + description: + type: youtube + video_id: "ka6h8RG-vbg" + duration: 402 + - id: "1sHdh9uFXro" + title: "Konstruktoren, ngOnInit und Services" + description: + type: youtube + video_id: "1sHdh9uFXro" + duration: 301 + - id: "xngMFlSGWaM" + title: "Constructor Injection" + description: + type: youtube + video_id: "xngMFlSGWaM" + duration: 646 + - id: "YeHHtkIiNkA" + title: "Strings injecten" + description: + type: youtube + video_id: "YeHHtkIiNkA" + duration: 307 + - id: "S18Ls1MoYnQ" + title: "Routing" + description: + type: youtube + video_id: "S18Ls1MoYnQ" + duration: 737 + - id: "MNjbhYo6Nbo" + title: "Router Links" + description: + type: youtube + video_id: "MNjbhYo6Nbo" + duration: 183 + - id: "irkpUItriro" + title: "Routenparameter" + description: + type: youtube + video_id: "irkpUItriro" + duration: 522 + - id: "-caV-oTjxAg" + title: "Weitere Tricks und Kniffe beim Routing" + description: + type: youtube + video_id: "-caV-oTjxAg" + duration: 307 + - id: "6uLE96s1u5U" + title: "Styles von aktiven Links" + description: + type: youtube + video_id: "6uLE96s1u5U" + duration: 344 + - id: "4dcUILpa1RU" + title: "Kommunikation mit dem Backend" + description: + type: youtube + video_id: "4dcUILpa1RU" + duration: 683 + - id: "qmnISYTIu5A" + title: "Die ganze Antwort verarbeiten" + description: + type: youtube + video_id: "qmnISYTIu5A" + duration: 342 + - id: "W8Up4RXZB94" + title: "Error-Handling" + description: + type: youtube + video_id: "W8Up4RXZB94" + duration: 683 + - id: "aOzbGq1t61Q" + title: "POST-Requests" + description: + type: youtube + video_id: "aOzbGq1t61Q" + duration: 689 + - id: "ZdsrInsKF78" + title: "Template Driven Forms" + description: + type: youtube + video_id: "ZdsrInsKF78" + duration: 577 + - id: "lH9za-VUVeY" + title: "Template Driven Forms - Control Klassen" + description: + type: youtube + video_id: "lH9za-VUVeY" + duration: 901 + - id: "bLOZD4S6AF4" + title: "Template Driven Forms - Controls gruppieren" + description: + type: youtube + video_id: "bLOZD4S6AF4" + duration: 271 + - id: "rCNUKHes4d8" + title: "Reactive Forms" + description: + type: youtube + video_id: "rCNUKHes4d8" + duration: 646 + - id: "IPoUmVJLC94" + title: "Reactive Forms - Validators" + description: + type: youtube + video_id: "IPoUmVJLC94" + duration: 190 + - id: "qp-X6BZKLMM" + title: "Reactive Forms - eigene Validators" + description: + type: youtube + video_id: "qp-X6BZKLMM" + duration: 323 + - id: "LEYbz1Hbdbo" + title: "eigene Module" + description: + type: youtube + video_id: "LEYbz1Hbdbo" + duration: 574 + - id: "LpdqCZllHuo" + title: "Building und Deployment" + description: + type: youtube + video_id: "LpdqCZllHuo" + duration: 420 + - id: "JuT8NcxG1YE" + title: "Attributdirektiven" + description: + type: youtube + video_id: "JuT8NcxG1YE" + duration: 334 + - id: "VSzz_siluJE" + title: "Events in Direktiven" + description: + type: youtube + video_id: "VSzz_siluJE" + duration: 357 + - id: "k1IoS5UZzBA" + title: "Injection von Parametern" + description: + type: youtube + video_id: "k1IoS5UZzBA" + duration: 347 + - id: "BMAyiMxhzeQ" + title: "ViewChild" + description: + type: youtube + video_id: "BMAyiMxhzeQ" + duration: 544 + - id: "NJyaFEZ5xxc" + title: "Lösung der Colorpicker Übung" + description: + type: youtube + video_id: "NJyaFEZ5xxc" + duration: 1271 + - id: "cbBxK8LySaw" + title: "Lösung der Übung für ViewChild bei Enkelbeziehung" + description: + type: youtube + video_id: "cbBxK8LySaw" + duration: 251 diff --git a/academy_data/courses/anonymitaet_im_internet.yml b/academy_data/courses/anonymitaet_im_internet.yml new file mode 100644 index 00000000..51789011 --- /dev/null +++ b/academy_data/courses/anonymitaet_im_internet.yml @@ -0,0 +1,230 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7on8Ckrk2wo4ySeenf3rgf0 +title: "Anonymität im Internet" +description: | + Anonymität ist heutzutage keine Seltenheit mehr. Leider führt das zu allerlei Problemen - unter anderem auch grundsätzlicher Angreifbarkeit zum Beispiel durch Social Engineering. + In diesem Kurs erfahrt ihr, warum das problematisch ist, welche Methoden es gibt und was ihr tun könnt. +category: +language: de +image: https://static.bootstrap.academy/thumbnails/anonymity.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506827 +sections: + - id: section + title: "Anonymität im Internet" + description: + lectures: + - id: "ecmMXWLudpI" + title: "Ich habe nichts zu verbergen: das digitale Missverständnis des 21. Jahrhunderts" + description: + type: youtube + video_id: "ecmMXWLudpI" + duration: 1327 + - id: "6bpac1NcrZM" + title: "Der Inkognitomodus" + description: + type: youtube + video_id: "6bpac1NcrZM" + duration: 420 + - id: "gGe-3-pw_nA" + title: "IP, Proxy, VPN und Tor" + description: + type: youtube + video_id: "gGe-3-pw_nA" + duration: 697 + - id: "wdPVt6m8wuA" + title: "Browserfingerprint" + description: + type: youtube + video_id: "wdPVt6m8wuA" + duration: 889 + - id: "dX-hUxsdCX0" + title: "Verschlüsseln mit AES" + description: + type: youtube + video_id: "dX-hUxsdCX0" + duration: 449 + - id: "yQJSQFxCHn0" + title: "Verschlüsseln mit PGP" + description: + type: youtube + video_id: "yQJSQFxCHn0" + duration: 761 + - id: "eyYQacf0gck" + title: "Emails PGP-Verschlüsseln mit Enigmail" + description: + type: youtube + video_id: "eyYQacf0gck" + duration: 260 + - id: "Jz9OTwqZssI" + title: "Verschlüsseln mit Truecrypt" + description: + type: youtube + video_id: "Jz9OTwqZssI" + duration: 726 + - id: "jzLDyxkDRNg" + title: "Anonym bleiben mit Whonix" + description: + type: youtube + video_id: "jzLDyxkDRNg" + duration: 1251 + - id: "qXxucKl5zzs" + title: "Den richtigen VPN Anbieter wählen" + description: + type: youtube + video_id: "qXxucKl5zzs" + duration: 557 + - id: "ol3zJAQD--8" + title: "Data Selfie - Welche Informationen hat Facebook" + description: + type: youtube + video_id: "ol3zJAQD--8" + duration: 134 + - id: "W9enTdOhKYE" + title: "Firefox Profilemaker, erweiterte Einstellungen in Firefox" + description: + type: youtube + video_id: "W9enTdOhKYE" + duration: 1525 + - id: "lX7ZJghgGgg" + title: "die Windows Datenschutzerklärung" + description: + type: youtube + video_id: "lX7ZJghgGgg" + duration: 551 + - id: "FYwbgTci3pI" + title: "Die Google Datenschutzerklärung kurz durchleuchtet" + description: + type: youtube + video_id: "FYwbgTci3pI" + duration: 723 + - id: "1lSvb71Uwes" + title: "Datenschutz bei Apple: so wird's gemacht" + description: + type: youtube + video_id: "1lSvb71Uwes" + duration: 1108 + - id: "0qXO1CmIX-s" + title: "Facebook, Whatsapp und Instagram - Der Datenschutz im Halloween-Kostüm" + description: + type: youtube + video_id: "0qXO1CmIX-s" + duration: 1153 + - id: "eyDaalvuOYE" + title: "Linux Tails - Maximale Anonymität - kurz vorgestellt und installiert" + description: + type: youtube + video_id: "eyDaalvuOYE" + duration: 1195 + - id: "ziGFK59haqY" + title: "Angriff auf Proxies, Sender und Empfängeranonymität" + description: + type: youtube + video_id: "ziGFK59haqY" + duration: 471 + - id: "coJd7qo5_kg" + title: "Mixes" + description: + type: youtube + video_id: "coJd7qo5_kg" + duration: 347 + - id: "WHKsHmFUjks" + title: "Onion Routing" + description: + type: youtube + video_id: "WHKsHmFUjks" + duration: 434 + - id: "ijfvhdsfsmw" + title: "Hidden Services" + description: + type: youtube + video_id: "ijfvhdsfsmw" + duration: 512 + - id: "0O4yeQaABAw" + title: "Bitmessage" + description: + type: youtube + video_id: "0O4yeQaABAw" + duration: 524 + - id: "i2SP4eb7aHk" + title: "Filesharing über TOR via Onionshare" + description: + type: youtube + video_id: "i2SP4eb7aHk" + duration: 393 + - id: "ejy0APEsRuY" + title: "Windows SICHER, ANONYM und SCHNELLER machen" + description: + type: youtube + video_id: "ejy0APEsRuY" + duration: 3287 + - id: "8H2Vxn6VXFY" + title: "Firefox: ANONYMER und SICHERER | Einstellungen und Addons" + description: + type: youtube + video_id: "8H2Vxn6VXFY" + duration: 3327 + - id: "EUxsBVjyiTY" + title: "Veracrypt: verschlüsselte USB Sticks und Dateien erstellen mit Geheim-Fach" + description: + type: youtube + video_id: "EUxsBVjyiTY" + duration: 1686 + - id: "-WymP8TwfcQ" + title: "GnuPG für Windows #1 - Installation und Schlüssel erstellen" + description: + type: youtube + video_id: "-WymP8TwfcQ" + duration: 620 + - id: "y78MITuTqAs" + title: "GnuPG Windows #2 - Nachrichten, Dateien verschlüsseln, signieren und prüfen" + description: + type: youtube + video_id: "y78MITuTqAs" + duration: 815 + - id: "qSz-y7wXF5s" + title: "In Outlook E-Mails verschlüsseln" + description: + type: youtube + video_id: "qSz-y7wXF5s" + duration: 259 + - id: "53llt5oY5I0" + title: "Gmail und Sonstige Web Mail Anbieter verschlüsseln" + description: + type: youtube + video_id: "53llt5oY5I0" + duration: 490 + - id: "mQFdUFDNaUs" + title: "GnuPG Verschlüsselung unter Android mit OpenKeyChain" + description: + type: youtube + video_id: "mQFdUFDNaUs" + duration: 675 + - id: "IZzU89SzLWc" + title: "Chrome sicher machen" + description: + type: youtube + video_id: "IZzU89SzLWc" + duration: 2102 + - id: "XcX3JY30tqU" + title: "Steganographie - Verstecke Nachrichten/Dateien in Bildern" + description: + type: youtube + video_id: "XcX3JY30tqU" + duration: 432 + - id: "sxFOti8SLSs" + title: "Steganographie - Verstecke Dateien wie Mr.Robot mit DeepSound" + description: + type: youtube + video_id: "sxFOti8SLSs" + duration: 385 + - id: "M6ly1shUVQo" + title: "Proxychains" + description: + type: youtube + video_id: "M6ly1shUVQo" + duration: 542 diff --git a/academy_data/courses/assembler.yml b/academy_data/courses/assembler.yml new file mode 100644 index 00000000..4645b134 --- /dev/null +++ b/academy_data/courses/assembler.yml @@ -0,0 +1,128 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7rhjy2t320NvKKGwP6Rxnpg +title: "Assembler Lernen" +description: | + Assembler - die Grundlage für alle modernen Programmiersprachen, die maschinennaheste Art der Programmierung überhaupt. + Heutzutage ist Assemblerprogrammierung wohl selten ein wirkliches Thema. Dennoch kann es in manchen Fällen nötig sein, Assembler lesen zu können - beispielsweise beim Verständnis des Compiler-generierten Codes oder bei der Analyse von Malware. +category: +language: de +image: https://static.bootstrap.academy/thumbnails/assembler.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665507903 +sections: + - id: section + title: "Assembler" + description: + lectures: + - id: "UiqAq-iWHPI" + title: "Einleitung" + description: + type: youtube + video_id: "UiqAq-iWHPI" + duration: 531 + - id: "XFB_-UrrG3Y" + title: "GCC Assembler" + description: + type: youtube + video_id: "XFB_-UrrG3Y" + duration: 703 + - id: "P013kCzh4TA" + title: "Der Von Neumann Rechner" + description: + type: youtube + video_id: "P013kCzh4TA" + duration: 420 + - id: "9cOFFHvUwCs" + title: "abstrahierter Speicher" + description: + type: youtube + video_id: "9cOFFHvUwCs" + duration: 353 + - id: "-yNUND7FTHY" + title: "Movl, Movq etc" + description: + type: youtube + video_id: "-yNUND7FTHY" + duration: 118 + - id: "9i_1T-I8Guo" + title: "Der Stack" + description: + type: youtube + video_id: "9i_1T-I8Guo" + duration: 217 + - id: "xA81yEWRLQc" + title: "Prozeduren und Funktionen" + description: + type: youtube + video_id: "xA81yEWRLQc" + duration: 359 + - id: "jn53WnfxMPk" + title: "Einstiegspunkte und Ausgaben" + description: + type: youtube + video_id: "jn53WnfxMPk" + duration: 494 + - id: "dCSYVW6yfFI" + title: "Einen Integer ausgeben" + description: + type: youtube + video_id: "dCSYVW6yfFI" + duration: 165 + - id: "fEyGD-Qx7u8" + title: "Bedingte Ausgaben" + description: + type: youtube + video_id: "fEyGD-Qx7u8" + duration: 516 + - id: "M50Vv32yzzo" + title: "Sprungbefehle - Jump" + description: + type: youtube + video_id: "M50Vv32yzzo" + duration: 597 + - id: "IkVZc5MALi4" + title: "Einfache Arithmetische Befehle" + description: + type: youtube + video_id: "IkVZc5MALi4" + duration: 778 + - id: "zYeOSoIB8ag" + title: "Schleifen" + description: + type: youtube + video_id: "zYeOSoIB8ag" + duration: 376 + - id: "4f3t94Xwkvg" + title: "Logische Befehle" + description: + type: youtube + video_id: "4f3t94Xwkvg" + duration: 478 + - id: "lpKo0ZDJD2Q" + title: "Shift Befehle" + description: + type: youtube + video_id: "lpKo0ZDJD2Q" + duration: 452 + - id: "nvErXNcWTNg" + title: "Stack Frames" + description: + type: youtube + video_id: "nvErXNcWTNg" + duration: 273 + - id: "zcQAd3vIXAU" + title: "Der GCC Output" + description: + type: youtube + video_id: "zcQAd3vIXAU" + duration: 840 + - id: "BKmzY8Bu8GY" + title: "Inline Assembler - Assembler Code in C" + description: + type: youtube + video_id: "BKmzY8Bu8GY" + duration: 538 diff --git a/academy_data/courses/bash.yml b/academy_data/courses/bash.yml new file mode 100644 index 00000000..49fbd809 --- /dev/null +++ b/academy_data/courses/bash.yml @@ -0,0 +1,54 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7r-Tw-cNntRgvwA7nXPAjP4 +title: "Bash" +description: "Bash ist die Programmiersprache für das Linux Terminal. Hiermit lässt sich jede Kette an Befehlen komplett automatisieren. Sie ist das Zuhause für Linux-Systemadministratoren." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/bash.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665508149 +sections: + - id: section + title: "Bash" + description: + lectures: + - id: "S7SAsLh60dE" + title: "Scripten für das Linux-Terminal" + description: + type: youtube + video_id: "S7SAsLh60dE" + duration: 328 + - id: "BiDXO0Cb2-k" + title: "Variablen" + description: + type: youtube + video_id: "BiDXO0Cb2-k" + duration: 438 + - id: "3gyZvA3FxiE" + title: "if-Bedingungen" + description: + type: youtube + video_id: "3gyZvA3FxiE" + duration: 346 + - id: "8PWnT7r-pIs" + title: "User Inputs" + description: + type: youtube + video_id: "8PWnT7r-pIs" + duration: 508 + - id: "N7G-px1dBWs" + title: "Schleifen" + description: + type: youtube + video_id: "N7G-px1dBWs" + duration: 565 + - id: "edzdqM2Wrug" + title: "Funktionen" + description: + type: youtube + video_id: "edzdqM2Wrug" + duration: 327 diff --git a/academy_data/courses/binaere_mathematik.yml b/academy_data/courses/binaere_mathematik.yml new file mode 100644 index 00000000..67b5653f --- /dev/null +++ b/academy_data/courses/binaere_mathematik.yml @@ -0,0 +1,60 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7rsjQsc8hFAdR4BlO_MQib1 +title: "Binäre Mathematik" +description: "Binäre Mathematik hat zwar nichts direkt mit Programmierung zu tun, hilft aber extrem zu verstehen, warum genau das Programm plötzlich eine Ungenauigkeit bei einer Gleitkommazahl hat oder was ein Overflow ist. Sie ist daher fast schon Pflicht, wenn man wirklich IT machen möchte." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/binary.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506721 +sections: + - id: section + title: "Binäre Mathematik" + description: + lectures: + - id: "E_UPLOUDeIE" + title: "Binär in Dezimal umrechnen und umgekehrt - Theoretische Informatik" + description: + type: youtube + video_id: "E_UPLOUDeIE" + duration: 568 + - id: "_lnX0kvaIjo" + title: "Binär addieren und subtrahieren - Theoretische Informatik" + description: + type: youtube + video_id: "_lnX0kvaIjo" + duration: 452 + - id: "HMl9rzFF6nI" + title: "Binär multiplizieren - Theoretische Informatik" + description: + type: youtube + video_id: "HMl9rzFF6nI" + duration: 281 + - id: "FrSw77DC7pI" + title: "Hornerschema - Theoretische Informatik" + description: + type: youtube + video_id: "FrSw77DC7pI" + duration: 809 + - id: "-2yUppq5iJg" + title: "Trick zum Zahlensysteme umwandeln - Theoretische Informatik" + description: + type: youtube + video_id: "-2yUppq5iJg" + duration: 446 + - id: "u3G9uVy9Wz4" + title: "Negative Zahlen - Theoretische Informatik" + description: + type: youtube + video_id: "u3G9uVy9Wz4" + duration: 563 + - id: "-B9RtV0Ps8k" + title: "IEEE-754 - Floating Point - Theoretische Informatik" + description: + type: youtube + video_id: "-B9RtV0Ps8k" + duration: 723 diff --git a/academy_data/courses/binary_exploitation_secure_coding.yml b/academy_data/courses/binary_exploitation_secure_coding.yml new file mode 100644 index 00000000..525c4e74 --- /dev/null +++ b/academy_data/courses/binary_exploitation_secure_coding.yml @@ -0,0 +1,174 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7qff-bnM05OqSI0fx4GknZ6 +title: "Binary Exploitation und Secure C Coding" +description: "C ist eine sehr hardwarenahe Sprache. Dementsprechend muss man sich auch mit Buffer Overflows und Co beschäftigen, damit man mit C wirklich sichere Anwendungen schreiben kann - und mal ehrlich, wenn eine Anwendung bitte sicher sein soll, dann doch unsere Betriebssysteme, Treiber und Firmware. Und die sind alle in C geschrieben." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/binaryexploitationsecurecoding.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 3000 +learning_goals: [] +requirements: [] +last_update: 1665507832 +sections: + - id: section + title: "Binary Exploitation und Secure Coding" + description: + lectures: + - id: "3Tdx9HNfFco" + title: "Binary Exploitation und Secure Coding in C" + description: + type: youtube + video_id: "3Tdx9HNfFco" + duration: 680 + - id: "w0OTPu0727Q" + title: "GDB" + description: + type: youtube + video_id: "w0OTPu0727Q" + duration: 1055 + - id: "5vaprZFAROE" + title: "Prozess Layout Stack und Heap" + description: + type: youtube + video_id: "5vaprZFAROE" + duration: 473 + - id: "lwG8NGgqcik" + title: "Buffer Overflows und Stack Smashing" + description: + type: youtube + video_id: "lwG8NGgqcik" + duration: 311 + - id: "5dguk0pTLec" + title: "Variablen ändern" + description: + type: youtube + video_id: "5dguk0pTLec" + duration: 739 + - id: "SYfoKZ-8eCw" + title: "Code Ausführung ändern" + description: + type: youtube + video_id: "SYfoKZ-8eCw" + duration: 924 + - id: "ATQiz5fEni4" + title: "Üben unter Windows Mac und Linux" + description: + type: youtube + video_id: "ATQiz5fEni4" + duration: 538 + - id: "E-S7cpv-9_A" + title: "Gezielt Variablen verändern" + description: + type: youtube + video_id: "E-S7cpv-9_A" + duration: 599 + - id: "WjWgBM74G-g" + title: "Nicht ASCII Werte nutzen" + description: + type: youtube + video_id: "WjWgBM74G-g" + duration: 524 + - id: "kQiBki9yddk" + title: "Ausführung verändern" + description: + type: youtube + video_id: "kQiBki9yddk" + duration: 489 + - id: "lPr5YOH5IO0" + title: "Ausführung verändern II" + description: + type: youtube + video_id: "lPr5YOH5IO0" + duration: 637 + - id: "9k2MN_FBGVM" + title: "Shellcode" + description: + type: youtube + video_id: "9k2MN_FBGVM" + duration: 1796 + - id: "eGyf_xcORcY" + title: "Das NX Bit" + description: + type: youtube + video_id: "eGyf_xcORcY" + duration: 528 + - id: "vfS3UsKyGmg" + title: "Return to LibC erklärt" + description: + type: youtube + video_id: "vfS3UsKyGmg" + duration: 340 + - id: "jPJK8u_D0Zw" + title: "Stack Canaries" + description: + type: youtube + video_id: "jPJK8u_D0Zw" + duration: 277 + - id: "YL60WELLlZE" + title: "ASLR und PIE" + description: + type: youtube + video_id: "YL60WELLlZE" + duration: 405 + - id: "_MCDmhUdivI" + title: "problematische Funktionen" + description: + type: youtube + video_id: "_MCDmhUdivI" + duration: 316 + - id: "dlz8x7WM1eI" + title: "Format String Leaks" + description: + type: youtube + video_id: "dlz8x7WM1eI" + duration: 607 + - id: "Pwco1NTsAVs" + title: "Format String Variablen ändern" + description: + type: youtube + video_id: "Pwco1NTsAVs" + duration: 520 + - id: "qaaY6KFIEaw" + title: "Format String An beliebige Orte schreiben" + description: + type: youtube + video_id: "qaaY6KFIEaw" + duration: 722 + - id: "HvzkKHbgcrI" + title: "Format String beliebige Werte schreiben" + description: + type: youtube + video_id: "HvzkKHbgcrI" + duration: 795 + - id: "j_dPzyYI--E" + title: "Integer Overflows" + description: + type: youtube + video_id: "j_dPzyYI--E" + duration: 342 + - id: "95VtC9s8RBY" + title: "Heap Overflows" + description: + type: youtube + video_id: "95VtC9s8RBY" + duration: 256 + - id: "hHWh9DfPlqw" + title: "Use after Free" + description: + type: youtube + video_id: "hHWh9DfPlqw" + duration: 582 + - id: "_jFt5HO0ZQc" + title: "No Free und Double Free" + description: + type: youtube + video_id: "_jFt5HO0ZQc" + duration: 447 + - id: "Z7ClHlFYRGQ" + title: "Abschließende Worte" + description: + type: youtube + video_id: "Z7ClHlFYRGQ" + duration: 298 diff --git a/academy_data/courses/bitcoin_blockchain_kryptowaehrungen.yml b/academy_data/courses/bitcoin_blockchain_kryptowaehrungen.yml new file mode 100644 index 00000000..0cdbd581 --- /dev/null +++ b/academy_data/courses/bitcoin_blockchain_kryptowaehrungen.yml @@ -0,0 +1,294 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7oiW2UVh1Go8JgllRbZRcPK +title: "Bitcoin, die Blockchain und Kryptowährungen einfach erklärt und praktisch angewandt" +description: "Blockchain-Technologien haben einen fragwürdigen Ruf - manche lieben sie, manche hassen sie. Eines ist aber sicher: Die wenigsten haben ein so tiefes technisches Verständnis, dass sie wissen, was es bedeutet, Transaktionen nachverfolgen zu können. Auch die kryptographischen Hintergründe von Blockchain-Technologien könnte man sich längst für viele weitere Anwendungen zunutze machen. Höchste Zeit, diese Technologie besser zu verstehen." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/blockchain.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665508312 +sections: + - id: section + title: "Bitcoin, die Blockchain und Kryptowährungen einfach erklärt und praktisch angewandt" + description: + lectures: + - id: "LpZO01eQb8I" + title: "Einleitung" + description: + type: youtube + video_id: "LpZO01eQb8I" + duration: 567 + - id: "tidYegYNplc" + title: "Banken" + description: + type: youtube + video_id: "tidYegYNplc" + duration: 434 + - id: "GcOVxYH3UD0" + title: "Die Anon-Bank" + description: + type: youtube + video_id: "GcOVxYH3UD0" + duration: 309 + - id: "4-T9QATVXl4" + title: "Die Blockchain" + description: + type: youtube + video_id: "4-T9QATVXl4" + duration: 670 + - id: "rp1nc0qyMFA" + title: "Dezentralisierung" + description: + type: youtube + video_id: "rp1nc0qyMFA" + duration: 296 + - id: "ep9emzqB54U" + title: "Blockchain.info" + description: + type: youtube + video_id: "ep9emzqB54U" + duration: 466 + - id: "PYAdagCNY3M" + title: "Transaktionen" + description: + type: youtube + video_id: "PYAdagCNY3M" + duration: 469 + - id: "uP06YTkbzmE" + title: "Das Double Spend Problem" + description: + type: youtube + video_id: "uP06YTkbzmE" + duration: 552 + - id: "qiJ5vI9I5U8" + title: "Proof of Work - Mining" + description: + type: youtube + video_id: "qiJ5vI9I5U8" + duration: 508 + - id: "34670_jd4HM" + title: "Warum Transaktionen manchmal ewig dauern" + description: + type: youtube + video_id: "34670_jd4HM" + duration: 559 + - id: "SzSmwvlLYSg" + title: "Stromverbrauch von Bitcoin" + description: + type: youtube + video_id: "SzSmwvlLYSg" + duration: 408 + - id: "h2K4eTfd-GA" + title: "Der SECP256K1-Standard für Schlüssel" + description: + type: youtube + video_id: "h2K4eTfd-GA" + duration: 405 + - id: "3lsKGK7YvLU" + title: "Mit Python Schlüssel generieren" + description: + type: youtube + video_id: "3lsKGK7YvLU" + duration: 577 + - id: "9gcT-9VAic8" + title: "Von den Keys zur Adresse" + description: + type: youtube + video_id: "9gcT-9VAic8" + duration: 303 + - id: "rrey8duU5EU" + title: "Wallets" + description: + type: youtube + video_id: "rrey8duU5EU" + duration: 325 + - id: "BhimXDC6zDQ" + title: "Non-Determinstic oder Random Wallets" + description: + type: youtube + video_id: "BhimXDC6zDQ" + duration: 183 + - id: "INIwb7A0qkI" + title: "Deterministic oder Seeded Wallets" + description: + type: youtube + video_id: "INIwb7A0qkI" + duration: 250 + - id: "2R8jZIUx86k" + title: "Hierarchical Deterministic (HD) Wallets" + description: + type: youtube + video_id: "2R8jZIUx86k" + duration: 421 + - id: "yMBgXEqGrnQ" + title: "Mnemonics" + description: + type: youtube + video_id: "yMBgXEqGrnQ" + duration: 352 + - id: "1C_ZElEgP8I" + title: "Software Wallets, Third Party Wallets und Hardware Wallets" + description: + type: youtube + video_id: "1C_ZElEgP8I" + duration: 461 + - id: "srKTodPzFU0" + title: "Paper Wallets selbst erstellen" + description: + type: youtube + video_id: "srKTodPzFU0" + duration: 595 + - id: "HrFKtfySVxY" + title: "Electrum Wallets" + description: + type: youtube + video_id: "HrFKtfySVxY" + duration: 852 + - id: "pdkdP33-yt8" + title: "Jaxx - Multiplatform Softwarewallet" + description: + type: youtube + video_id: "pdkdP33-yt8" + duration: 376 + - id: "rzuWktCSPvw" + title: "Script - Bitcoins Programmiersprache" + description: + type: youtube + video_id: "rzuWktCSPvw" + duration: 671 + - id: "fMVy9kvRoNE" + title: "Script - OP Codes" + description: + type: youtube + video_id: "fMVy9kvRoNE" + duration: 590 + - id: "YTniSN-7y6U" + title: "Multisignatures" + description: + type: youtube + video_id: "YTniSN-7y6U" + duration: 514 + - id: "p8ZSEvNlkv4" + title: "Pay-2-Script-Hash" + description: + type: youtube + video_id: "p8ZSEvNlkv4" + duration: 593 + - id: "31mMHVMT2Dg" + title: "Transaktionstimelocks mit nTimelock" + description: + type: youtube + video_id: "31mMHVMT2Dg" + duration: 452 + - id: "pgIkavypXb4" + title: "Per Output Timelocks mit Checklocktime" + description: + type: youtube + video_id: "pgIkavypXb4" + duration: 399 + - id: "nrWFXrhn3Fc" + title: "Bootstrapping im P2P-Netz" + description: + type: youtube + video_id: "nrWFXrhn3Fc" + duration: 334 + - id: "JKWEuUWzrWQ" + title: "Der Blockaustausch" + description: + type: youtube + video_id: "JKWEuUWzrWQ" + duration: 186 + - id: "YlHQh9Evav0" + title: "Der Genesis Block und der Code von Bitcoin" + description: + type: youtube + video_id: "YlHQh9Evav0" + duration: 339 + - id: "9mxVBqUykF8" + title: "Simplified Payment Verification" + description: + type: youtube + video_id: "9mxVBqUykF8" + duration: 401 + - id: "tURba0N50Cg" + title: "Bloom FIlter" + description: + type: youtube + video_id: "tURba0N50Cg" + duration: 466 + - id: "I7uG0ojtzkQ" + title: "Merkle Trees" + description: + type: youtube + video_id: "I7uG0ojtzkQ" + duration: 388 + - id: "ZueiWt-gVSU" + title: "Der Mining Algorithmus in Python" + description: + type: youtube + video_id: "ZueiWt-gVSU" + duration: 358 + - id: "LqegYrpYUeM" + title: "Das Mining Target und die Difficulty" + description: + type: youtube + video_id: "LqegYrpYUeM" + duration: 270 + - id: "4COmXzIQVSE" + title: "Soft Forks" + description: + type: youtube + video_id: "4COmXzIQVSE" + duration: 442 + - id: "vpJXW8nYCYs" + title: "Mining Pools" + description: + type: youtube + video_id: "vpJXW8nYCYs" + duration: 454 + - id: "Qh-nK_Nx-wE" + title: "P2Pool" + description: + type: youtube + video_id: "Qh-nK_Nx-wE" + duration: 352 + - id: "YZLIvGizEto" + title: "Mining Software und Equipment" + description: + type: youtube + video_id: "YZLIvGizEto" + duration: 526 + - id: "zeNEiC8pZdI" + title: "Lohnt Bitcoin Mining" + description: + type: youtube + video_id: "zeNEiC8pZdI" + duration: 665 + - id: "sA44Cg8ktew" + title: "Payment Channels" + description: + type: youtube + video_id: "sA44Cg8ktew" + duration: 706 + - id: "-kIwnUZpQGo" + title: "Asymmetric Revocable Commitments" + description: + type: youtube + video_id: "-kIwnUZpQGo" + duration: 685 + - id: "8kinwF17fK0" + title: "Das Lightning Network" + description: + type: youtube + video_id: "8kinwF17fK0" + duration: 329 + - id: "DxV5JK67gOM" + title: "Bitcoin kaufen" + description: + type: youtube + video_id: "DxV5JK67gOM" + duration: 728 diff --git a/academy_data/courses/c.yml b/academy_data/courses/c.yml new file mode 100644 index 00000000..09f4eb68 --- /dev/null +++ b/academy_data/courses/c.yml @@ -0,0 +1,204 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7q4shI4L__SRpetWff9BjLZ +title: "C Programmierung" +description: "C ist die Sprache, die als Vorlage für unsere modernen Sprachen zum Einsatz kam. Und sie ist noch immer weit verbreitet - hardwarenahe Programmierung, Treiber, Firmware, Betriebssysteme: Fast alles wird nach wie vor in C geschrieben. Wollt ihr hier einsteigen, solltet ihr C definitiv beherrschen." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/c.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506415 +sections: + - id: section + title: "C Programmierung" + description: + lectures: + - id: "x-2ZCkS3OHY" + title: "Einleitung" + description: + type: youtube + video_id: "x-2ZCkS3OHY" + duration: 390 + - id: "9bX5xEUqsqo" + title: "Variablen" + description: + type: youtube + video_id: "9bX5xEUqsqo" + duration: 400 + - id: "2tDkKZeAiPc" + title: "Datentypen" + description: + type: youtube + video_id: "2tDkKZeAiPc" + duration: 683 + - id: "w8Q0SaKS3C0" + title: "Konstanten" + description: + type: youtube + video_id: "w8Q0SaKS3C0" + duration: 273 + - id: "wRBes5ORwRo" + title: "if-Verzweigungen" + description: + type: youtube + video_id: "wRBes5ORwRo" + duration: 397 + - id: "a0S_1Yl4k2s" + title: "Operatoren" + description: + type: youtube + video_id: "a0S_1Yl4k2s" + duration: 438 + - id: "pJ1g-mWXJoc" + title: "Logische Operatoren und mehr als ein if" + description: + type: youtube + video_id: "pJ1g-mWXJoc" + duration: 309 + - id: "4yIVdaWHBYc" + title: "Die Switch-Case-Verzweigung" + description: + type: youtube + video_id: "4yIVdaWHBYc" + duration: 420 + - id: "_imEnxCFyiE" + title: "While-Schleife" + description: + type: youtube + video_id: "_imEnxCFyiE" + duration: 468 + - id: "qNRwmmQui6k" + title: "Die For-Schleife" + description: + type: youtube + video_id: "qNRwmmQui6k" + duration: 191 + - id: "9YizVz4ffgc" + title: "Die Do-While Schleife" + description: + type: youtube + video_id: "9YizVz4ffgc" + duration: 145 + - id: "6Uj_Ki9ZSqU" + title: "Loop Control" + description: + type: youtube + video_id: "6Uj_Ki9ZSqU" + duration: 351 + - id: "Q1Wf5cScgDM" + title: "Funktionen" + description: + type: youtube + video_id: "Q1Wf5cScgDM" + duration: 376 + - id: "yY3IB-vlpIw" + title: "Rückgabewerte" + description: + type: youtube + video_id: "yY3IB-vlpIw" + duration: 530 + - id: "UNGFcLwMG1E" + title: "Parameter" + description: + type: youtube + video_id: "UNGFcLwMG1E" + duration: 435 + - id: "eAl9ehuJpCo" + title: "Gültigkeitsbereiche von Variablen" + description: + type: youtube + video_id: "eAl9ehuJpCo" + duration: 379 + - id: "cH0pZYLEE5o" + title: "Arrays" + description: + type: youtube + video_id: "cH0pZYLEE5o" + duration: 408 + - id: "FBiwnHnZ8s8" + title: "Arrays in Funktionen" + description: + type: youtube + video_id: "FBiwnHnZ8s8" + duration: 389 + - id: "e2oUCDel0ZE" + title: "Pointer" + description: + type: youtube + video_id: "e2oUCDel0ZE" + duration: 412 + - id: "otsNa8gmHwQ" + title: "Pointer auf Arrays" + description: + type: youtube + video_id: "otsNa8gmHwQ" + duration: 376 + - id: "HJxSbFqqceo" + title: "Strings als Arrays mit Pointern" + description: + type: youtube + video_id: "HJxSbFqqceo" + duration: 641 + - id: "wlMgxCxFdxY" + title: "Mehrdimensionale Arrays" + description: + type: youtube + video_id: "wlMgxCxFdxY" + duration: 473 + - id: "JlJwVBKT4TM" + title: "Structures" + description: + type: youtube + video_id: "JlJwVBKT4TM" + duration: 425 + - id: "38NPeapXYSY" + title: "Pointer auf Structures" + description: + type: youtube + video_id: "38NPeapXYSY" + duration: 229 + - id: "59MOqTyAiVc" + title: "Unions" + description: + type: youtube + video_id: "59MOqTyAiVc" + duration: 334 + - id: "-nFGkHRLl2c" + title: "typedef" + description: + type: youtube + video_id: "-nFGkHRLl2c" + duration: 176 + - id: "5wnoPArE4Ns" + title: "Eingaben und Ausgaben" + description: + type: youtube + video_id: "5wnoPArE4Ns" + duration: 470 + - id: "7D5nsUZiGEc" + title: "Dateien lesen und schreiben" + description: + type: youtube + video_id: "7D5nsUZiGEc" + duration: 929 + - id: "xKX854l3How" + title: "Header-Dateien" + description: + type: youtube + video_id: "xKX854l3How" + duration: 473 + - id: "Dvs6s6_Gz6Y" + title: "Funktionen mit variabler Anzahl an Parametern" + description: + type: youtube + video_id: "Dvs6s6_Gz6Y" + duration: 307 + - id: "Pe0S0mUPGBc" + title: "Speicherzuweisung" + description: + type: youtube + video_id: "Pe0S0mUPGBc" + duration: 495 diff --git a/academy_data/courses/c_sharp.yml b/academy_data/courses/c_sharp.yml new file mode 100644 index 00000000..158f6a48 --- /dev/null +++ b/academy_data/courses/c_sharp.yml @@ -0,0 +1,198 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7rlNexPh8wjI2DyABX8It7U +title: "C#" +description: "C# - das Java von Microsoft - ist eine moderne, objektorientierte Sprache, die überall da ganz gerne eingesetzt wird, wo Microsoft ist - und das ist häufig!" +category: +language: de +image: https://static.bootstrap.academy/thumbnails/c_sharp.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1666715892 +sections: + - id: section + title: "C#" + description: + lectures: + - id: "podkKm7HsY8" + title: "Einleitung" + description: + type: youtube + video_id: "podkKm7HsY8" + duration: 428 + - id: "2VUwc7ur7aw" + title: "Variablen" + description: + type: youtube + video_id: "2VUwc7ur7aw" + duration: 656 + - id: "lU7WPpr1yf0" + title: "If-Statement / Bedingungen" + description: + type: youtube + video_id: "lU7WPpr1yf0" + duration: 781 + - id: "gLlGO9IzDQc" + title: "Switch Case Verzweigungen" + description: + type: youtube + video_id: "gLlGO9IzDQc" + duration: 444 + - id: "6znQH27H7-c" + title: "Schleifen" + description: + type: youtube + video_id: "6znQH27H7-c" + duration: 816 + - id: "Vf5f01CHxjc" + title: "Arrays" + description: + type: youtube + video_id: "Vf5f01CHxjc" + duration: 616 + - id: "fpDZbEc5ZGs" + title: "Mehrdimensionale Arrays" + description: + type: youtube + video_id: "fpDZbEc5ZGs" + duration: 633 + - id: "gB7SbBefhNc" + title: "Methoden" + description: + type: youtube + video_id: "gB7SbBefhNc" + duration: 760 + - id: "28ud2F4h6pE" + title: "Rekursive Methoden" + description: + type: youtube + video_id: "28ud2F4h6pE" + duration: 352 + - id: "Bkxgp6hbhvw" + title: "Überladung und Standardparameter" + description: + type: youtube + video_id: "Bkxgp6hbhvw" + duration: 512 + - id: "g1xYdLwH_c0" + title: "Klassen" + description: + type: youtube + video_id: "g1xYdLwH_c0" + duration: 730 + - id: "ZoIF2AOPZzY" + title: "Konstruktoren" + description: + type: youtube + video_id: "ZoIF2AOPZzY" + duration: 426 + - id: "5IHiqJsGoL4" + title: "Private und Public" + description: + type: youtube + video_id: "5IHiqJsGoL4" + duration: 369 + - id: "-Bgt6HJEhf0" + title: "Getter und Setter" + description: + type: youtube + video_id: "-Bgt6HJEhf0" + duration: 377 + - id: "SicsKRIyEQw" + title: "static" + description: + type: youtube + video_id: "SicsKRIyEQw" + duration: 330 + - id: "5fwTQ6G13fw" + title: "Vererbung und Konstruktoren bei Vererbung" + description: + type: youtube + video_id: "5fwTQ6G13fw" + duration: 566 + - id: "_Zvi21_kMw4" + title: "Interfaces" + description: + type: youtube + video_id: "_Zvi21_kMw4" + duration: 656 + - id: "JY6eVIwqsZo" + title: "Mehrfachvererbung" + description: + type: youtube + video_id: "JY6eVIwqsZo" + duration: 534 + - id: "ea_NeSG5Vto" + title: "Polymorphismus und abstrakte Klassen" + description: + type: youtube + video_id: "ea_NeSG5Vto" + duration: 699 + - id: "C9g95JGIvf4" + title: "Operatoren überladen" + description: + type: youtube + video_id: "C9g95JGIvf4" + duration: 619 + - id: "kNtaIkuwJPY" + title: "Namespaces" + description: + type: youtube + video_id: "kNtaIkuwJPY" + duration: 467 + - id: "Ss80KnT2JN8" + title: "Listen selbst implementiert" + description: + type: youtube + video_id: "Ss80KnT2JN8" + duration: 1536 + - id: "vaIs3NqwBi8" + title: "Enums" + description: + type: youtube + video_id: "vaIs3NqwBi8" + duration: 199 + - id: "D2MtL6cIbpg" + title: "Casts und mehr zu Typen" + description: + type: youtube + video_id: "D2MtL6cIbpg" + duration: 719 + - id: "XOHopSwGXxM" + title: "Funktionspointer und Lambda" + description: + type: youtube + video_id: "XOHopSwGXxM" + duration: 792 + - id: "2I4LtpaYl2g" + title: "Objektinitialisierer und anonyme Typen" + description: + type: youtube + video_id: "2I4LtpaYl2g" + duration: 515 + - id: "jqoNgqif5og" + title: "Events" + description: + type: youtube + video_id: "jqoNgqif5og" + duration: 811 + - id: "tUZ_NoEX28w" + title: "Präprozessordirektiven" + description: + type: youtube + video_id: "tUZ_NoEX28w" + duration: 503 + - id: "8z8hqSDL_0s" + title: "Dictionaries" + description: + type: youtube + video_id: "8z8hqSDL_0s" + duration: 527 + - id: "7ViaVtMnW7M" + title: "Exceptionhandling" + description: + type: youtube + video_id: "7ViaVtMnW7M" + duration: 493 diff --git a/academy_data/courses/clean_code.yml b/academy_data/courses/clean_code.yml new file mode 100644 index 00000000..e7eda170 --- /dev/null +++ b/academy_data/courses/clean_code.yml @@ -0,0 +1,102 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7ryyZikMDPxxyYxEKtKn0ji +title: "Clean Code" +description: "Denkt immer daran: Wenn ihr schlechten Code schreibt, muss irgendein armer Mensch später damit weiter arbeiten - im Zweifel seid ihr das selbst. Spaß beiseite, schlechter Code kann dazu führen, dass ein Projekt bis zu Faktor 60 langsamer entwickelt wird. Irgendwann kommt man zum Stillstand. Deswegen BRAUCHEN wir sauberen Code." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/cleancode.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665507543 +sections: + - id: section + title: "Clean Code" + description: + lectures: + - id: "vOBiHk6MwX0" + title: "Einführung und Struktur einer Klasse" + description: + type: youtube + video_id: "vOBiHk6MwX0" + duration: 410 + - id: "Sa1slZ18nLo" + title: "Law of Demeter" + description: + type: youtube + video_id: "Sa1slZ18nLo" + duration: 284 + - id: "QKtGq66dN6U" + title: "Prinzip der kleinsten Überraschung" + description: + type: youtube + video_id: "QKtGq66dN6U" + duration: 274 + - id: "OKHkGNue7fI" + title: "Kommentare" + description: + type: youtube + video_id: "OKHkGNue7fI" + duration: 339 + - id: "HVSTWJwWC_w" + title: "DRY: dont repeat yourself" + description: + type: youtube + video_id: "HVSTWJwWC_w" + duration: 230 + - id: "oKdy-hwdpw8" + title: "YAGNI" + description: + type: youtube + video_id: "oKdy-hwdpw8" + duration: 285 + - id: "ju3NeXFCsaE" + title: "Single Responsibility" + description: + type: youtube + video_id: "ju3NeXFCsaE" + duration: 286 + - id: "rLPNqlbUyIM" + title: "Open Closed" + description: + type: youtube + video_id: "rLPNqlbUyIM" + duration: 288 + - id: "VQinjwq03rY" + title: "Liskovsches Substitutionsprinzip" + description: + type: youtube + video_id: "VQinjwq03rY" + duration: 429 + - id: "adXGiewEY1c" + title: "Interface Segregation" + description: + type: youtube + video_id: "adXGiewEY1c" + duration: 347 + - id: "oC-y2TS0qbE" + title: "Dependency Inversion" + description: + type: youtube + video_id: "oC-y2TS0qbE" + duration: 273 + - id: "o5zdblAfZ6U" + title: "Single Level of Abstraction" + description: + type: youtube + video_id: "o5zdblAfZ6U" + duration: 278 + - id: "F8tAUuHJ43U" + title: "Refactoring und Pfadfinderregel" + description: + type: youtube + video_id: "F8tAUuHJ43U" + duration: 572 + - id: "LQrWkq6_hQQ" + title: "Clean JavaScript Code" + description: + type: youtube + video_id: "LQrWkq6_hQQ" + duration: 1690 diff --git a/academy_data/courses/cloud.yml b/academy_data/courses/cloud.yml new file mode 100644 index 00000000..6176ebe4 --- /dev/null +++ b/academy_data/courses/cloud.yml @@ -0,0 +1,60 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7oxg9u5X2a-9X_jpN8iPOQy +title: "Cloud Technologien" +description: "Die Cloud ist überall, so sagt man doch. Doch gerade wenn ihr selbst eine Software wirklich hosten wollt, verbreiten wollt, anderen zugänglich machen wollt - je kleiner man ist, desto wertvoller sind Cloud Technologien. Logisch: Es ist als eine Person kaum finanzierbar, ein ganzes Serverzentrum zu betreiben. Deswegen ziehen viele kleinere Firmen gerade immer mehr in die Cloud. Aber was heißt das? Dazu ist diese Serie da." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/cloud.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665508407 +sections: + - id: section + title: "Cloud Technologien" + description: + lectures: + - id: "alYIYtIxIVE" + title: "* As A Service - Die Grundbegriffe des Cloud Computing" + description: + type: youtube + video_id: "alYIYtIxIVE" + duration: 659 + - id: "FsVTmFb6Eio" + title: 'GCP vs AWS vs Azure vs "die anderen"' + description: + type: youtube + video_id: "FsVTmFb6Eio" + duration: 481 + - id: "N3JlH4HCzXU" + title: "Die Client-Server-Architektur" + description: + type: youtube + video_id: "N3JlH4HCzXU" + duration: 603 + - id: "xkunFE-J_NE" + title: "Server Virtualisierung - Was ist das?" + description: + type: youtube + video_id: "xkunFE-J_NE" + duration: 706 + - id: "_KnVD65mEJE" + title: "Virtuelle Maschinen vs Container / Docker" + description: + type: youtube + video_id: "_KnVD65mEJE" + duration: 996 + - id: "bKyEecIGwJ0" + title: "Nested VMs sind meistens eine schlechte Idee" + description: + type: youtube + video_id: "bKyEecIGwJ0" + duration: 652 + - id: "dlDGWN6xb44" + title: "Der Reverse Proxy | Wichtigster Baustein für Serverarchitekturen?" + description: + type: youtube + video_id: "dlDGWN6xb44" + duration: 869 diff --git a/academy_data/courses/cpp.yml b/academy_data/courses/cpp.yml new file mode 100644 index 00000000..449e5071 --- /dev/null +++ b/academy_data/courses/cpp.yml @@ -0,0 +1,360 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7oG-kkn36ZnDpRq6iahUXZS +title: "C++ Programmierung" +description: "C++ ist die Weiterentwicklung von C - Objektorientierung, Vererbung, dynamische Bindung. Hier kam der ganze Spaß dazu. C++ ist mittlerweile eine moderne Sprache, die weit verbreitet ist und speziell dort zum Einsatz kommt, wo Leistung essentiell ist: Spiele, Server und Co." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/cpp.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506460 +sections: + - id: section + title: "Grundlagen der C++ Programmierung" + description: + lectures: + - id: "Q7CnoMhUxWQ" + title: "C Crashkurs Tutorial für Programmierer in ~45 Minuten" + description: + type: youtube + video_id: "Q7CnoMhUxWQ" + duration: 2640 + - id: "fypyXGaNFgg" + title: "Installation und Setup" + description: + type: youtube + video_id: "fypyXGaNFgg" + duration: 593 + - id: "jZAaUJvqbPM" + title: "Inputs und Outputs" + description: + type: youtube + video_id: "jZAaUJvqbPM" + duration: 278 + - id: "nIhTXXxl-Lc" + title: "Strings" + description: + type: youtube + video_id: "nIhTXXxl-Lc" + duration: 781 + - id: "JytgNgE1CqQ" + title: "Klassen" + description: + type: youtube + video_id: "JytgNgE1CqQ" + duration: 616 + - id: "z-2Od9wLzKM" + title: "Konstruktoren" + description: + type: youtube + video_id: "z-2Od9wLzKM" + duration: 647 + - id: "Psdvmx-Hj-8" + title: "Member Initialisierung und Pointer auf Objekte" + description: + type: youtube + video_id: "Psdvmx-Hj-8" + duration: 558 + - id: "uWiPVmOJdLo" + title: "Kapselung mit private und public" + description: + type: youtube + video_id: "uWiPVmOJdLo" + duration: 541 + - id: "SML9OTNlAOg" + title: "Operatoren überladen" + description: + type: youtube + video_id: "SML9OTNlAOg" + duration: 559 + - id: "vpaAQu7Lkfs" + title: "this und Call by Reference" + description: + type: youtube + video_id: "vpaAQu7Lkfs" + duration: 394 + - id: "j1KKmMF1_Ys" + title: "static - Klassenvariablen" + description: + type: youtube + video_id: "j1KKmMF1_Ys" + duration: 320 + - id: "eRg5EU2qq-k" + title: "const" + description: + type: youtube + video_id: "eRg5EU2qq-k" + duration: 518 + - id: "Lh8tzIieBJU" + title: "Header Files für Klassendefinitionen" + description: + type: youtube + video_id: "Lh8tzIieBJU" + duration: 496 + - id: "8prKOxAS_Co" + title: "Friendship" + description: + type: youtube + video_id: "8prKOxAS_Co" + duration: 267 + - id: "Ia1QE-RraGU" + title: "Vererbung" + description: + type: youtube + video_id: "Ia1QE-RraGU" + duration: 468 + - id: "X8HqCZQr1PI" + title: "Zugriffsmodifikatoren bei Vererbung" + description: + type: youtube + video_id: "X8HqCZQr1PI" + duration: 550 + - id: "esCBTBiMTNQ" + title: "virtual und mehr zu Vererbung" + description: + type: youtube + video_id: "esCBTBiMTNQ" + duration: 610 + - id: "a3zvYc-txRo" + title: "Mehrfachvererbung" + description: + type: youtube + video_id: "a3zvYc-txRo" + duration: 473 + - id: "qHQpz7UFvA0" + title: "Abstraktheit und Interfaces" + description: + type: youtube + video_id: "qHQpz7UFvA0" + duration: 507 + - id: "wiW3hDyYvmc" + title: "Multithreading" + description: + type: youtube + video_id: "wiW3hDyYvmc" + duration: 723 + - id: "bpRmoIWyZLE" + title: "Multithreading #2" + description: + type: youtube + video_id: "bpRmoIWyZLE" + duration: 502 + - id: section2 + title: "Moderne C++ Programmierung" + description: + lectures: + - id: "1hO5O5t-9Ws" + title: "Die IDE CLion einrichten" + description: + type: youtube + video_id: "1hO5O5t-9Ws" + duration: 534 + - id: "VUuSzDQh8uo" + title: "Vector" + description: + type: youtube + video_id: "VUuSzDQh8uo" + duration: 805 + - id: "1grLmPPU9v0" + title: "Maps" + description: + type: youtube + video_id: "1grLmPPU9v0" + duration: 874 + - id: "rNnE37oObh4" + title: "Auto" + description: + type: youtube + video_id: "rNnE37oObh4" + duration: 675 + - id: "ljiP8T16ckU" + title: "nullptr" + description: + type: youtube + video_id: "ljiP8T16ckU" + duration: 607 + - id: "NIAJPOroh94" + title: "constexpr" + description: + type: youtube + video_id: "NIAJPOroh94" + duration: 809 + - id: "Dpm7gqLhPPk" + title: "Chrono" + description: + type: youtube + video_id: "Dpm7gqLhPPk" + duration: 356 + - id: "-Y4kigvvrAQ" + title: "If-Variablen-Scope" + description: + type: youtube + video_id: "-Y4kigvvrAQ" + duration: 525 + - id: "U-dZ4uaeMlo" + title: "initializer Lists" + description: + type: youtube + video_id: "U-dZ4uaeMlo" + duration: 483 + - id: "PjIR0QO2dGE" + title: "Mehrere Rückgabe-Werte" + description: + type: youtube + video_id: "PjIR0QO2dGE" + duration: 529 + - id: "F_Gn20Vr-1w" + title: "Raw Strings" + description: + type: youtube + video_id: "F_Gn20Vr-1w" + duration: 474 + - id: section3 + title: "Smart Pointer" + description: + lectures: + - id: "b_rgiYG5xWs" + title: "RAII" + description: + type: youtube + video_id: "b_rgiYG5xWs" + duration: 751 + - id: "KNcqxpjO_vI" + title: "Shared Pointer" + description: + type: youtube + video_id: "KNcqxpjO_vI" + duration: 648 + - id: "u2TME7SqLlo" + title: "Unique Pointer" + description: + type: youtube + video_id: "u2TME7SqLlo" + duration: 569 + - id: "JYs5hroLTJE" + title: "Weak Pointer" + description: + type: youtube + video_id: "JYs5hroLTJE" + duration: 547 + - id: section4 + title: "Filesystem" + description: + lectures: + - id: "ryFOJlhb4nc" + title: "Ordner" + description: + type: youtube + video_id: "ryFOJlhb4nc" + duration: 559 + - id: "EowRm0EKWsg" + title: "Dateien" + description: + type: youtube + video_id: "EowRm0EKWsg" + duration: 666 + - id: section5 + title: "Lambdas und Functional C++" + description: + lectures: + - id: "cOXo09KHVtw" + title: "Einleitung" + description: + type: youtube + video_id: "cOXo09KHVtw" + duration: 649 + - id: "CF30r-A7uV8" + title: "Capture List" + description: + type: youtube + video_id: "CF30r-A7uV8" + duration: 604 + - id: "otInl-deYSk" + title: "Die Typen von Funktionen" + description: + type: youtube + video_id: "otInl-deYSk" + duration: 607 + - id: section6 + title: "So geht neue OOP" + description: + lectures: + - id: "Kzei0cT8bE8" + title: "Delegate und Inheritance Constructors" + description: + type: youtube + video_id: "Kzei0cT8bE8" + duration: 472 + - id: "Dgh1I5x-g50" + title: "override und final für virtual functions" + description: + type: youtube + video_id: "Dgh1I5x-g50" + duration: 435 + - id: "NCa-QKf5MZ8" + title: "noexcept" + description: + type: youtube + video_id: "NCa-QKf5MZ8" + duration: 301 + - id: section7 + title: "Parallelismus und Concurrency" + description: + lectures: + - id: "S1E0GD4UZMo" + title: "Threads erstellen" + description: + type: youtube + video_id: "S1E0GD4UZMo" + duration: 522 + - id: "2w4p0miwRzs" + title: "Mutex" + description: + type: youtube + video_id: "2w4p0miwRzs" + duration: 791 + - id: "8KO-q2SymjQ" + title: "Spinlocks" + description: + type: youtube + video_id: "8KO-q2SymjQ" + duration: 316 + - id: "9lz3j2BY9UY" + title: "Atomic Variablen" + description: + type: youtube + video_id: "9lz3j2BY9UY" + duration: 244 + - id: "E7E-KI9qX9M" + title: "Der Standard Daten Workflow" + description: + type: youtube + video_id: "E7E-KI9qX9M" + duration: 771 + - id: "DypE0Eg5qb4" + title: "Condition Variables" + description: + type: youtube + video_id: "DypE0Eg5qb4" + duration: 549 + - id: "wAqT0Jk4NYg" + title: "Asnyc und Futures" + description: + type: youtube + video_id: "wAqT0Jk4NYg" + duration: 615 + - id: "7IJdAKgJ_xE" + title: "Futures und Promises" + description: + type: youtube + video_id: "7IJdAKgJ_xE" + duration: 608 + - id: "9VlNjHhKHMc" + title: "Parallele Algorithmen in der STL" + description: + type: youtube + video_id: "9VlNjHhKHMc" + duration: 1188 diff --git a/academy_data/courses/css3_fuer_anfaenger.yml b/academy_data/courses/css3_fuer_anfaenger.yml new file mode 100644 index 00000000..97d03443 --- /dev/null +++ b/academy_data/courses/css3_fuer_anfaenger.yml @@ -0,0 +1,180 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7qQz698kYRkkBXJDeXJY_I7 +title: "CSS 3" +description: "Mit CSS definiert man, wie eine Website aussehen soll - nicht den Inhalt oder das Verhalten. Doch ist das Design bei Web nicht gerade einer der wichtigsten Punkte? Schatten, Ecken aber auch Design für mobile Geräte und Effekte sind heute nicht mehr wegzudenken. Hier erfahrt ihr, wie man diese einsetzt." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/CSS.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506525 +sections: + - id: section + title: "CSS 3" + description: + lectures: + - id: "49ya2iMC40Q" + title: "Einleitung und Einbindung in HTML" + description: + type: youtube + video_id: "49ya2iMC40Q" + duration: 414 + - id: "GiLNSfOmtZQ" + title: "grundlegender Aufbau und Selektoren" + description: + type: youtube + video_id: "GiLNSfOmtZQ" + duration: 550 + - id: "5I7UlR2QK-U" + title: "mehr zu Selektoren" + description: + type: youtube + video_id: "5I7UlR2QK-U" + duration: 650 + - id: "8GephXAvg9o" + title: "Farben" + description: + type: youtube + video_id: "8GephXAvg9o" + duration: 381 + - id: "CxQCoA0YN9g" + title: "Hintergründe" + description: + type: youtube + video_id: "CxQCoA0YN9g" + duration: 526 + - id: "s0WSM0ck4TA" + title: "Das Box-Modell" + description: + type: youtube + video_id: "s0WSM0ck4TA" + duration: 600 + - id: "2C-VziV2McI" + title: "Schriftvarianz" + description: + type: youtube + video_id: "2C-VziV2McI" + duration: 740 + - id: "cjr7nQRwwms" + title: "Links und das Hovern von Objekten" + description: + type: youtube + video_id: "cjr7nQRwwms" + duration: 537 + - id: "wmpoN0OmNZo" + title: "Position" + description: + type: youtube + video_id: "wmpoN0OmNZo" + duration: 790 + - id: "4ZSK5drtj1I" + title: "Float" + description: + type: youtube + video_id: "4ZSK5drtj1I" + duration: 403 + - id: "hyW3xtH5Y4s" + title: "Navigationsleiste zum Mitprogrammieren" + description: + type: youtube + video_id: "hyW3xtH5Y4s" + duration: 902 + - id: "S3tM87aokfQ" + title: "Schatten und runde Ecken" + description: + type: youtube + video_id: "S3tM87aokfQ" + duration: 560 + - id: "kWLlgNQf8fg" + title: "Transparenz" + description: + type: youtube + video_id: "kWLlgNQf8fg" + duration: 457 + - id: "VUQISeNOt2U" + title: "Farbverläufe" + description: + type: youtube + video_id: "VUQISeNOt2U" + duration: 548 + - id: "dxJf6uF5Yd4" + title: "eigene Schriftarten verwenden" + description: + type: youtube + video_id: "dxJf6uF5Yd4" + duration: 333 + - id: "koSJKFfCvYU" + title: "Bilder filtern" + description: + type: youtube + video_id: "koSJKFfCvYU" + duration: 506 + - id: "z5JdAwtsbZM" + title: "2D Transformationen" + description: + type: youtube + video_id: "z5JdAwtsbZM" + duration: 388 + - id: "JyIvnPSv8CM" + title: "Responsive Media Design" + description: + type: youtube + video_id: "JyIvnPSv8CM" + duration: 572 + - id: "R6CerSgbC_w" + title: "Flex Layouts" + description: + type: youtube + video_id: "R6CerSgbC_w" + duration: 1063 + - id: "dMuJa_jjyAI" + title: "Grid Layouts" + description: + type: youtube + video_id: "dMuJa_jjyAI" + duration: 602 + - id: "oKk2jjqMypU" + title: "Variablen" + description: + type: youtube + video_id: "oKk2jjqMypU" + duration: 722 + - id: "VaRILz4GC1U" + title: "Before und After" + description: + type: youtube + video_id: "VaRILz4GC1U" + duration: 343 + - id: "_fqHym2MYxc" + title: "Calc" + description: + type: youtube + video_id: "_fqHym2MYxc" + duration: 390 + - id: "PPHofk9ei6E" + title: "CSS Let's Code: Ein hübsches 3D CSS-only Lade-Symbol" + description: + type: youtube + video_id: "PPHofk9ei6E" + duration: 1720 + - id: "YWJ2yQTt8tw" + title: "Animationen Grundlagen" + description: + type: youtube + video_id: "YWJ2yQTt8tw" + duration: 402 + - id: "gHXRU5a2dlw" + title: "Animationen für Fortgeschrittene" + description: + type: youtube + video_id: "gHXRU5a2dlw" + duration: 920 + - id: "v013BPfB_ks" + title: "WHERE vs IS" + description: + type: youtube + video_id: "v013BPfB_ks" + duration: 491 diff --git a/academy_data/courses/dart_flutter.yml b/academy_data/courses/dart_flutter.yml new file mode 100644 index 00000000..16686801 --- /dev/null +++ b/academy_data/courses/dart_flutter.yml @@ -0,0 +1,198 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7qokXX4II7FCZthJcrirT4o +title: "Dart und Flutter - Einfach Apps entwickeln mit Googles crossplattform Framework" +description: "Mit der Sprache Dart und dem Framework Flutter können mobile Apps nach modernen Standards entwickelt werden - und sofort für Android und iOS verbreitet werden, denn das heißt Crossplattform." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/dartflutter.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665507614 +sections: + - id: section + title: "Dart und Flutter - Einfach Apps entwickeln mit Googles crossplattform Framework" + description: + lectures: + - id: "S0SPcUrZaZQ" + title: "Installation" + description: + type: youtube + video_id: "S0SPcUrZaZQ" + duration: 1586 + - id: "RtBQ_6OFTqQ" + title: "Erklärung der Demo App" + description: + type: youtube + video_id: "RtBQ_6OFTqQ" + duration: 957 + - id: "hwYjscZArtc" + title: "Externe Pakete für eine erste eigene App" + description: + type: youtube + video_id: "hwYjscZArtc" + duration: 662 + - id: "Eow-ISyijHY" + title: "Klassenstruktur" + description: + type: youtube + video_id: "Eow-ISyijHY" + duration: 483 + - id: "CQkd2L8LHLs" + title: "Eine ListView hinzufügen" + description: + type: youtube + video_id: "CQkd2L8LHLs" + duration: 1016 + - id: "DWlOik7zhiI" + title: "Anklickbare Icons hinzufügen" + description: + type: youtube + video_id: "DWlOik7zhiI" + duration: 491 + - id: "S6HdPBstNOo" + title: "Bilder und neue Widgets" + description: + type: youtube + video_id: "S6HdPBstNOo" + duration: 606 + - id: "Yfv1FLIzWWk" + title: "Layouts: Rows und Columns" + description: + type: youtube + video_id: "Yfv1FLIzWWk" + duration: 708 + - id: "WTiW7qt2CCk" + title: "Achsen und Layouts" + description: + type: youtube + video_id: "WTiW7qt2CCk" + duration: 484 + - id: "o5PBbPicsBQ" + title: "Quellcode ordentlich halten" + description: + type: youtube + video_id: "o5PBbPicsBQ" + duration: 555 + - id: "sU13IpjzV3I" + title: "Der Container" + description: + type: youtube + video_id: "sU13IpjzV3I" + duration: 532 + - id: "umiNz0Kc3O4" + title: "Die Gridview" + description: + type: youtube + video_id: "umiNz0Kc3O4" + duration: 572 + - id: "Xz-VC1MlGr0" + title: "Der Stack" + description: + type: youtube + video_id: "Xz-VC1MlGr0" + duration: 640 + - id: "JwIvUA6ihbc" + title: "Material Cards" + description: + type: youtube + video_id: "JwIvUA6ihbc" + duration: 495 + - id: "hxE3ZvmPn9E" + title: "HTTP Anfragen, Kommunikation mit dem Backend" + description: + type: youtube + video_id: "hxE3ZvmPn9E" + duration: 1201 + - id: "RMNZ123y6Zk" + title: "JSON Objekte verarbeiten" + description: + type: youtube + video_id: "RMNZ123y6Zk" + duration: 721 + - id: "HkZ79bVAqp8" + title: "Debug Tools" + description: + type: youtube + video_id: "HkZ79bVAqp8" + duration: 703 + - id: "-RtixfTWR30" + title: "Klickbare Buttons" + description: + type: youtube + video_id: "-RtixfTWR30" + duration: 540 + - id: "Zp8J9B_h6Uk" + title: "Dismissable Items" + description: + type: youtube + video_id: "Zp8J9B_h6Uk" + duration: 853 + - id: "C5aZT9uvVwg" + title: "Navigationsleiste" + description: + type: youtube + video_id: "C5aZT9uvVwg" + duration: 776 + - id: "jmgr44o5wiY" + title: "Bottom Nav Leiste" + description: + type: youtube + video_id: "jmgr44o5wiY" + duration: 907 + - id: "qemv5YGIjik" + title: "Inhalte ändern über Navigationsleiste" + description: + type: youtube + video_id: "qemv5YGIjik" + duration: 472 + - id: "zaDZvM5KdXc" + title: "Optionen Menü" + description: + type: youtube + video_id: "zaDZvM5KdXc" + duration: 729 + - id: "zOOlWg_ijKI" + title: "TabBar" + description: + type: youtube + video_id: "zOOlWg_ijKI" + duration: 724 + - id: "Keu9s4652Hc" + title: "Bottom App Bar" + description: + type: youtube + video_id: "Keu9s4652Hc" + duration: 909 + - id: "wxV8mfXQYCU" + title: "Input Felder" + description: + type: youtube + video_id: "wxV8mfXQYCU" + duration: 945 + - id: "QsOXxSSm2bA" + title: "Input Felder validation und submit" + description: + type: youtube + video_id: "QsOXxSSm2bA" + duration: 1027 + - id: "xbA5e2uZClY" + title: "Banner" + description: + type: youtube + video_id: "xbA5e2uZClY" + duration: 175 + - id: "l1kbFB1UL6M" + title: "Animation zwischen Widgets" + description: + type: youtube + video_id: "l1kbFB1UL6M" + duration: 973 + - id: "TorSNwZRRuY" + title: "Animation" + description: + type: youtube + video_id: "TorSNwZRRuY" + duration: 960 diff --git a/academy_data/courses/data_mining.yml b/academy_data/courses/data_mining.yml new file mode 100644 index 00000000..fb839b91 --- /dev/null +++ b/academy_data/courses/data_mining.yml @@ -0,0 +1,84 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7qIOuGJrd-lu-ZZc9t4EdwM +title: "Eine kurze Einführung ins Data Mining" +description: "Alle sprechen von Data Science oder KI, die ja auch Daten nutzt. Doch.. wie kommen wir eigentlich an die Daten? Eine kurze Einführung gibt es hier." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/datamining.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 100 +learning_goals: [] +requirements: [] +last_update: 1665508109 +sections: + - id: section + title: "Eine kurze Einführung ins Data Mining" + description: + lectures: + - id: "Y7fEREo2gfQ" + title: "Einleitung" + description: + type: youtube + video_id: "Y7fEREo2gfQ" + duration: 114 + - id: "g_Kvy2uL_nA" + title: "Daten" + description: + type: youtube + video_id: "g_Kvy2uL_nA" + duration: 625 + - id: "oteQDfTKi3o" + title: "Features" + description: + type: youtube + video_id: "oteQDfTKi3o" + duration: 453 + - id: "j-CYgOs2Wjg" + title: "Wie kommt man an Daten" + description: + type: youtube + video_id: "j-CYgOs2Wjg" + duration: 453 + - id: "Z8Vs8gpNgjY" + title: "Plots" + description: + type: youtube + video_id: "Z8Vs8gpNgjY" + duration: 315 + - id: "VkQxtrj426Y" + title: "Rückschlüsse" + description: + type: youtube + video_id: "VkQxtrj426Y" + duration: 94 + - id: "LRpsfdXgdbk" + title: "Geheimtipp: Warnsysteme" + description: + type: youtube + video_id: "LRpsfdXgdbk" + duration: 231 + - id: "jFRZQNCeYiw" + title: "Beispiel: WhatsApp Metadaten" + description: + type: youtube + video_id: "jFRZQNCeYiw" + duration: 289 + - id: "Vc5GokYTkWI" + title: "Neuronale Netze" + description: + type: youtube + video_id: "Vc5GokYTkWI" + duration: 351 + - id: "ymN3lePsT74" + title: "Die große Gefahr von Data Science" + description: + type: youtube + video_id: "ymN3lePsT74" + duration: 417 + - id: "9K0tGphkxpY" + title: "Ausblick: was soll ich lernen" + description: + type: youtube + video_id: "9K0tGphkxpY" + duration: 149 diff --git a/academy_data/courses/datenvisualisierung.yml b/academy_data/courses/datenvisualisierung.yml new file mode 100644 index 00000000..4596ec11 --- /dev/null +++ b/academy_data/courses/datenvisualisierung.yml @@ -0,0 +1,102 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7pb4apqIMKvCz37t_dLznMm +title: "Datenvisualisierung" +description: "Data Science ist das eine, aber wie Daten gut dargestellt werden können, damit man auch auf den ersten Blick einen Zusammenhang zwischen zwei Dimensionen erkennen kann ein ganz anderer. Dazu gibt es Datenvisualisierung." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/datenvisualisierung.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665507531 +sections: + - id: section + title: "Datenvisualisierung" + description: + lectures: + - id: "Eo8b3Y2ibvY" + title: "hübsche Grafiken mit Python erstellen: Daten visualisieren" + description: + type: youtube + video_id: "Eo8b3Y2ibvY" + duration: 514 + - id: "tMW5yWpo7H0" + title: "Graph Objects vs Dictionaries" + description: + type: youtube + video_id: "tMW5yWpo7H0" + duration: 587 + - id: "JnOM7s1BSN8" + title: "Scatter Plots mit Express" + description: + type: youtube + video_id: "JnOM7s1BSN8" + duration: 615 + - id: "H0VPGq0RcZU" + title: "Scatter Plots mit Fehlern" + description: + type: youtube + video_id: "H0VPGq0RcZU" + duration: 197 + - id: "6sVXa1gfIbA" + title: "Bar Diagramme mit Express" + description: + type: youtube + video_id: "6sVXa1gfIbA" + duration: 718 + - id: "a982sb3bDD0" + title: "Scatter Matrix - perfekt zum Überblick verschaffen" + description: + type: youtube + video_id: "a982sb3bDD0" + duration: 632 + - id: "r4GdOcQLbeY" + title: "Parallel-Graphen" + description: + type: youtube + video_id: "r4GdOcQLbeY" + duration: 719 + - id: "EMMLaY2GSX0" + title: "Animationen in Scatter Plots und mehr fortgeschrittene Themen" + description: + type: youtube + video_id: "EMMLaY2GSX0" + duration: 727 + - id: "lej3-XxmAr4" + title: "Linien und Flächen Plots" + description: + type: youtube + video_id: "lej3-XxmAr4" + duration: 731 + - id: "h2YYjgG_LtI" + title: "Kuchen und Sunburst Diagramme" + description: + type: youtube + video_id: "h2YYjgG_LtI" + duration: 868 + - id: "knBjYw7e6z4" + title: "Histogramme erstellen" + description: + type: youtube + video_id: "knBjYw7e6z4" + duration: 647 + - id: "IXOE-IPFuFc" + title: "Histogramme mit weiterverwendbaren Counts" + description: + type: youtube + video_id: "IXOE-IPFuFc" + duration: 339 + - id: "XkE6YRR6voU" + title: "fortgeschrittene Histogramme" + description: + type: youtube + video_id: "XkE6YRR6voU" + duration: 598 + - id: "dXPIayOZBQA" + title: "Templates" + description: + type: youtube + video_id: "dXPIayOZBQA" + duration: 275 diff --git a/academy_data/courses/devops_grundlagen.yml b/academy_data/courses/devops_grundlagen.yml new file mode 100644 index 00000000..910b5855 --- /dev/null +++ b/academy_data/courses/devops_grundlagen.yml @@ -0,0 +1,90 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7pSbRnMtEG5XEdYVwJE5se9 +title: "DevOps" +description: "Die Softwareentwicklung hat sich stark weiter entwickelt. Klassische Entwicklung, agile Development, DevOps. Es wurde irgendwie immer weniger technisch und mittlerweile ist man echt darauf fixiert, dass man menschlich und kommunikativ gut ist. Was das heißt, erfahrt ihr hier." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/devops.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506858 +sections: + - id: section + title: "DevOps Grundlagen" + description: + lectures: + - id: "YtQdxrbfYVE" + title: "Was ist DevOps" + description: + type: youtube + video_id: "YtQdxrbfYVE" + duration: 459 + - id: "npDTCy90BZI" + title: "Das CAMS Modell" + description: + type: youtube + video_id: "npDTCy90BZI" + duration: 1036 + - id: "xY7qYF7Rql8" + title: "The three ways" + description: + type: youtube + video_id: "xY7qYF7Rql8" + duration: 501 + - id: "YMJ_sdeDbFE" + title: "CI/CD - Continuous Integration und Continuous Delivery" + description: + type: youtube + video_id: "YMJ_sdeDbFE" + duration: 492 + - id: "Q73xlpx5fH4" + title: "Testen" + description: + type: youtube + video_id: "Q73xlpx5fH4" + duration: 784 + - id: "CVlW_xJRJyQ" + title: "Canary Deployment" + description: + type: youtube + video_id: "CVlW_xJRJyQ" + duration: 226 + - id: "5_KihxuO9sE" + title: "Blue Green Deployment" + description: + type: youtube + video_id: "5_KihxuO9sE" + duration: 243 + - id: "kMNxhTSeUZk" + title: "Immutable Deployment" + description: + type: youtube + video_id: "kMNxhTSeUZk" + duration: 167 + - id: "xsZKoOtt-0c" + title: "Monitoring" + description: + type: youtube + video_id: "xsZKoOtt-0c" + duration: 349 + - id: "7604cNfJfiU" + title: "Das Post Mortem Gespräch - ein Beispiel für DevOps" + description: + type: youtube + video_id: "7604cNfJfiU" + duration: 304 + - id: "RwtqQWF-tYc" + title: "Pair Programming - Varianten, Dos und Don'ts" + description: + type: youtube + video_id: "RwtqQWF-tYc" + duration: 1109 + - id: "4u4x4Zg5Zpg" + title: "Aufgaben besser verwalten: Top KANBAN-Boards im Vergleich" + description: + type: youtube + video_id: "4u4x4Zg5Zpg" + duration: 2068 diff --git a/academy_data/courses/docker.yml b/academy_data/courses/docker.yml new file mode 100644 index 00000000..98089e50 --- /dev/null +++ b/academy_data/courses/docker.yml @@ -0,0 +1,282 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7oea6IDCLzpKe5XfLmWCwgr +title: "Docker" +description: "Auf meinem System läuft's doch. Dieses Problem kennen wir alle. Abhängigkeiten, Bibliotheken, die nicht installiert sind oder irgendwas anderes, das gerade Probleme macht. Docker ist eine Container-Software, das heißt hier wird eine Laufzeitumgebung für eure Software bereitgestellt, die sich einfach dynamisch alles holt, was sie braucht und schon sind diese Probleme Vergangenheit. Bonus: Sicherheit und einfacheres Deployment!" +category: +language: de +image: https://static.bootstrap.academy/thumbnails/docker.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665507061 +sections: + - id: section + title: "Docker" + description: + lectures: + - id: "avdVAfL8GPI" + title: "Warum ihr Docker braucht!" + description: + type: youtube + video_id: "avdVAfL8GPI" + duration: 499 + - id: "_KnVD65mEJE" + title: "Virtuelle Maschinen vs Container / Docker" + description: + type: youtube + video_id: "_KnVD65mEJE" + duration: 996 + - id: "DisDkSqDCNc" + title: "Wie Docker arbeitet" + description: + type: youtube + video_id: "DisDkSqDCNc" + duration: 225 + - id: "prqcw-ijWHU" + title: "Docker unter Linux installieren" + description: + type: youtube + video_id: "prqcw-ijWHU" + duration: 759 + - id: "VV6EKMUg9Hk" + title: "Docker unter Windows installieren" + description: + type: youtube + video_id: "VV6EKMUg9Hk" + duration: 130 + - id: "bKyEecIGwJ0" + title: "Nested VMs sind meistens eine schlechte Idee" + description: + type: youtube + video_id: "bKyEecIGwJ0" + duration: 652 + - id: "O-WZnE5Pu4A" + title: "Docker unter Mac installieren" + description: + type: youtube + video_id: "O-WZnE5Pu4A" + duration: 158 + - id: "ooj0bFwkV7Y" + title: "Docker Compose unter Linux installieren" + description: + type: youtube + video_id: "ooj0bFwkV7Y" + duration: 187 + - id: "Sc6IL5oYu50" + title: "Die Installation überprüfen" + description: + type: youtube + video_id: "Sc6IL5oYu50" + duration: 244 + - id: "oikJmNT1T0E" + title: "Eine Busybox starten" + description: + type: youtube + video_id: "oikJmNT1T0E" + duration: 685 + - id: "DdOV-3f2hT8" + title: "Befehle im inneren des Containers ausführen" + description: + type: youtube + video_id: "DdOV-3f2hT8" + duration: 182 + - id: "e-smL7N3ALk" + title: "WebApps und Port Mapping" + description: + type: youtube + video_id: "e-smL7N3ALk" + duration: 327 + - id: "yfaspTvApNU" + title: "Der Detached Modus" + description: + type: youtube + video_id: "yfaspTvApNU" + duration: 111 + - id: "KvRuH6KheNg" + title: "Eine Shell im Detached Mode erlangen" + description: + type: youtube + video_id: "KvRuH6KheNg" + duration: 356 + - id: "Dv--5NSZ91A" + title: "Dateien an Container übergeben" + description: + type: youtube + video_id: "Dv--5NSZ91A" + duration: 213 + - id: "ojREzIPCHbg" + title: "Container stoppen, Löschen von Images und Containern" + description: + type: youtube + video_id: "ojREzIPCHbg" + duration: 280 + - id: "KXyD4K8ct1o" + title: "Container automatisch starten lassen" + description: + type: youtube + video_id: "KXyD4K8ct1o" + duration: 408 + - id: "5HQw92WNY20" + title: "Statistiken der laufenden Container" + description: + type: youtube + video_id: "5HQw92WNY20" + duration: 172 + - id: "9k12DF-zuO4" + title: "Die Ressourcen eines Containers limitieren" + description: + type: youtube + video_id: "9k12DF-zuO4" + duration: 318 + - id: "1w1VFVyCGQ8" + title: "Logs ansehen" + description: + type: youtube + video_id: "1w1VFVyCGQ8" + duration: 112 + - id: "JwKPbh-6K_Q" + title: "In eine Datei loggen" + description: + type: youtube + video_id: "JwKPbh-6K_Q" + duration: 468 + - id: "eIHHFOE2D4A" + title: "Dockerfiles" + description: + type: youtube + video_id: "eIHHFOE2D4A" + duration: 498 + - id: "IlQVORxAs70" + title: "Dockerfiles builden und starten" + description: + type: youtube + video_id: "IlQVORxAs70" + duration: 370 + - id: "3Fz4VvHgKmI" + title: "Images auf Docker Hub teilen" + description: + type: youtube + video_id: "3Fz4VvHgKmI" + duration: 281 + - id: "Lod-Hs7rGeE" + title: "Environment Variablen" + description: + type: youtube + video_id: "Lod-Hs7rGeE" + duration: 357 + - id: "HbQOF8CSp3o" + title: "Python Deployment mit Docker" + description: + type: youtube + video_id: "HbQOF8CSp3o" + duration: 336 + - id: "QXxVJHSpIZ4" + title: "Nodejs Deployment mit Docker" + description: + type: youtube + video_id: "QXxVJHSpIZ4" + duration: 232 + - id: "Jn59zf63Ong" + title: "Ein Email Server mit MailCow" + description: + type: youtube + video_id: "Jn59zf63Ong" + duration: 600 + - id: "c_OEr4c8kmc" + title: "Wordpress mit Docker installieren" + description: + type: youtube + video_id: "c_OEr4c8kmc" + duration: 365 + - id: "iiGVw6Mw2_k" + title: "Eine eigene Cloud mit Nextcloud" + description: + type: youtube + video_id: "iiGVw6Mw2_k" + duration: 237 + - id: "lEpxGWMkOk0" + title: "Mehr Optionen in Docker Compose Files" + description: + type: youtube + video_id: "lEpxGWMkOk0" + duration: 390 + - id: "vH7o3eAFLJ8" + title: "Swarms" + description: + type: youtube + video_id: "vH7o3eAFLJ8" + duration: 166 + - id: "LXT8k1fro0Q" + title: "Docker Machine auf Linux installieren" + description: + type: youtube + video_id: "LXT8k1fro0Q" + duration: 298 + - id: "bhzxOBFKERQ" + title: "Lokale virtuelle Maschinen erstellen" + description: + type: youtube + video_id: "bhzxOBFKERQ" + duration: 366 + - id: "n2f2kWIGbkY" + title: "Zusätzliche Informationen über die VMs" + description: + type: youtube + video_id: "n2f2kWIGbkY" + duration: 192 + - id: "QJCQLb3xhAI" + title: "Einen Swarm erstellen" + description: + type: youtube + video_id: "QJCQLb3xhAI" + duration: 335 + - id: "18u66b5dKb0" + title: "Eine App im Swarm hosten" + description: + type: youtube + video_id: "18u66b5dKb0" + duration: 333 + - id: "tcuHLhwgKoU" + title: "Den Stack beenden, den Swarm verlassen" + description: + type: youtube + video_id: "tcuHLhwgKoU" + duration: 246 + - id: "-LxLq2ZW00E" + title: "Ein Image nur auf dem Manager starten" + description: + type: youtube + video_id: "-LxLq2ZW00E" + duration: 224 + - id: "UtjLSCQ5JXk" + title: "Einen einzelnen Service im Cluster veröffentlichen" + description: + type: youtube + video_id: "UtjLSCQ5JXk" + duration: 213 + - id: "ac--_k2gLqk" + title: "Services update" + description: + type: youtube + video_id: "ac--_k2gLqk" + duration: 168 + - id: "VjgcxQlzpkI" + title: "Letzte Worte" + description: + type: youtube + video_id: "VjgcxQlzpkI" + duration: 152 + - id: "YYYT91RfkkU" + title: "Joomla mit Docker aufsetzen" + description: + type: youtube + video_id: "YYYT91RfkkU" + duration: 402 + - id: "FgESFWtxFB0" + title: "Docker Compose Dateiformat Version" + description: + type: youtube + video_id: "FgESFWtxFB0" + duration: 252 diff --git a/academy_data/courses/firewalls.yml b/academy_data/courses/firewalls.yml new file mode 100644 index 00000000..826509dc --- /dev/null +++ b/academy_data/courses/firewalls.yml @@ -0,0 +1,112 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7oAAFVjNrAz1uRqIcanXreg +title: "Firewalls: Angriffe und Verteidigung" +description: "Vorbei sind die Zeiten, wo man sich einfach alle seine Webservices hosten konnte. Mittlerweile braucht es leider auch gute Verteidigungsstrategien, um sich gegen Hacker aus aller Welt zu verteidigen. Und eines der wichtigsten Tools dazu ist eine funktionierende Firewall." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/firewalls.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506732 +sections: + - id: section + title: "Einleitung" + description: + lectures: + - id: "IYnhQfDMjj4" + title: "Was sollen Firewalls tun" + description: + type: youtube + video_id: "IYnhQfDMjj4" + duration: 366 + - id: "Hpeq3tdJ09U" + title: "Network Firewall vs Personal Firewall" + description: + type: youtube + video_id: "Hpeq3tdJ09U" + duration: 956 + - id: "AEmHwkeq8xQ" + title: "Next Generation Firewalls, Stateful Firewalls, Packet-Filtering Firewalls" + description: + type: youtube + video_id: "AEmHwkeq8xQ" + duration: 1231 + - id: "0EFeqbfmTyE" + title: "Eine Einführung in FirewallD" + description: + type: youtube + video_id: "0EFeqbfmTyE" + duration: 932 + - id: "ZBsiayncWas" + title: "Gängige Zones in Firewalld" + description: + type: youtube + video_id: "ZBsiayncWas" + duration: 1423 + - id: section2 + title: "OpnSense" + description: + lectures: + - id: "UBAoqQ-15No" + title: "Proxmox auf einem Hetzner Server installieren" + description: + type: youtube + video_id: "UBAoqQ-15No" + duration: 1089 + - id: "uKGkw7KE0ng" + title: "OpnSense auf Proxmox installieren: Nur 1 IP" + description: + type: youtube + video_id: "uKGkw7KE0ng" + duration: 3306 + - id: "GhaGO83VIz0" + title: "OpnSense auf Proxmox: IPv6 Setup" + description: + type: youtube + video_id: "GhaGO83VIz0" + duration: 1799 + - id: "kXULPtfKu_A" + title: "OpnSense: Einrichtung nach Installation" + description: + type: youtube + video_id: "kXULPtfKu_A" + duration: 916 + - id: "tVX2z85wGmg" + title: "OpnSense: VMs anlegen in Proxmox" + description: + type: youtube + video_id: "tVX2z85wGmg" + duration: 2836 + - id: "O2CHWr_AQT0" + title: "OpnSense: TLS Zertifikat via ACME.sh" + description: + type: youtube + video_id: "O2CHWr_AQT0" + duration: 1214 + - id: "lGA3ifzAnRk" + title: "OpnSense: VPN zum Server" + description: + type: youtube + video_id: "lGA3ifzAnRk" + duration: 2026 + - id: "F9uMNMl-GAw" + title: "OpnSense: User Certificates für den VPN einrichten" + description: + type: youtube + video_id: "F9uMNMl-GAw" + duration: 813 + - id: "pLynrwMoorY" + title: "OpnSense: Wireguard VPN" + description: + type: youtube + video_id: "pLynrwMoorY" + duration: 1459 + - id: "jGGrOQT6kqs" + title: "OpnSense: Internes Netzwerk, private Webservices via VPN" + description: + type: youtube + video_id: "jGGrOQT6kqs" + duration: 950 diff --git a/academy_data/courses/ghidra_reverse_engineering.yml b/academy_data/courses/ghidra_reverse_engineering.yml new file mode 100644 index 00000000..3815bc41 --- /dev/null +++ b/academy_data/courses/ghidra_reverse_engineering.yml @@ -0,0 +1,112 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7oQc3MxjWB-rYHHo9vX905a +title: "Reverse Engineering mit Ghidra" +description: "Malware ist mittlerweile überall - doch was genau tut sie? Stiehlt sie Informationen, verschlüsselt sie nur oder nutzt sie das System als Botnetz? Das sind wichtige Informationen, nicht zuletzt um Kunden zu informieren oder die Täter zu schnappen. Und daher muss man die Malware genau analysieren - Beispielsweise mit Ghidra, einem Tool der NSA selbst." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/reversing.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665507867 +sections: + - id: section + title: "Reverse Engineering mit Ghidra" + description: + lectures: + - id: "gdpHhWiiayM" + title: "Ghidra vs. Ida Pro" + description: + type: youtube + video_id: "gdpHhWiiayM" + duration: 693 + - id: "KwVAdKZieag" + title: "Eine einfache Aufgabe" + description: + type: youtube + video_id: "KwVAdKZieag" + duration: 892 + - id: "rnR3T4CWu6s" + title: "Windows .exe-Dateien, Strings finden, Ordnung" + description: + type: youtube + video_id: "rnR3T4CWu6s" + duration: 532 + - id: "I50Qp47G78g" + title: "Vorgehen bei Algorithmen" + description: + type: youtube + video_id: "I50Qp47G78g" + duration: 851 + - id: "UW9RrMJaKN0" + title: "Klassen" + description: + type: youtube + video_id: "UW9RrMJaKN0" + duration: 702 + - id: section2 + title: "Praxisprojekt: WannaCry Reversing" + description: + lectures: + - id: "-OwWG8B2prA" + title: "Strings" + description: + type: youtube + video_id: "-OwWG8B2prA" + duration: 659 + - id: "B0v3Nnmsjq4" + title: "WinMain" + description: + type: youtube + video_id: "B0v3Nnmsjq4" + duration: 655 + - id: "aHSVBnhU0Es" + title: "die ersten Funktionen" + description: + type: youtube + video_id: "aHSVBnhU0Es" + duration: 794 + - id: "kZYHkv5NCjI" + title: "Ressourcen Extrahieren" + description: + type: youtube + video_id: "kZYHkv5NCjI" + duration: 806 + - id: "Ti1PM7VpJo8" + title: "Weiter im Code" + description: + type: youtube + video_id: "Ti1PM7VpJo8" + duration: 853 + - id: "kJbz1lm-DIk" + title: "NAME" + description: + type: youtube + video_id: "kJbz1lm-DIk" + duration: 693 + - id: "XHeRQuTd1pM" + title: "Krypto" + description: + type: youtube + video_id: "XHeRQuTd1pM" + duration: 961 + - id: "j_0bNIZLl8w" + title: "NAME" + description: + type: youtube + video_id: "j_0bNIZLl8w" + duration: 811 + - id: "TMNjeGKunRY" + title: "#9" + description: + type: youtube + video_id: "TMNjeGKunRY" + duration: 728 + - id: "tEelsPRPUU8" + title: "die Kryptographie extrahieren" + description: + type: youtube + video_id: "tEelsPRPUU8" + duration: 995 diff --git a/academy_data/courses/git_und_github.yml b/academy_data/courses/git_und_github.yml new file mode 100644 index 00000000..b4a6901f --- /dev/null +++ b/academy_data/courses/git_und_github.yml @@ -0,0 +1,82 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7rbmmqb1Lt_RGU4DEhelTrR +title: "Git und Github" +description: "Ihr entwickelt eure Programme noch ohne Git? Oh oh... Die Versionierungssoftware Git - und ihr zugehörige Cloud Variante Github - können euch helfen, ungewollte Änderungen rückgängig zu machen, im Team zu arbeiten und gleichzeitig noch das Deployment immens stabiler zu halten. Absolutes Must-Have für jeden in der IT." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/git.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665507293 +sections: + - id: section + title: "Git" + description: + lectures: + - id: "9RbU-h0NH0A" + title: "Lokale Repositories" + description: + type: youtube + video_id: "9RbU-h0NH0A" + duration: 523 + - id: "Oc3jnCqnLjo" + title: "Remote Repositories mit Beispiel Github" + description: + type: youtube + video_id: "Oc3jnCqnLjo" + duration: 346 + - id: "ZVoSBA03Tdc" + title: "Branches, Merges etc" + description: + type: youtube + video_id: "ZVoSBA03Tdc" + duration: 607 + - id: section2 + title: "Github" + description: + lectures: + - id: "mBfbktYFftQ" + title: "In eine Jetbrains IDE einbinden" + description: + type: youtube + video_id: "mBfbktYFftQ" + duration: 661 + - id: "xi4q3dTVSgI" + title: "In der IDE mit Branches arbeiten" + description: + type: youtube + video_id: "xi4q3dTVSgI" + duration: 774 + - id: "l8MZCnrSeQQ" + title: "Pull-Requests" + description: + type: youtube + video_id: "l8MZCnrSeQQ" + duration: 616 + - id: "jRX87fDJDaI" + title: "Ein paar Worte zu Lizenzen" + description: + type: youtube + video_id: "jRX87fDJDaI" + duration: 776 + - id: "wSHNvdRjB9Q" + title: "Issues" + description: + type: youtube + video_id: "wSHNvdRjB9Q" + duration: 408 + - id: "YbuJv8XPVV8" + title: "Templates, Code of Conduct und Beschreibungen" + description: + type: youtube + video_id: "YbuJv8XPVV8" + duration: 531 + - id: "CLz4sedgK-4" + title: "Github Dev: VS Code im Browser direkt nutzen" + description: + type: youtube + video_id: "CLz4sedgK-4" + duration: 260 diff --git a/academy_data/courses/graphentheorie.yml b/academy_data/courses/graphentheorie.yml new file mode 100644 index 00000000..9eff9909 --- /dev/null +++ b/academy_data/courses/graphentheorie.yml @@ -0,0 +1,126 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7q2hZHyLJS6IeHQIlyEgKqf +title: "Graphentheorie (und -praxis)" +description: "Graphen ermöglichen Navigations-Algorithmen, aber auch Zustände, Automaten, all das basiert auf Graphen. Sie zu beherrschen ist also definitiv wichtig - und umfangreicher als man vielleicht denkt." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/algorithmen.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506775 +sections: + - id: section + title: "Graphen" + description: + lectures: + - id: "L-WHssJ8SlU" + title: "Eine Einführung zu Graphen" + description: + type: youtube + video_id: "L-WHssJ8SlU" + duration: 719 + - id: "MbTX_fHo-QQ" + title: "Knotengrade" + description: + type: youtube + video_id: "MbTX_fHo-QQ" + duration: 123 + - id: "BfpfmChIVGc" + title: "Pfade" + description: + type: youtube + video_id: "BfpfmChIVGc" + duration: 282 + - id: "3trqS95bStI" + title: "Gewichtete Graphen" + description: + type: youtube + video_id: "3trqS95bStI" + duration: 331 + - id: "hxL1KcPe6ok" + title: "Teilgraphen" + description: + type: youtube + video_id: "hxL1KcPe6ok" + duration: 296 + - id: "1X-EhqAztiA" + title: "Bäume" + description: + type: youtube + video_id: "1X-EhqAztiA" + duration: 346 + - id: "wu_X9TZfUCE" + title: "Gerichtete Graphen auf Zyklen prüfen" + description: + type: youtube + video_id: "wu_X9TZfUCE" + duration: 904 + - id: "YUIrMxTqI6I" + title: "Breitensuche" + description: + type: youtube + video_id: "YUIrMxTqI6I" + duration: 572 + - id: "rHUKtUlWQq4" + title: "Breitensuche in Python" + description: + type: youtube + video_id: "rHUKtUlWQq4" + duration: 1065 + - id: "Vdjd82O8_B8" + title: "Tiefensuche" + description: + type: youtube + video_id: "Vdjd82O8_B8" + duration: 459 + - id: "Pc1pJpcWQHU" + title: "Tiefensuche in Python" + description: + type: youtube + video_id: "Pc1pJpcWQHU" + duration: 485 + - id: "U1jP6reXQrI" + title: "Tiefensuche im Labyrinth mit Turtle" + description: + type: youtube + video_id: "U1jP6reXQrI" + duration: 1685 + - id: "SUzjEDaJyX0" + title: "Der Dijkstra Algorithmus" + description: + type: youtube + video_id: "SUzjEDaJyX0" + duration: 514 + - id: "kJCdNrYY6rc" + title: "Der Dijkstra Algorithmus in Python" + description: + type: youtube + video_id: "kJCdNrYY6rc" + duration: 1412 + - id: "G9omIe5RyAU" + title: "Der Bellman Ford Algorithmus" + description: + type: youtube + video_id: "G9omIe5RyAU" + duration: 983 + - id: "71WDq4F67gI" + title: "Der Bellman Ford Algorithmus in Python" + description: + type: youtube + video_id: "71WDq4F67gI" + duration: 843 + - id: "XUva15ZNOCA" + title: "Minimum Spanning Trees - Der Kruskal Algorithmus" + description: + type: youtube + video_id: "XUva15ZNOCA" + duration: 537 + - id: "nUZKCdcWo9g" + title: "Der Kruskal Algorithmus in Python" + description: + type: youtube + video_id: "nUZKCdcWo9g" + duration: 953 diff --git a/academy_data/courses/haskell.yml b/academy_data/courses/haskell.yml new file mode 100644 index 00000000..cfafcefb --- /dev/null +++ b/academy_data/courses/haskell.yml @@ -0,0 +1,78 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7pFIXDN1NLw6jMExuK-wN8I +title: "Haskell Programmierung" +description: "Die Programmiersprache gilt wohl als das, was funktionale Programmierung mit am meisten beeinflusst hat. Mittlerweile finden sich Züge hiervon in Python, JavaScript, Kotlin und C++. Doch Haskell zwingt euch als einzige dazu, wirklich anders zu DENKEN - und das macht sie ideal, um funktionale Programmierung besser zu verstehen." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/haskell.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506672 +sections: + - id: section + title: "Haskell" + description: + lectures: + - id: "-KIXPpdnAZs" + title: "Einleitung" + description: + type: youtube + video_id: "-KIXPpdnAZs" + duration: 827 + - id: "Q5baqnT6jLw" + title: "Rekursionen und Akkumulator" + description: + type: youtube + video_id: "Q5baqnT6jLw" + duration: 492 + - id: "JxygG74puB0" + title: "Listen und Pattern Matching" + description: + type: youtube + video_id: "JxygG74puB0" + duration: 805 + - id: "3vVWHpMHVaY" + title: "Mehr zu Listen" + description: + type: youtube + video_id: "3vVWHpMHVaY" + duration: 444 + - id: "LUQhVtRucys" + title: "Lambda-Funktionen und Map" + description: + type: youtube + video_id: "LUQhVtRucys" + duration: 620 + - id: "-lYXNObDzdk" + title: "Filter und Unterversorgen von Funktionen" + description: + type: youtube + video_id: "-lYXNObDzdk" + duration: 623 + - id: "TL5DpNxiTnc" + title: "Variablen dank Let und Where" + description: + type: youtube + video_id: "TL5DpNxiTnc" + duration: 378 + - id: "rxA2DoQ6eso" + title: "Listenkombinatoren" + description: + type: youtube + video_id: "rxA2DoQ6eso" + duration: 752 + - id: "jt3Msx5wwLY" + title: "Unendliche Listen und Lazy Evaluation" + description: + type: youtube + video_id: "jt3Msx5wwLY" + duration: 601 + - id: "R3XEHaw4o44" + title: "Datentypen" + description: + type: youtube + video_id: "R3XEHaw4o44" + duration: 702 diff --git a/academy_data/courses/html5_fuer_anfaenger.yml b/academy_data/courses/html5_fuer_anfaenger.yml new file mode 100644 index 00000000..75270cf9 --- /dev/null +++ b/academy_data/courses/html5_fuer_anfaenger.yml @@ -0,0 +1,108 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7qIbKPeroqn3-BkUTWzYBT4 +title: "HTML 5" +description: "HTML bildet die Grundlage jeder Website. Mit HTML ist auf jeder Website definiert, was der Inhalt ist. HTML ist leicht zu lernen, aber ein absolutes Must-Have, da es mittlerweile sogar häufig außerhalb der Web-Entwicklung zum Einsatz kommt." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/html.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506509 +sections: + - id: section + title: "HTML 5" + description: + lectures: + - id: "pM-G2sIFPkA" + title: "Einleitung" + description: + type: youtube + video_id: "pM-G2sIFPkA" + duration: 446 + - id: "9LmJjujyccw" + title: "einfache Tags" + description: + type: youtube + video_id: "9LmJjujyccw" + duration: 570 + - id: "5ZiAHCPy1jc" + title: "Tags mit Attributen" + description: + type: youtube + video_id: "5ZiAHCPy1jc" + duration: 638 + - id: "cV5q-AbyeAo" + title: "häufig verwendete Tags" + description: + type: youtube + video_id: "cV5q-AbyeAo" + duration: 644 + - id: "s9iZxZUot3A" + title: "Tabellen" + description: + type: youtube + video_id: "s9iZxZUot3A" + duration: 518 + - id: "HRJI36zZ29g" + title: "Listen" + description: + type: youtube + video_id: "HRJI36zZ29g" + duration: 443 + - id: "Vj3DOvPwO0Q" + title: "Struktur und CSS-Zugriffsmöglichkeiten" + description: + type: youtube + video_id: "Vj3DOvPwO0Q" + duration: 545 + - id: "B84vj38QULY" + title: "IFrames" + description: + type: youtube + video_id: "B84vj38QULY" + duration: 380 + - id: "-4BE31wiJAw" + title: "Forms #1" + description: + type: youtube + video_id: "-4BE31wiJAw" + duration: 989 + - id: "ynSOu2rqj7g" + title: "Forms #2" + description: + type: youtube + video_id: "ynSOu2rqj7g" + duration: 804 + - id: "5tKNGQ5iG4Q" + title: "Forms #3" + description: + type: youtube + video_id: "5tKNGQ5iG4Q" + duration: 462 + - id: "t1UwtbrHDsA" + title: "Meta-Tags" + description: + type: youtube + video_id: "t1UwtbrHDsA" + duration: 544 + - id: "ZoFUebsyMr8" + title: "Videos und Untertitel" + description: + type: youtube + video_id: "ZoFUebsyMr8" + duration: 411 + - id: "i01EUb0VuPk" + title: "Audio und YouTube einbetten" + description: + type: youtube + video_id: "i01EUb0VuPk" + duration: 426 + - id: "CR4ZDwlIBtw" + title: "SVG-Grafiken" + description: + type: youtube + video_id: "CR4ZDwlIBtw" + duration: 736 diff --git a/academy_data/courses/iam.yml b/academy_data/courses/iam.yml new file mode 100644 index 00000000..d13b39ba --- /dev/null +++ b/academy_data/courses/iam.yml @@ -0,0 +1,91 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7rBqyMDGlv4LZmNrq1gChjh +title: "Identity- und Access Management / IAM" +description: >- + Willkommen zum Kurs "Identitäts- und Zugriffsmanagement für Informatiker". Dieser umfassende Kurs richtet sich an Informatiker und Fachleute aus dem Bereich IT-Sicherheit, die ihre Kenntnisse im Bereich Identitäts- und Zugriffsmanagement (IAM) vertiefen möchten. In diesem Kurs lernst du, wie du effektive IAM-Strategien entwickeln und umsetzen kannst, um die Sicherheit in deinem Unternehmen oder auch privat zu erhöhen und den unbefugten Zugriff auf sensible Daten und Systeme zu verhindern. Wir werden hier die grundlegenden Konzepte, Technologien und Best Practices vermitteln, die für ein erfolgreiches IAM-Programm erforderlich sind. Dieser Kurs konzentriert sich auf die theoretischen Grundlagen, die für die Verwendung von konkreten Technologien nötig sind. +category: +language: de +image: https://static.bootstrap.academy/thumbnails/iam.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1681146317 +sections: + - id: section + title: "Identity- und Access Management / IAM" + description: + lectures: + - id: "k3pUSPZSk2E" + title: "Einleitung zu Identity und Access Management - IAM #01" + description: + type: youtube + video_id: "k3pUSPZSk2E" + duration: 447 + - id: "UHpDjq1SZYU" + title: "Identitäten vs Accounts - IAM Tutorial #02" + description: + type: youtube + video_id: "UHpDjq1SZYU" + duration: 340 + - id: "GZDjqDeNHvc" + title: "Arten von Identitäten - IAM Tutorial #03" + description: + type: youtube + video_id: "GZDjqDeNHvc" + duration: 614 + - id: "uBAgMznq7r8" + title: "Identity Lifecycle Management - IAM Tutorial #04" + description: + type: youtube + video_id: "uBAgMznq7r8" + duration: 895 + - id: "aNzmdw6Z-M4" + title: "Identitätsnachweise - IAM Tutorial #05" + description: + type: youtube + video_id: "aNzmdw6Z-M4" + duration: 1482 + - id: "qeVvZ25hQeA" + title: "Die Access Control Matrix - IAM Tutorial #06" + description: + type: youtube + video_id: "qeVvZ25hQeA" + duration: 632 + - id: "qnD00VYoa1M" + title: "Role Based Access Control - IAM Tutorial #07" + description: + type: youtube + video_id: "qnD00VYoa1M" + duration: 841 + - id: "g_gG1J9DLKw" + title: "Varianten der RBAC - IAM Tutorial #08" + description: + type: youtube + video_id: "g_gG1J9DLKw" + duration: 633 + - id: "lR54PK54Thk" + title: "Attribute Based Access Control - IAM Tutorial #09" + description: + type: youtube + video_id: "lR54PK54Thk" + duration: 811 + - id: "dQkcTw9g54Q" + title: "Single Sign On - IAM Tutorial #10" + description: + type: youtube + video_id: "dQkcTw9g54Q" + duration: 1053 + - id: "6vCalj0us64" + title: "Privileged Access Management - IAM Tutorial #11" + description: + type: youtube + video_id: "6vCalj0us64" + duration: 752 + - id: "OnSN58iyUUs" + title: "Fallbeispiel: Discords Rollen und Rechte - IAM Tutorial #12" + description: + type: youtube + video_id: "OnSN58iyUUs" + duration: 650 diff --git a/academy_data/courses/it_sicherheit_hacken_essentials.yml b/academy_data/courses/it_sicherheit_hacken_essentials.yml new file mode 100644 index 00000000..c5c68a19 --- /dev/null +++ b/academy_data/courses/it_sicherheit_hacken_essentials.yml @@ -0,0 +1,216 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7oVGaVtkLlu3jYl_D8ugxeT +title: "Grundlagen der IT-Sicherheit" +description: +category: +language: de +image: +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1668100929 +sections: + - id: section + title: "Grundlagen der IT-Sicherheit" + description: + lectures: + - id: "BCsEkMRzrOo" + title: "Was ist IT Sicherheit" + description: + type: youtube + video_id: "BCsEkMRzrOo" + duration: 803 + - id: "0XVvU__CQBU" + title: "Hackerarten und ihre Hüte" + description: + type: youtube + video_id: "0XVvU__CQBU" + duration: 595 + - id: "na3vuTTa30o" + title: "Schutzziele" + description: + type: youtube + video_id: "na3vuTTa30o" + duration: 637 + - id: "7vsSK0GspqU" + title: "Social Engineering und Phishing" + description: + type: youtube + video_id: "7vsSK0GspqU" + duration: 589 + - id: "ZjvcMd3VG_A" + title: "Trojaner und der SourceCode von Meterpreter" + description: + type: youtube + video_id: "ZjvcMd3VG_A" + duration: 1601 + - id: "IlRMgDJPQQE" + title: "Viren und Würmer" + description: + type: youtube + video_id: "IlRMgDJPQQE" + duration: 701 + - id: "oKwjmtHMgsM" + title: "Ransomwares" + description: + type: youtube + video_id: "oKwjmtHMgsM" + duration: 487 + - id: "jYykpF5Y6o4" + title: "Drive-by-Downloads" + description: + type: youtube + video_id: "jYykpF5Y6o4" + duration: 476 + - id: "7x8omaV58lQ" + title: "Schwachstellen, Bedrohungen, Exploits, Zero Days und CVEs" + description: + type: youtube + video_id: "7x8omaV58lQ" + duration: 672 + - id: "P6ieMg9e0N8" + title: "kurzer Kryptographie-Crashkurs" + description: + type: youtube + video_id: "P6ieMg9e0N8" + duration: 437 + - id: "k8zJh1tAcok" + title: "Praxis mit OpenSSL und Angriff gegen AES-ECB" + description: + type: youtube + video_id: "k8zJh1tAcok" + duration: 596 + - id: "gPvudBI2a9g" + title: "Aktive Angreifer und Replay Angriffe" + description: + type: youtube + video_id: "gPvudBI2a9g" + duration: 559 + - id: "nlSmsEJOAsQ" + title: "Asymmetrische Krypto und Man in the middle Angriffe" + description: + type: youtube + video_id: "nlSmsEJOAsQ" + duration: 445 + - id: "qK7BhpkeGxs" + title: "X.509-Zertifikate und Zertifizierungsstellen" + description: + type: youtube + video_id: "qK7BhpkeGxs" + duration: 681 + - id: "aDsc6C2OgEU" + title: "Wie wird wirklich verschlüsselt am Beispiel von TLS" + description: + type: youtube + video_id: "aDsc6C2OgEU" + duration: 580 + - id: "1kV3-Wcu2zw" + title: "Zertifikatwiderruf" + description: + type: youtube + video_id: "1kV3-Wcu2zw" + duration: 408 + - id: "vAjElfpTwKo" + title: "Bot-Netze und DDoS" + description: + type: youtube + video_id: "vAjElfpTwKo" + duration: 526 + - id: "tPWduYBZ2c8" + title: "Wie werden Passwörter gespeichert" + description: + type: youtube + video_id: "tPWduYBZ2c8" + duration: 366 + - id: "a5-83uboWzs" + title: "JSON Web Tokens" + description: + type: youtube + video_id: "a5-83uboWzs" + duration: 876 + - id: "_RUrT74bui0" + title: "Wenn Cybersecurity Leben kostet" + description: + type: youtube + video_id: "_RUrT74bui0" + duration: 818 + - id: "8a6KH7JD4Dg" + title: "Wie Instagram Accounts gehackt werden und was ihr dagegen tun könnt" + description: + type: youtube + video_id: "8a6KH7JD4Dg" + duration: 838 + - id: "SisN1R_Aei4" + title: "Visual Hacking und wie ihr euch verteidigen könnt" + description: + type: youtube + video_id: "SisN1R_Aei4" + duration: 393 + - id: "1ct0j5AuvRU" + title: "Passwort Manager - Warum ihr einen nutzen solltet und welchen ich nutze" + description: + type: youtube + video_id: "1ct0j5AuvRU" + duration: 1155 + - id: "Agfqr5Ur6l0" + title: "Passwortsicherheit ist egal - So machen Google und Co 2FA, MFA und U2F" + description: + type: youtube + video_id: "Agfqr5Ur6l0" + duration: 1438 + - id: "EUxsBVjyiTY" + title: "Veracrypt: verschlüsselte USB Sticks und Dateien erstellen mit Geheim-Fach" + description: + type: youtube + video_id: "EUxsBVjyiTY" + duration: 1686 + - id: "-WymP8TwfcQ" + title: "GnuPG für Windows #1 - Installation und Schlüssel erstellen" + description: + type: youtube + video_id: "-WymP8TwfcQ" + duration: 620 + - id: "y78MITuTqAs" + title: "GnuPG Windows #2 - Nachrichten, Dateien verschlüsseln, signieren und prüfen" + description: + type: youtube + video_id: "y78MITuTqAs" + duration: 815 + - id: "qSz-y7wXF5s" + title: "In Outlook E-Mails verschlüsseln" + description: + type: youtube + video_id: "qSz-y7wXF5s" + duration: 259 + - id: "53llt5oY5I0" + title: "Gmail und Sonstige Web Mail Anbieter verschlüsseln" + description: + type: youtube + video_id: "53llt5oY5I0" + duration: 490 + - id: "mQFdUFDNaUs" + title: "GnuPG Verschlüsselung unter Android mit OpenKeyChain" + description: + type: youtube + video_id: "mQFdUFDNaUs" + duration: 675 + - id: "DmddGxbgEQk" + title: "Mit Virtuellen Maschinen SICHER arbeiten mit Snapshots, Exports und Co" + description: + type: youtube + video_id: "DmddGxbgEQk" + duration: 1741 + - id: "hBuM1qfc3Yw" + title: "Bestes Linux-Backup-Tool: BorgBackup" + description: + type: youtube + video_id: "hBuM1qfc3Yw" + duration: 1278 + - id: "IZzU89SzLWc" + title: "Chrome sicher machen" + description: + type: youtube + video_id: "IZzU89SzLWc" + duration: 2102 diff --git a/academy_data/courses/java.yml b/academy_data/courses/java.yml new file mode 100644 index 00000000..cc0808ba --- /dev/null +++ b/academy_data/courses/java.yml @@ -0,0 +1,144 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7qI9vtiiU5bJBfbxqBailVM +title: "Java Programmierung für Anfänger" +description: "X Milliarden Geräte nutzen Java - und das hat einen Grund. Java kann plattformübergreifend verwendet werden und das macht es so unfassbar angenehm zu nutzen. In den meisten Softwaresystemen von Unternehmen findet sich noch immer Java - auch wenn es weniger werden." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/java.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665508085 +sections: + - id: section + title: "Java für Anfänger" + description: + lectures: + - id: "U1KQrPl3FPg" + title: "Java installieren auf Windows" + description: + type: youtube + video_id: "U1KQrPl3FPg" + duration: 411 + - id: "f9VGF0_Wkzw" + title: "Hello World" + description: + type: youtube + video_id: "f9VGF0_Wkzw" + duration: 663 + - id: "_ip_IbKd7Lc" + title: "Typen und Variablen" + description: + type: youtube + video_id: "_ip_IbKd7Lc" + duration: 862 + - id: "fUU2LufK66c" + title: "If-Anweisungen" + description: + type: youtube + video_id: "fUU2LufK66c" + duration: 777 + - id: "-QFRBm2BptI" + title: "Switch Case" + description: + type: youtube + video_id: "-QFRBm2BptI" + duration: 507 + - id: "UnUuwQT2-Nk" + title: "While und Do-While" + description: + type: youtube + video_id: "UnUuwQT2-Nk" + duration: 569 + - id: "2x-PYhN9M3s" + title: "Arrays" + description: + type: youtube + video_id: "2x-PYhN9M3s" + duration: 638 + - id: "h28nX_JocKg" + title: "Methoden" + description: + type: youtube + video_id: "h28nX_JocKg" + duration: 678 + - id: "U4FUhOtnfSE" + title: "Überladen von Methoden" + description: + type: youtube + video_id: "U4FUhOtnfSE" + duration: 308 + - id: "0U3FfYbkMog" + title: "Klassen" + description: + type: youtube + video_id: "0U3FfYbkMog" + duration: 869 + - id: "EEweBM7sIRk" + title: "Konstruktoren und mehr zu Klassen" + description: + type: youtube + video_id: "EEweBM7sIRk" + duration: 591 + - id: "-HUWV-tbNGw" + title: "Strings" + description: + type: youtube + video_id: "-HUWV-tbNGw" + duration: 756 + - id: "PR9ingLj2bE" + title: "Vererbung" + description: + type: youtube + video_id: "PR9ingLj2bE" + duration: 649 + - id: "xJVJrzm2piM" + title: "Interfaces" + description: + type: youtube + video_id: "xJVJrzm2piM" + duration: 599 + - id: "SSaGhjgVPjc" + title: "abstrakte Klassen und Klassenkonventionen" + description: + type: youtube + video_id: "SSaGhjgVPjc" + duration: 695 + - id: "xbPdJStJqFY" + title: "Modifikatoren" + description: + type: youtube + video_id: "xbPdJStJqFY" + duration: 602 + - id: "t9r2mh2hSAc" + title: "Rekursion und Overflow" + description: + type: youtube + video_id: "t9r2mh2hSAc" + duration: 1299 + - id: "Txw3hDq1nVs" + title: "Benutzereingaben" + description: + type: youtube + video_id: "Txw3hDq1nVs" + duration: 710 + - id: "rDn3AWPk_hw" + title: "Listen" + description: + type: youtube + video_id: "rDn3AWPk_hw" + duration: 1564 + - id: "trjFQXSHZ8s" + title: "Java Crash Kurs für Programmierer in ~30 Minuten" + description: + type: youtube + video_id: "trjFQXSHZ8s" + duration: 1893 + - id: "s6i1Ou6R7vk" + title: "Lerne Java in einem Video - Das Java All in One Tutorial" + description: + type: youtube + video_id: "s6i1Ou6R7vk" + duration: 3633 diff --git a/academy_data/courses/java_algorithmen.yml b/academy_data/courses/java_algorithmen.yml new file mode 100644 index 00000000..1325da3c --- /dev/null +++ b/academy_data/courses/java_algorithmen.yml @@ -0,0 +1,162 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7o4qcD8tepVY5k7YiHYfMu5 +title: "Algorithmen in Java" +description: "Ihr könnt Java? Ein bisschen Übung kann nicht schaden, um eure Kenntnisse über Algorithmen in der Praxis zu vertiefen." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/java.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506355 +sections: + - id: section + title: "Java Algorithmen" + description: + lectures: + - id: "1WGUjrGzZ2g" + title: "Automaten" + description: + type: youtube + video_id: "1WGUjrGzZ2g" + duration: 996 + - id: "MsFhP3sO8go" + title: "Fifos und Stacks" + description: + type: youtube + video_id: "MsFhP3sO8go" + duration: 691 + - id: "MuaikGaCHzQ" + title: "Webcrawler für Youtube" + description: + type: youtube + video_id: "MuaikGaCHzQ" + duration: 1194 + - id: "VcW-MlwJTR8" + title: "Kodierung und Kompression" + description: + type: youtube + video_id: "VcW-MlwJTR8" + duration: 1561 + - id: "TsjqDYjBl5w" + title: "K-Nearest-Neighbours aka kNN" + description: + type: youtube + video_id: "TsjqDYjBl5w" + duration: 1332 + - id: "BOlpNPCE7Y4" + title: "Neuronale Netze" + description: + type: youtube + video_id: "BOlpNPCE7Y4" + duration: 816 + - id: "vzFcMR68DlA" + title: "Training eines Neurons aka Perzeptrons" + description: + type: youtube + video_id: "vzFcMR68DlA" + duration: 716 + - id: "KVVqdijV_7k" + title: "Sampling" + description: + type: youtube + video_id: "KVVqdijV_7k" + duration: 742 + - id: "A-ykNJ5Ysts" + title: "Quantisierung" + description: + type: youtube + video_id: "A-ykNJ5Ysts" + duration: 1119 + - id: "1ncy3GkY0ZI" + title: "Parzen-Windows" + description: + type: youtube + video_id: "1ncy3GkY0ZI" + duration: 657 + - id: "HHbEeDXcsgc" + title: "Markov Modell" + description: + type: youtube + video_id: "HHbEeDXcsgc" + duration: 1159 + - id: "gq9LqlaeZXs" + title: "Bäume: Einleitung" + description: + type: youtube + video_id: "gq9LqlaeZXs" + duration: 595 + - id: "-bdEjEs0d_k" + title: "Mehr zu Bäumen" + description: + type: youtube + video_id: "-bdEjEs0d_k" + duration: 555 + - id: "XOg1jmEIDw4" + title: "balancierte Bäume" + description: + type: youtube + video_id: "XOg1jmEIDw4" + duration: 1417 + - id: "ti26qtqpRdU" + title: "Bubble Sort" + description: + type: youtube + video_id: "ti26qtqpRdU" + duration: 688 + - id: "LcbIisbf5bM" + title: "Insertion Sort" + description: + type: youtube + video_id: "LcbIisbf5bM" + duration: 462 + - id: "2XcfA6WKLPw" + title: "Merge Sort" + description: + type: youtube + video_id: "2XcfA6WKLPw" + duration: 594 + - id: "VhwTKvuQ_Oc" + title: "Invertieren von Bildern" + description: + type: youtube + video_id: "VhwTKvuQ_Oc" + duration: 781 + - id: "RU0y57aK_ng" + title: "Bild in Graustufen konvertieren und Kontrast verbessern" + description: + type: youtube + video_id: "RU0y57aK_ng" + duration: 714 + - id: "ls3zZpfjn_M" + title: "Gaussian Blur" + description: + type: youtube + video_id: "ls3zZpfjn_M" + duration: 1801 + - id: "QL1gNhcBhKk" + title: "Caesar Cipher aka Cäsar Verschlüsselung" + description: + type: youtube + video_id: "QL1gNhcBhKk" + duration: 977 + - id: "ave1We1FQoo" + title: "Das Damen-Problem" + description: + type: youtube + video_id: "ave1We1FQoo" + duration: 1270 + - id: "tevFX3e0Tj8" + title: "Sudokusolver mit Sat4J" + description: + type: youtube + video_id: "tevFX3e0Tj8" + duration: 2879 + - id: "fu42rU7a-fE" + title: "Kantenerkennung" + description: + type: youtube + video_id: "fu42rU7a-fE" + duration: 974 diff --git a/academy_data/courses/java_fortgeschrittene_techniken.yml b/academy_data/courses/java_fortgeschrittene_techniken.yml new file mode 100644 index 00000000..eef3515d --- /dev/null +++ b/academy_data/courses/java_fortgeschrittene_techniken.yml @@ -0,0 +1,338 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7oirQMpjPjrmNx4vcVIGIGY +title: "Java für Fortgeschrittene" +description: "Ihr denkt, ihr könnt Java? Abwarten. Hier sind eingie Themen drin, die ihr in (fast) keinem Studium, Ausbildung und sogar nur in wenigen Betrieben lernt - denn sie machen Entwicklern Angst. Bereit für eine wilde Runde in den Expertenkreisen?" +category: +language: de +image: https://static.bootstrap.academy/thumbnails/java.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506298 +sections: + - id: section + title: "Multithreading" + description: + lectures: + - id: "tcqbIVhdw2s" + title: "Erstellen von Threads" + description: + type: youtube + video_id: "tcqbIVhdw2s" + duration: 444 + - id: "DmAb5BfudxI" + title: "Synchronisation von Threads" + description: + type: youtube + video_id: "DmAb5BfudxI" + duration: 436 + - id: "q-pUT_XOdro" + title: "Deadlocks" + description: + type: youtube + video_id: "q-pUT_XOdro" + duration: 935 + - id: "wspqCy2DKFE" + title: "Kommunikation zwischen Prozessen" + description: + type: youtube + video_id: "wspqCy2DKFE" + duration: 861 + - id: section2 + title: "Debugging und Ordnung" + description: + lectures: + - id: "mqO1x0papKk" + title: "Java Debugging" + description: + type: youtube + video_id: "mqO1x0papKk" + duration: 514 + - id: "hjpK4lLcLFk" + title: "Javadoc" + description: + type: youtube + video_id: "hjpK4lLcLFk" + duration: 539 + - id: "CK8shWNtizk" + title: "JUnit Tests" + description: + type: youtube + video_id: "CK8shWNtizk" + duration: 854 + - id: section3 + title: "Objekt-Orientierung für Profis" + description: + lectures: + - id: "fb7RfVnlVfs" + title: "anonyme innere Klassen und der Grund für OOP" + description: + type: youtube + video_id: "fb7RfVnlVfs" + duration: 687 + - id: "hK8RBOWiY7A" + title: "Attribute vererben" + description: + type: youtube + video_id: "hK8RBOWiY7A" + duration: 612 + - id: "PuXaXs824UU" + title: "Super und Typecasts" + description: + type: youtube + video_id: "PuXaXs824UU" + duration: 781 + - id: "zCJc_Fx7P-4" + title: "Rekursion und dynamische Bindung" + description: + type: youtube + video_id: "zCJc_Fx7P-4" + duration: 529 + - id: "yhbZNvBIX9Q" + title: "Private" + description: + type: youtube + video_id: "yhbZNvBIX9Q" + duration: 439 + - id: "UoJpX561Sg8" + title: "static und instance initializer" + description: + type: youtube + video_id: "UoJpX561Sg8" + duration: 689 + - id: "bPv-mJ-QnDw" + title: "Initializer bei Vererbung" + description: + type: youtube + video_id: "bPv-mJ-QnDw" + duration: 455 + - id: "DX65HTfVe8I" + title: "dynamische Bindung in Konstruktoren und Initializern" + description: + type: youtube + video_id: "DX65HTfVe8I" + duration: 534 + - id: "wQ8ikeKHBFo" + title: "final" + description: + type: youtube + video_id: "wQ8ikeKHBFo" + duration: 869 + - id: "4Gex2cWIiDA" + title: "Tricks und Tücken der Überladung" + description: + type: youtube + video_id: "4Gex2cWIiDA" + duration: 509 + - id: "k4pLHmdL0HE" + title: "static inner classes" + description: + type: youtube + video_id: "k4pLHmdL0HE" + duration: 407 + - id: "Q9fsix-IGvA" + title: "Nested inner classes" + description: + type: youtube + video_id: "Q9fsix-IGvA" + duration: 390 + - id: section4 + title: "Generics" + description: + lectures: + - id: "uLSiFW18OhE" + title: "Einleitung" + description: + type: youtube + video_id: "uLSiFW18OhE" + duration: 398 + - id: "CevmKZNZ7GQ" + title: "Typschranken" + description: + type: youtube + video_id: "CevmKZNZ7GQ" + duration: 475 + - id: "dfPSSPsxDxQ" + title: "Vererbung bei generischen Klassen" + description: + type: youtube + video_id: "dfPSSPsxDxQ" + duration: 488 + - id: "3OtdO12CLgI" + title: "Generische Methoden" + description: + type: youtube + video_id: "3OtdO12CLgI" + duration: 260 + - id: "Uz5CxTqlLu8" + title: "Wildcards" + description: + type: youtube + video_id: "Uz5CxTqlLu8" + duration: 706 + - id: section5 + title: "Reflections" + description: + lectures: + - id: "CWpzke0mZ_E" + title: "Intro" + description: + type: youtube + video_id: "CWpzke0mZ_E" + duration: 621 + - id: "HLTSzsb6WW8" + title: "Instanzen erstellen" + description: + type: youtube + video_id: "HLTSzsb6WW8" + duration: 674 + - id: "fBsZ90w6PfQ" + title: "Fields" + description: + type: youtube + video_id: "fBsZ90w6PfQ" + duration: 578 + - id: "E_Mznt2a_Io" + title: "Methoden" + description: + type: youtube + video_id: "E_Mznt2a_Io" + duration: 434 + - id: "3H9bBhm_lf0" + title: "Zugriff auf private Felder und Methoden" + description: + type: youtube + video_id: "3H9bBhm_lf0" + duration: 379 + - id: "za6nWqISSE4" + title: "Arrays" + description: + type: youtube + video_id: "za6nWqISSE4" + duration: 711 + - id: "RwuOK8K6fOQ" + title: "Generics" + description: + type: youtube + video_id: "RwuOK8K6fOQ" + duration: 800 + - id: "Ued4ncJFPbM" + title: "Der Classloader" + description: + type: youtube + video_id: "Ued4ncJFPbM" + duration: 196 + - id: section6 + title: "Tipps und Tricks" + description: + lectures: + - id: "s54sgTcS75A" + title: "Erste Schritte in Swing" + description: + type: youtube + video_id: "s54sgTcS75A" + duration: 689 + - id: "uU21-fuhHcY" + title: "Laufzeiten" + description: + type: youtube + video_id: "uU21-fuhHcY" + duration: 845 + - id: "DW_AkNTtgio" + title: "YoutubePlayer in Swing - Einbinden fremder Pakete" + description: + type: youtube + video_id: "DW_AkNTtgio" + duration: 1038 + - id: "fzfit1Op0Kc" + title: "In eine txt-Datei schreiben" + description: + type: youtube + video_id: "fzfit1Op0Kc" + duration: 426 + - id: "yU-9JMS52Ss" + title: "Zwischenablage: Auslesen und Reinschreiben" + description: + type: youtube + video_id: "yU-9JMS52Ss" + duration: 467 + - id: "lJw_k1xnaxg" + title: "Drucken" + description: + type: youtube + video_id: "lJw_k1xnaxg" + duration: 570 + - id: "P45lRNbTcmg" + title: "Timer" + description: + type: youtube + video_id: "P45lRNbTcmg" + duration: 301 + - id: "OPTGMxrmf5s" + title: "Time Funktionen und Klassen: Neu in Java 8" + description: + type: youtube + video_id: "OPTGMxrmf5s" + duration: 1041 + - id: "5MTAItl2kOI" + title: "Exceptions und Exception Handling" + description: + type: youtube + video_id: "5MTAItl2kOI" + duration: 735 + - id: "sBddaaWhbOU" + title: "HashSet" + description: + type: youtube + video_id: "sBddaaWhbOU" + duration: 649 + - id: "lpvC3Rfgai8" + title: "TreeSet" + description: + type: youtube + video_id: "lpvC3Rfgai8" + duration: 527 + - id: "xeZkdm7tE3s" + title: "HashMap und TreeMap" + description: + type: youtube + video_id: "xeZkdm7tE3s" + duration: 606 + - id: "KiSXLZlPj3c" + title: "Logging" + description: + type: youtube + video_id: "KiSXLZlPj3c" + duration: 1379 + - id: "d_sM_cucnUE" + title: "RSA" + description: + type: youtube + video_id: "d_sM_cucnUE" + duration: 1359 + - id: "O7TuxKJXBII" + title: "Server" + description: + type: youtube + video_id: "O7TuxKJXBII" + duration: 1098 + - id: "Nu5lZ3oxl9s" + title: "Lambda Ausdrücke" + description: + type: youtube + video_id: "Nu5lZ3oxl9s" + duration: 441 + - id: "6PA84EcGaHM" + title: "Neuronale Netze anwenden mit Snipe" + description: + type: youtube + video_id: "6PA84EcGaHM" + duration: 898 + - id: "NIUGbgLU5Uk" + title: "Enums" + description: + type: youtube + video_id: "NIUGbgLU5Uk" + duration: 500 diff --git a/academy_data/courses/java_ray_tracing.yml b/academy_data/courses/java_ray_tracing.yml new file mode 100644 index 00000000..70f114a5 --- /dev/null +++ b/academy_data/courses/java_ray_tracing.yml @@ -0,0 +1,114 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7rvhHip_LTM-J-5wHw7dWnw +title: "Ray Tracing - Grafikprogrammierung in Java" +description: "Habt ihr jemals gedacht, es wäre schon cool, selbst mal einen Raytracer zu programmieren? Hier seht ihr meinen Anlauf, der von euch ergänzt werden will." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/java.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506397 +sections: + - id: section + title: "Ray Tracing - Grafikprogrammierung in Java" + description: + lectures: + - id: "qpb19vrBpJ4" + title: "Setup und Einleitung" + description: + type: youtube + video_id: "qpb19vrBpJ4" + duration: 878 + - id: "6C9qtjliz3M" + title: "Der erste Teil der Kamera" + description: + type: youtube + video_id: "6C9qtjliz3M" + duration: 605 + - id: "qLHPcTYYr4A" + title: "Die Vector-Klasse" + description: + type: youtube + video_id: "qLHPcTYYr4A" + duration: 1016 + - id: "nfTFDLTzS2Y" + title: "Der 2. Teil der Kamera" + description: + type: youtube + video_id: "nfTFDLTzS2Y" + duration: 700 + - id: "ZcIn6e_UdVs" + title: "Teil 1 des Tracers" + description: + type: youtube + video_id: "ZcIn6e_UdVs" + duration: 649 + - id: "m_IeoWvSbQI" + title: "Teil 2 des Tracers" + description: + type: youtube + video_id: "m_IeoWvSbQI" + duration: 527 + - id: "vjeU6aOntmY" + title: "Schnitt mit einer Kugel" + description: + type: youtube + video_id: "vjeU6aOntmY" + duration: 986 + - id: "lVa2jdiqXqI" + title: "Der erste Output" + description: + type: youtube + video_id: "lVa2jdiqXqI" + duration: 1057 + - id: "BqmNviqfTCo" + title: "Vorbereitungen für die Schattenberechnung" + description: + type: youtube + video_id: "BqmNviqfTCo" + duration: 677 + - id: "R-_J-sFfUCc" + title: "Schnittpunktposition und Normale einer Kugel" + description: + type: youtube + video_id: "R-_J-sFfUCc" + duration: 597 + - id: "ON8ZCpa4KWc" + title: "Die Materialklasse" + description: + type: youtube + video_id: "ON8ZCpa4KWc" + duration: 511 + - id: "352eWQJstzQ" + title: "Licht ins Dunkle" + description: + type: youtube + video_id: "352eWQJstzQ" + duration: 399 + - id: "FzeWe9BYrRI" + title: "Schattenberechnung Teil 1" + description: + type: youtube + video_id: "FzeWe9BYrRI" + duration: 878 + - id: "UzHHkCrFxNY" + title: "Phong Shading" + description: + type: youtube + video_id: "UzHHkCrFxNY" + duration: 976 + - id: "_G_eZ9BljC0" + title: "Shading Output" + description: + type: youtube + video_id: "_G_eZ9BljC0" + duration: 607 + - id: "0bAkPWPnz-U" + title: "Spiegelungen" + description: + type: youtube + video_id: "0bAkPWPnz-U" + duration: 1277 diff --git a/academy_data/courses/java_swing.yml b/academy_data/courses/java_swing.yml new file mode 100644 index 00000000..7be19ffc --- /dev/null +++ b/academy_data/courses/java_swing.yml @@ -0,0 +1,100 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7o5ALam15-pQWtf22RgU6D7 +title: "Java Swing: GUI Erstellung in Java" +description: "Grafische Oberflächen für Desktop-PCs werden zwar seltener, aber manchmal macht das durchaus Sinn. Warum also nicht mit Java Swing?" +category: +language: de +image: https://static.bootstrap.academy/thumbnails/java.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506381 +sections: + - id: section + title: "Java Swing" + description: + lectures: + - id: "s54sgTcS75A" + title: "Erste Schritte in Swing" + description: + type: youtube + video_id: "s54sgTcS75A" + duration: 689 + - id: "U_9ilSvimVE" + title: "Menüs" + description: + type: youtube + video_id: "U_9ilSvimVE" + duration: 1028 + - id: "TxCHvvr2bMQ" + title: "Layouts" + description: + type: youtube + video_id: "TxCHvvr2bMQ" + duration: 905 + - id: "6M1Yvb68vms" + title: "Dialoge" + description: + type: youtube + video_id: "6M1Yvb68vms" + duration: 835 + - id: "rGcUzZe4uPQ" + title: "Label, CheckBox und ComboBox" + description: + type: youtube + video_id: "rGcUzZe4uPQ" + duration: 645 + - id: "7Z58BxdmvwE" + title: "Slider, ProgressBar und ToggleButton" + description: + type: youtube + video_id: "7Z58BxdmvwE" + duration: 521 + - id: "mLgngVGL4Z8" + title: "ScrollPane, List und TextArea" + description: + type: youtube + video_id: "mLgngVGL4Z8" + duration: 492 + - id: "DW_AkNTtgio" + title: "YoutubePlayer in Swing - Einbinden fremder Pakete" + description: + type: youtube + video_id: "DW_AkNTtgio" + duration: 1038 + - id: "N5Bgbhn4hJs" + title: "Grid Bag Layout" + description: + type: youtube + video_id: "N5Bgbhn4hJs" + duration: 761 + - id: section2 + title: "Snake in Swing" + description: + lectures: + - id: "5hq-_yLyr5c" + title: "#1" + description: + type: youtube + video_id: "5hq-_yLyr5c" + duration: 1004 + - id: "5tMQNZ8zmtk" + title: "#2" + description: + type: youtube + video_id: "5tMQNZ8zmtk" + duration: 1098 + - id: "FWKW1N48GsE" + title: "#3" + description: + type: youtube + video_id: "FWKW1N48GsE" + duration: 629 + - id: "wxzy7fpCrF4" + title: "#4" + description: + type: youtube + video_id: "wxzy7fpCrF4" + duration: 655 diff --git a/academy_data/courses/javascript.yml b/academy_data/courses/javascript.yml new file mode 100644 index 00000000..7d2c175a --- /dev/null +++ b/academy_data/courses/javascript.yml @@ -0,0 +1,334 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7qOfMI2ZNk-LXUAiXKrwDIi +title: "JavaScript Programmierung" +description: "JavaScript - die Sprache ohne die kaum eine Website heutzutage noch läuft. Die Sprache, die für die meisten Web-Frameworks zum Einsatz kommt und auch die Sprache, in der mittlerweile eine wahre Vielzahl an Servern(!) geschrieben wurden. Jap. Essentiell." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/javascript.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665507478 +sections: + - id: section + title: "JavaScript Grundlagen" + description: + lectures: + - id: "UeZi8a99iS0" + title: "Einleitung und Einbinden" + description: + type: youtube + video_id: "UeZi8a99iS0" + duration: 421 + - id: "8WpNm5lQoyk" + title: "Ausgaben" + description: + type: youtube + video_id: "8WpNm5lQoyk" + duration: 485 + - id: "HuAFOK4vqZs" + title: "Variablen" + description: + type: youtube + video_id: "HuAFOK4vqZs" + duration: 468 + - id: "0uyMhfpVgXs" + title: "Operatoren" + description: + type: youtube + video_id: "0uyMhfpVgXs" + duration: 359 + - id: "UFQo9mIovpo" + title: "Strings" + description: + type: youtube + video_id: "UFQo9mIovpo" + duration: 405 + - id: "ClF-2WZcE3w" + title: "Booleans" + description: + type: youtube + video_id: "ClF-2WZcE3w" + duration: 365 + - id: "R7yRD_1qp_0" + title: "if-Abfragen" + description: + type: youtube + video_id: "R7yRD_1qp_0" + duration: 474 + - id: "ZHgGIWru5Ec" + title: "Switch Case Statements" + description: + type: youtube + video_id: "ZHgGIWru5Ec" + duration: 386 + - id: "1iae6R8zAoI" + title: "Arrays" + description: + type: youtube + video_id: "1iae6R8zAoI" + duration: 371 + - id: "-VruqDKhryM" + title: "Arrays #2" + description: + type: youtube + video_id: "-VruqDKhryM" + duration: 340 + - id: "HixeTVkfyn4" + title: "For Schleifen" + description: + type: youtube + video_id: "HixeTVkfyn4" + duration: 413 + - id: "rSMrSyW_baw" + title: "For In Schleifen" + description: + type: youtube + video_id: "rSMrSyW_baw" + duration: 169 + - id: "MtdHUmt2w20" + title: "While Schleifen" + description: + type: youtube + video_id: "MtdHUmt2w20" + duration: 325 + - id: "M8VbJhWIGCI" + title: "Break und Continue" + description: + type: youtube + video_id: "M8VbJhWIGCI" + duration: 246 + - id: "WkWVjhURF9s" + title: "Mathematische Funktionen" + description: + type: youtube + video_id: "WkWVjhURF9s" + duration: 478 + - id: "pt0YqMbZO8Q" + title: "Funktionen" + description: + type: youtube + video_id: "pt0YqMbZO8Q" + duration: 285 + - id: "KRIkAnbFq3A" + title: "Parameter und Rückgabewerte" + description: + type: youtube + video_id: "KRIkAnbFq3A" + duration: 346 + - id: "qhi9f8E0Kps" + title: "Rekursive Funktionen" + description: + type: youtube + video_id: "qhi9f8E0Kps" + duration: 295 + - id: "Z5uhFcg4lRg" + title: "Auslagern von Scripts" + description: + type: youtube + video_id: "Z5uhFcg4lRg" + duration: 258 + - id: "LGefU5nrQbg" + title: "Variablenscopes" + description: + type: youtube + video_id: "LGefU5nrQbg" + duration: 287 + - id: section2 + title: "JavaScript im DOM und BOM" + description: + lectures: + - id: "K0PIQ7hispI" + title: "Events - Auf Klick Javascript ausführen" + description: + type: youtube + video_id: "K0PIQ7hispI" + duration: 287 + - id: "7jyy4OcX_FA" + title: "Das Document Object Model DOM" + description: + type: youtube + video_id: "7jyy4OcX_FA" + duration: 425 + - id: "Lkpfu_doJQc" + title: "Elemente" + description: + type: youtube + video_id: "Lkpfu_doJQc" + duration: 788 + - id: "BdukNYP5Aow" + title: "Elemente verändern" + description: + type: youtube + video_id: "BdukNYP5Aow" + duration: 450 + - id: "QIy874Wn1kM" + title: "Animationen" + description: + type: youtube + video_id: "QIy874Wn1kM" + duration: 478 + - id: "1pUiyWP8jAU" + title: "this und Events" + description: + type: youtube + video_id: "1pUiyWP8jAU" + duration: 418 + - id: "sZDjqTnfiGA" + title: "dynamisch neue Elemente erstellen - Nodes" + description: + type: youtube + video_id: "sZDjqTnfiGA" + duration: 736 + - id: "LkYmKRo7-Ak" + title: "dynamisch neue Elemente erstellen #2" + description: + type: youtube + video_id: "LkYmKRo7-Ak" + duration: 301 + - id: "TkoBFAmVgbQ" + title: "Das Browser Object Model BOM" + description: + type: youtube + video_id: "TkoBFAmVgbQ" + duration: 472 + - id: "dtl9_Ob2Hx0" + title: "Das Browser Object Model BOM #2" + description: + type: youtube + video_id: "dtl9_Ob2Hx0" + duration: 252 + - id: "-7fvXr97RDc" + title: "Cookies" + description: + type: youtube + video_id: "-7fvXr97RDc" + duration: 584 + - id: section3 + title: "JavaScript OOP" + description: + lectures: + - id: "kmvpCw0Q0DY" + title: "Objektorientierung" + description: + type: youtube + video_id: "kmvpCw0Q0DY" + duration: 383 + - id: "-YOx-2BhNhs" + title: "Konstruktoren" + description: + type: youtube + video_id: "-YOx-2BhNhs" + duration: 527 + - id: "XGI1e_dthlk" + title: "Methoden" + description: + type: youtube + video_id: "XGI1e_dthlk" + duration: 397 + - id: "XTOKcXRionI" + title: "Prototypes" + description: + type: youtube + video_id: "XTOKcXRionI" + duration: 208 + - id: section4 + title: "JavaScript Nützliches" + description: + lectures: + - id: "HgR6X6QigE0" + title: "Errorhandling" + description: + type: youtube + video_id: "HgR6X6QigE0" + duration: 318 + - id: "NPPJWmEe0EY" + title: "Datum und Uhrzeit" + description: + type: youtube + video_id: "NPPJWmEe0EY" + duration: 484 + - id: "OGe8OlfibQI" + title: "var, let und const" + description: + type: youtube + video_id: "OGe8OlfibQI" + duration: 779 + - id: "k2dLCL-hudE" + title: "Generatoren und Yield" + description: + type: youtube + video_id: "k2dLCL-hudE" + duration: 862 + - id: "vYoMEYTaBYE" + title: "Mehr Informationen zu Generatoren" + description: + type: youtube + video_id: "vYoMEYTaBYE" + duration: 552 + - id: "mvS450Y2FH4" + title: "Arrow Functions" + description: + type: youtube + video_id: "mvS450Y2FH4" + duration: 949 + - id: section5 + title: "Wie geht es weiter?" + description: + lectures: + - id: "uo4PWU-R96k" + title: "TypeScript" + description: + type: youtube + video_id: "uo4PWU-R96k" + duration: 799 + - id: "joVJKCGM2RE" + title: "JavaScript - kann (a ==1 && a== 2 && a==3) jemals True werden?" + description: + type: youtube + video_id: "joVJKCGM2RE" + duration: 271 + - id: "OXW1lu-bLk8" + title: "Sichere Passwörter in JavaScript mit @Unleashed Design" + description: + type: youtube + video_id: "OXW1lu-bLk8" + duration: 1681 + - id: "LQrWkq6_hQQ" + title: "Clean JavaScript Code" + description: + type: youtube + video_id: "LQrWkq6_hQQ" + duration: 1690 + - id: "IyNpu4t30e8" + title: "NodeJS: JavaScript sinnvoll erweitern" + description: + type: youtube + video_id: "IyNpu4t30e8" + duration: 431 + - id: "f15kMS0z5iU" + title: "NPM - Paketmanager für Javascript" + description: + type: youtube + video_id: "f15kMS0z5iU" + duration: 411 + - id: "pRZ5qdJxxgE" + title: "JavaScript - NPM: Abhängigkeiten definieren und Projekte weitergeben mit der Package.json" + description: + type: youtube + video_id: "pRZ5qdJxxgE" + duration: 355 + - id: "Ei7-YOR8oRU" + title: "NPM - Automatisierte Builds und Browserify" + description: + type: youtube + video_id: "Ei7-YOR8oRU" + duration: 1002 + - id: "9mTQPlhNvb8" + title: "NodeJS Tutorial - Mit nodemon unkompliziert schnelleres serverseitiges Arbeiten ermöglichen" + description: + type: youtube + video_id: "9mTQPlhNvb8" + duration: 257 diff --git a/academy_data/courses/javascript_express.yml b/academy_data/courses/javascript_express.yml new file mode 100644 index 00000000..1e1b3659 --- /dev/null +++ b/academy_data/courses/javascript_express.yml @@ -0,0 +1,132 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7ogA_q-mOoYH3dDQIh8B3Oe +title: "ExpressJS: JavaScript Server und APIs in einfach" +description: "Ihr wollt eine API mit JavaScript erstellen? Klar, ihr könnt auch alles von Hand machen.. oder ihr nutzt Express und seid in 20 Minuten durch." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/javascript.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665507444 +sections: + - id: section + title: "Mit Express einfach einen JavaScript Server erstellen" + description: + lectures: + - id: "vTeblk3C7tc" + title: "Einleitung" + description: + type: youtube + video_id: "vTeblk3C7tc" + duration: 286 + - id: "oQn6CWihv-A" + title: "Ein einfacher Express Server" + description: + type: youtube + video_id: "oQn6CWihv-A" + duration: 830 + - id: "cJYnVOJpCJA" + title: "HTTP Methoden und Postman" + description: + type: youtube + video_id: "cJYnVOJpCJA" + duration: 642 + - id: "1MQT_LAFSVo" + title: "Grundlegendes Routing" + description: + type: youtube + video_id: "1MQT_LAFSVo" + duration: 381 + - id: "ym79gBNCRpA" + title: "Statische Ordner" + description: + type: youtube + video_id: "ym79gBNCRpA" + duration: 429 + - id: "xxx3H555t64" + title: "Dateien als Antwort" + description: + type: youtube + video_id: "xxx3H555t64" + duration: 438 + - id: "HLbtNPcGVNo" + title: "Middleware und use vs all" + description: + type: youtube + video_id: "HLbtNPcGVNo" + duration: 930 + - id: "bIRLtRJjlHA" + title: "Daten empfangen via Json und URLEncoded" + description: + type: youtube + video_id: "bIRLtRJjlHA" + duration: 696 + - id: "D_6YZGTG_Pg" + title: "Helmet für mehr Sicherheit" + description: + type: youtube + video_id: "D_6YZGTG_Pg" + duration: 408 + - id: "PhMQh8iVprw" + title: "In Json antworten: eine echte API" + description: + type: youtube + video_id: "PhMQh8iVprw" + duration: 352 + - id: "jAqsi8Ot2W8" + title: "Serverside Rendering: Einführung" + description: + type: youtube + video_id: "jAqsi8Ot2W8" + duration: 625 + - id: "DhWS50ZJY7M" + title: "EJS: Embedded JavaScript" + description: + type: youtube + video_id: "DhWS50ZJY7M" + duration: 603 + - id: "tI_D_H0g9y8" + title: "EJS mit Express verbinden" + description: + type: youtube + video_id: "tI_D_H0g9y8" + duration: 362 + - id: "kFoeoxmvi48" + title: "EJS und Escapes: ein kleiner Ausflug in die Security" + description: + type: youtube + video_id: "kFoeoxmvi48" + duration: 851 + - id: "8FWuPtOgs10" + title: "Fortgeschrittenes Routing" + description: + type: youtube + video_id: "8FWuPtOgs10" + duration: 643 + - id: "kEiVL-RdQsI" + title: "Der Express Router" + description: + type: youtube + video_id: "kEiVL-RdQsI" + duration: 567 + - id: "uaithhg0eIg" + title: "Get-Parameter" + description: + type: youtube + video_id: "uaithhg0eIg" + duration: 666 + - id: "CUDsF03tcvo" + title: "Cookies" + description: + type: youtube + video_id: "CUDsF03tcvo" + duration: 831 + - id: "C2o-9t50Wmc" + title: "Express Generator" + description: + type: youtube + video_id: "C2o-9t50Wmc" + duration: 734 diff --git a/academy_data/courses/javascript_jest.yml b/academy_data/courses/javascript_jest.yml new file mode 100644 index 00000000..775e4e03 --- /dev/null +++ b/academy_data/courses/javascript_jest.yml @@ -0,0 +1,60 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7qgQ2jnCFTo_knQTbpU5W4X +title: "Jest - JavaScript Testing" +description: "Ich weiß, ich weiß, testen ist so ein Ding, das will man nicht unbedingt als Entwickler tun. Aber wer tut's dann? Wer findet die Bugs, wer sagt, was genau schief geht. Am Ende ist man meist deutlich schneller, Tests zu schreiben, als die Bugs vom Kunden finden zu lassen. Und Jest ist DIE Bibliothek für JS Tests." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/javascript.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665508127 +sections: + - id: section + title: "Jest - JavaScript Testing" + description: + lectures: + - id: "Z_OOxP4g25U" + title: "Der erste JavaScript Test" + description: + type: youtube + video_id: "Z_OOxP4g25U" + duration: 978 + - id: "DhlAbTVVV8Y" + title: "Test-Überdeckung Coverage berechnen und Grenzwerte festlegen" + description: + type: youtube + video_id: "DhlAbTVVV8Y" + duration: 616 + - id: "9U4cKUThYIs" + title: "Die Matcher vorgestellt" + description: + type: youtube + video_id: "9U4cKUThYIs" + duration: 964 + - id: "ay9_AwpyoZg" + title: "Asynchrone Funktionen testen" + description: + type: youtube + video_id: "ay9_AwpyoZg" + duration: 755 + - id: "M_y0ENvKlPY" + title: "Setup und Teardown" + description: + type: youtube + video_id: "M_y0ENvKlPY" + duration: 538 + - id: "N90-ii0VSkk" + title: "Mocking" + description: + type: youtube + video_id: "N90-ii0VSkk" + duration: 635 + - id: "JhlLKlHXrWA" + title: "Mocking von Modulen" + description: + type: youtube + video_id: "JhlLKlHXrWA" + duration: 524 diff --git a/academy_data/courses/jquery.yml b/academy_data/courses/jquery.yml new file mode 100644 index 00000000..2b658fbe --- /dev/null +++ b/academy_data/courses/jquery.yml @@ -0,0 +1,96 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7qbE13388pQpsXQkpRQ96sM +title: "jQuery: Leichtere Dynamik in JavaScript" +description: "jQuery ist eine der am meisten verbreiteten JavaScript Bibliotheken. Sie vereinfacht Animationen im Browser und stellt euch eine Reihe an wirklichen Komfort-Funktionen zur Verfügung." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/javascript.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506283 +sections: + - id: section + title: "jQuery" + description: + lectures: + - id: "RbXoevfILuI" + title: "Einleitung" + description: + type: youtube + video_id: "RbXoevfILuI" + duration: 331 + - id: "K8eSuq1eKbg" + title: "Selektoren" + description: + type: youtube + video_id: "K8eSuq1eKbg" + duration: 689 + - id: "Rj3Tp71n3QI" + title: "Events" + description: + type: youtube + video_id: "Rj3Tp71n3QI" + duration: 730 + - id: "glv7nxOzOe8" + title: "Verschwinde Effekte" + description: + type: youtube + video_id: "glv7nxOzOe8" + duration: 480 + - id: "KKb58faJvbo" + title: "Chaining und Callbacks" + description: + type: youtube + video_id: "KKb58faJvbo" + duration: 286 + - id: "QfZZpg0dZxQ" + title: "auf HTML-Elemente zugreifen" + description: + type: youtube + video_id: "QfZZpg0dZxQ" + duration: 657 + - id: "rUY6EQVWeEs" + title: "Attribute verändern" + description: + type: youtube + video_id: "rUY6EQVWeEs" + duration: 249 + - id: "glCnpQsUEVQ" + title: "after und before vs append und prepend" + description: + type: youtube + video_id: "glCnpQsUEVQ" + duration: 247 + - id: "9EBoYWP1btU" + title: "CSS Attribute verändern" + description: + type: youtube + video_id: "9EBoYWP1btU" + duration: 409 + - id: "QXWDsXXVZQM" + title: "Animationen" + description: + type: youtube + video_id: "QXWDsXXVZQM" + duration: 390 + - id: "y8gU9kFiYKs" + title: "AJAX und JQuery - RESTful APIs" + description: + type: youtube + video_id: "y8gU9kFiYKs" + duration: 550 + - id: "nw1rmyrJWew" + title: "Die $.each-Schleife" + description: + type: youtube + video_id: "nw1rmyrJWew" + duration: 366 + - id: "hWgDC4kYSnQ" + title: "not" + description: + type: youtube + video_id: "hWgDC4kYSnQ" + duration: 421 diff --git a/academy_data/courses/kotlin.yml b/academy_data/courses/kotlin.yml new file mode 100644 index 00000000..8d4a35b6 --- /dev/null +++ b/academy_data/courses/kotlin.yml @@ -0,0 +1,222 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7rylgyThgUldHG8KE6Nbc1O +title: "Kotlin Programmierung" +description: "Kotlin ist zwar nicht mehr so unbekannt, wie das vor kurzem noch war. Kotlin ist mittlerweile die Standardsprache für native Android-Apps. Es ist die Sprache, die ihr in jedes Java-Projekt stecken könnt - egal wie alt und dadurch einen modernen Ansatz nutzen könnt, der in Java noch nicht angekommen ist." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/kotlin.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665507680 +sections: + - id: section + title: "Kotlin: Das moderne Java" + description: + lectures: + - id: "HcFY9NSgXkk" + title: "Das bessere Java" + description: + type: youtube + video_id: "HcFY9NSgXkk" + duration: 901 + - id: "rnnlkqgQdJ8" + title: "Die IDE einrichten" + description: + type: youtube + video_id: "rnnlkqgQdJ8" + duration: 338 + - id: "BBu6MSlvA7Y" + title: "IntelliJ als bessere, alternative IDE" + description: + type: youtube + video_id: "BBu6MSlvA7Y" + duration: 798 + - id: "3CX_fZrl90I" + title: "Variablen und Konstanten" + description: + type: youtube + video_id: "3CX_fZrl90I" + duration: 500 + - id: "wG2b0iEqBmw" + title: "Zahlen" + description: + type: youtube + video_id: "wG2b0iEqBmw" + duration: 683 + - id: "6jlxiWJtJqE" + title: "Buchstaben" + description: + type: youtube + video_id: "6jlxiWJtJqE" + duration: 516 + - id: "fX132y4twbE" + title: "Strings" + description: + type: youtube + video_id: "fX132y4twbE" + duration: 243 + - id: "k_0Jo9mLof4" + title: "Arrays" + description: + type: youtube + video_id: "k_0Jo9mLof4" + duration: 566 + - id: "iBB7BBAPWB4" + title: "if Abfragen" + description: + type: youtube + video_id: "iBB7BBAPWB4" + duration: 388 + - id: "8XV9S6bScB0" + title: "Booleans" + description: + type: youtube + video_id: "8XV9S6bScB0" + duration: 627 + - id: "y2MUpG1-2jo" + title: "For Schleifen für Arrays" + description: + type: youtube + video_id: "y2MUpG1-2jo" + duration: 568 + - id: "D7NZeXTmvuI" + title: "Lösung zur Übung Caesar Cipher" + description: + type: youtube + video_id: "D7NZeXTmvuI" + duration: 513 + - id: "6cauhBmIKW8" + title: "While und Do While Schleifen" + description: + type: youtube + video_id: "6cauhBmIKW8" + duration: 506 + - id: "l8kgm8NY6Tw" + title: "Übung - Das Maximum eines Arrays" + description: + type: youtube + video_id: "l8kgm8NY6Tw" + duration: 347 + - id: "AslItyfet1k" + title: "Übung - Fakultät berechnen" + description: + type: youtube + video_id: "AslItyfet1k" + duration: 296 + - id: "I7chONqAB2A" + title: "Mehrdimensionale Arrays" + description: + type: youtube + video_id: "I7chONqAB2A" + duration: 571 + - id: "qfI6JZejM8w" + title: "User Input" + description: + type: youtube + video_id: "qfI6JZejM8w" + duration: 387 + - id: "tQFGCBEMJfw" + title: "Übung - Integer Overflow" + description: + type: youtube + video_id: "tQFGCBEMJfw" + duration: 480 + - id: section3 + title: "Grundlagen von funktionalem Kotlin" + description: + lectures: + - id: "u4Vdnra4310" + title: "Funktionen" + description: + type: youtube + video_id: "u4Vdnra4310" + duration: 482 + - id: "JHyryoU4pX4" + title: "Parameter" + description: + type: youtube + video_id: "JHyryoU4pX4" + duration: 491 + - id: "qUahvS-aRaM" + title: "Rückgabewerte mit return" + description: + type: youtube + video_id: "qUahvS-aRaM" + duration: 664 + - id: "WR6FI7hHSFg" + title: "Rekursion" + description: + type: youtube + video_id: "WR6FI7hHSFg" + duration: 792 + - id: "sKCbFVeJSLk" + title: "Übung: Fakultät" + description: + type: youtube + video_id: "sKCbFVeJSLk" + duration: 526 + - id: section5 + title: "Übungsblock zu Funktionen" + description: + lectures: + - id: "VcSbpr0z2M0" + title: "Übung - Abs" + description: + type: youtube + video_id: "VcSbpr0z2M0" + duration: 235 + - id: "AqImeobt-A8" + title: "Übung - Summe über ein Array" + description: + type: youtube + video_id: "AqImeobt-A8" + duration: 188 + - id: "90rQ6cb8Bi0" + title: "Übung - Sinus von Hand berechnen" + description: + type: youtube + video_id: "90rQ6cb8Bi0" + duration: 811 + - id: "yoE9Yw4Vma8" + title: "Übung - Buchstaben ersetzen" + description: + type: youtube + video_id: "yoE9Yw4Vma8" + duration: 503 + - id: section6 + title: "Klassen und Objekte" + description: + lectures: + - id: "RwZ8YZEX1lo" + title: "Klassen" + description: + type: youtube + video_id: "RwZ8YZEX1lo" + duration: 502 + - id: "0njRtRR07Wg" + title: "Methoden und this" + description: + type: youtube + video_id: "0njRtRR07Wg" + duration: 424 + - id: "djKCjzQbZ7g" + title: "Konstruktoren" + description: + type: youtube + video_id: "djKCjzQbZ7g" + duration: 219 + - id: "7aa1tfXxq3g" + title: "Vererbung" + description: + type: youtube + video_id: "7aa1tfXxq3g" + duration: 471 + - id: "XAVhjK6_7Q4" + title: "Zugriffsmodifikatoren" + description: + type: youtube + video_id: "XAVhjK6_7Q4" + duration: 660 diff --git a/academy_data/courses/kotlin_fortgeschrittene_techniken.yml b/academy_data/courses/kotlin_fortgeschrittene_techniken.yml new file mode 100644 index 00000000..ed2344b3 --- /dev/null +++ b/academy_data/courses/kotlin_fortgeschrittene_techniken.yml @@ -0,0 +1,646 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7rylgyThgUldHG8KE6Nbc1O +title: "Kotlin für Fortgeschrittene" +description: "Kann man Kotlin, kann man programmieren - und zwar wirklich fast alle Arten. Diese Sprache hat so viel zu bieten, ihr werdet staunen." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/kotlin.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665507680 +sections: + - id: section2 + title: "Besondere Features von Kotlin" + description: + lectures: + - id: "Wu7qAEkEbDI" + title: "Maybe Typen" + description: + type: youtube + video_id: "Wu7qAEkEbDI" + duration: 464 + - id: "zipMLBzX0kQ" + title: "if not null else" + description: + type: youtube + video_id: "zipMLBzX0kQ" + duration: 394 + - id: "BJZqu13r-Mk" + title: "Unsigned Typen" + description: + type: youtube + video_id: "BJZqu13r-Mk" + duration: 365 + - id: "HuW9n0z3Ua4" + title: "Zuweisungen mit if Anweisungen" + description: + type: youtube + video_id: "HuW9n0z3Ua4" + duration: 194 + - id: "pWEpcLI0p6c" + title: "Nullable Booleans" + description: + type: youtube + video_id: "pWEpcLI0p6c" + duration: 201 + - id: "--BP0l0D-Nk" + title: "Variablen swappen" + description: + type: youtube + video_id: "--BP0l0D-Nk" + duration: 157 + - id: "1Ebe1KBJ_QA" + title: "Typecasts bei grundlegenden Typen" + description: + type: youtube + video_id: "1Ebe1KBJ_QA" + duration: 503 + - id: "Xgn6AITIk7c" + title: "String Templates" + description: + type: youtube + video_id: "Xgn6AITIk7c" + duration: 192 + - id: "vbGKq8spJbM" + title: "Break und Continue" + description: + type: youtube + video_id: "vbGKq8spJbM" + duration: 490 + - id: "-JlddUWxCsc" + title: "Ranges" + description: + type: youtube + video_id: "-JlddUWxCsc" + duration: 239 + - id: "03Y22SDnSpo" + title: "Foreach Schleifen" + description: + type: youtube + video_id: "03Y22SDnSpo" + duration: 171 + - id: "wOvruRnE03Y" + title: "For Schleifen mit Indizes" + description: + type: youtube + video_id: "wOvruRnE03Y" + duration: 168 + - id: "pQr-sT9azKM" + title: "Pattern Matching mit when" + description: + type: youtube + video_id: "pQr-sT9azKM" + duration: 457 + - id: "ltHYzdNxR7c" + title: "Übung mit Modulo" + description: + type: youtube + video_id: "ltHYzdNxR7c" + duration: 330 + - id: section4 + title: "Funktionale Programmierung: Besonders in Kotlin" + description: + lectures: + - id: "op5F5liCd-A" + title: "Default Parameter" + description: + type: youtube + video_id: "op5F5liCd-A" + duration: 715 + - id: "CxYZMYniWT4" + title: "Einzeilige Funktionen" + description: + type: youtube + video_id: "CxYZMYniWT4" + duration: 218 + - id: section7 + title: "Kotlin bei OOP" + description: + lectures: + - id: "FtTNc6yj_1M" + title: "Getter und Setter" + description: + type: youtube + video_id: "FtTNc6yj_1M" + duration: 609 + - id: "Xg0n-D-EhmA" + title: "Init Blöcke" + description: + type: youtube + video_id: "Xg0n-D-EhmA" + duration: 589 + - id: "-kaP5ZMecYg" + title: "Sekundäre Konstruktoren" + description: + type: youtube + video_id: "-kaP5ZMecYg" + duration: 697 + - id: "7rJZa1W8hsg" + title: "Übung zu Vererbung" + description: + type: youtube + video_id: "7rJZa1W8hsg" + duration: 595 + - id: "2ILQt5rw_OU" + title: "Overrides" + description: + type: youtube + video_id: "2ILQt5rw_OU" + duration: 491 + - id: "RWanQRSf4V8" + title: "Auf die Parent Funktion zugreifen" + description: + type: youtube + video_id: "RWanQRSf4V8" + duration: 298 + - id: "LxAKXq8Wd54" + title: "Abstrakte Klassen" + description: + type: youtube + video_id: "LxAKXq8Wd54" + duration: 460 + - id: "UJlkG6qHTOQ" + title: "Interfaces" + description: + type: youtube + video_id: "UJlkG6qHTOQ" + duration: 785 + - id: "D-yhPufwQfE" + title: "Mehrfachvererbung" + description: + type: youtube + video_id: "D-yhPufwQfE" + duration: 429 + - id: "XJVZDBqEfv4" + title: "TypeCasts" + description: + type: youtube + video_id: "XJVZDBqEfv4" + duration: 791 + - id: "e0g91hCoXbE" + title: "TypeCasts bei nullable Typen" + description: + type: youtube + video_id: "e0g91hCoXbE" + duration: 106 + - id: "uQEo8L5XZSs" + title: "lateinit" + description: + type: youtube + video_id: "uQEo8L5XZSs" + duration: 474 + - id: "3Xo0zC6Rcl8" + title: "Extensions" + description: + type: youtube + video_id: "3Xo0zC6Rcl8" + duration: 555 + - id: "aulgd6WEdBM" + title: "Lambda Funktionen" + description: + type: youtube + video_id: "aulgd6WEdBM" + duration: 305 + - id: section8 + title: "Collections" + description: + lectures: + - id: "7WOIm7mk5eg" + title: "Arrays von speziellen Typen" + description: + type: youtube + video_id: "7WOIm7mk5eg" + duration: 280 + - id: "UxtbMHDGIa0" + title: "Listen" + description: + type: youtube + video_id: "UxtbMHDGIa0" + duration: 636 + - id: "L205LnoxAyE" + title: "Elemente holen" + description: + type: youtube + video_id: "L205LnoxAyE" + duration: 397 + - id: "xJz0SpczXII" + title: "Elemente hinzufügen und löschen" + description: + type: youtube + video_id: "xJz0SpczXII" + duration: 370 + - id: "JTCzzOsGXb4" + title: "Reverse, Partition, Slice und Chunked" + description: + type: youtube + video_id: "JTCzzOsGXb4" + duration: 650 + - id: "jTpch9T2C94" + title: "Take und Drop" + description: + type: youtube + video_id: "jTpch9T2C94" + duration: 427 + - id: "KEaPGheSJYY" + title: "Sortieren" + description: + type: youtube + video_id: "KEaPGheSJYY" + duration: 397 + - id: "GXS3amKoOac" + title: "Map" + description: + type: youtube + video_id: "GXS3amKoOac" + duration: 261 + - id: "dnXRFDTu8UE" + title: "Paare - Pairs" + description: + type: youtube + video_id: "dnXRFDTu8UE" + duration: 206 + - id: "EE8KD1z5_l0" + title: "Zip - Listen vereinen" + description: + type: youtube + video_id: "EE8KD1z5_l0" + duration: 344 + - id: "FrmowP6iVzc" + title: "Reduce" + description: + type: youtube + video_id: "FrmowP6iVzc" + duration: 356 + - id: "2oIV2x2E7O8" + title: "Fold" + description: + type: youtube + video_id: "2oIV2x2E7O8" + duration: 354 + - id: "f8NgRZNcMsQ" + title: "Count, Average, Max, Min, Sum" + description: + type: youtube + video_id: "f8NgRZNcMsQ" + duration: 151 + - id: "ugRzy92fiv8" + title: "Filter" + description: + type: youtube + video_id: "ugRzy92fiv8" + duration: 146 + - id: "3wYmeqO6Hpk" + title: "Finden von Elementen" + description: + type: youtube + video_id: "3wYmeqO6Hpk" + duration: 290 + - id: "ruyq7DcmxGE" + title: "Distinct, Intersect und Union" + description: + type: youtube + video_id: "ruyq7DcmxGE" + duration: 363 + - id: "OWxz7E_V0xo" + title: "All, Any, None" + description: + type: youtube + video_id: "OWxz7E_V0xo" + duration: 341 + - id: "b2o0YDqrjDs" + title: "Contains" + description: + type: youtube + video_id: "b2o0YDqrjDs" + duration: 165 + - id: "dYV_EP9EQDI" + title: "Übung - ist Zahl x y-mal vorhanden" + description: + type: youtube + video_id: "dYV_EP9EQDI" + duration: 212 + - id: "2sqGFB_PSH4" + title: "Sets, HashSets und LinkedSets" + description: + type: youtube + video_id: "2sqGFB_PSH4" + duration: 515 + - id: "mlS6v-_I3tU" + title: "Maps" + description: + type: youtube + video_id: "mlS6v-_I3tU" + duration: 312 + - id: "dHBCyA1dc2M" + title: "HashMaps und LinkedMaps" + description: + type: youtube + video_id: "dHBCyA1dc2M" + duration: 285 + - id: "qXEymoWMQS4" + title: "Hinzufügen und Löschen bei Maps" + description: + type: youtube + video_id: "qXEymoWMQS4" + duration: 258 + - id: "qzc7axfXc3Q" + title: "MapKeys und MapValues" + description: + type: youtube + video_id: "qzc7axfXc3Q" + duration: 224 + - id: "Fm4e6A9-mIE" + title: "Mutable collections" + description: + type: youtube + video_id: "Fm4e6A9-mIE" + duration: 303 + - id: "YUk4qnf5XHw" + title: "Nullables in Collections" + description: + type: youtube + video_id: "YUk4qnf5XHw" + duration: 136 + - id: section9 + title: "Die Standard Library und Best Practice" + description: + lectures: + - id: "ihzHTksJyds" + title: "Imports" + description: + type: youtube + video_id: "ihzHTksJyds" + duration: 551 + - id: "Xk6F2UjUlEU" + title: "run, with, let, also und apply" + description: + type: youtube + video_id: "Xk6F2UjUlEU" + duration: 1256 + - id: "C9SO0JgYiZU" + title: "String Funktionen" + description: + type: youtube + video_id: "C9SO0JgYiZU" + duration: 750 + - id: "bVCWVnwUEQc" + title: "Dateien" + description: + type: youtube + video_id: "bVCWVnwUEQc" + duration: 494 + - id: "6sFZqJ5No8A" + title: "Sehr große und binäre Dateien" + description: + type: youtube + video_id: "6sFZqJ5No8A" + duration: 590 + - id: "mU859MKcSt4" + title: "Zeit" + description: + type: youtube + video_id: "mU859MKcSt4" + duration: 585 + - id: "-JsjsGiXYk0" + title: "Exceptions verarbeiten" + description: + type: youtube + video_id: "-JsjsGiXYk0" + duration: 639 + - id: "rqv3Z3SEkMg" + title: "Try als Expression" + description: + type: youtube + video_id: "rqv3Z3SEkMg" + duration: 236 + - id: "R3EuM5T6eJA" + title: "Exceptions werfen" + description: + type: youtube + video_id: "R3EuM5T6eJA" + duration: 265 + - id: "TLojkfK6PDk" + title: "Eigene Exceptions" + description: + type: youtube + video_id: "TLojkfK6PDk" + duration: 320 + - id: "pugNaQXeLX0" + title: "Zufall" + description: + type: youtube + video_id: "pugNaQXeLX0" + duration: 151 + - id: section10 + title: "Übungsprojekt" + description: + lectures: + - id: "cSKTLkyPt1Y" + title: "Start" + description: + type: youtube + video_id: "cSKTLkyPt1Y" + duration: 801 + - id: "CLDogR65-AY" + title: "Spielfeld" + description: + type: youtube + video_id: "CLDogR65-AY" + duration: 586 + - id: "kY_1YYtob0M" + title: "Wabe" + description: + type: youtube + video_id: "kY_1YYtob0M" + duration: 1280 + - id: "nQuIT8N9rS8" + title: "Spieler" + description: + type: youtube + video_id: "nQuIT8N9rS8" + duration: 344 + - id: "XtsqdOKVXqI" + title: "Items" + description: + type: youtube + video_id: "XtsqdOKVXqI" + duration: 876 + - id: "Oe8jV_yASiE" + title: "Bugfixes" + description: + type: youtube + video_id: "Oe8jV_yASiE" + duration: 999 + - id: section11 + title: "Testing" + description: + lectures: + - id: "CYpLlEGs5xc" + title: "unittests - Einen Test erstellen" + description: + type: youtube + video_id: "CYpLlEGs5xc" + duration: 563 + - id: "PYRvw77fRYs" + title: "Test Coverage" + description: + type: youtube + video_id: "PYRvw77fRYs" + duration: 444 + - id: "lggXrf73W1w" + title: "Vor den Tests" + description: + type: youtube + video_id: "lggXrf73W1w" + duration: 606 + - id: section12 + title: "Fortgeschrittene Funktionale Programmierung" + description: + lectures: + - id: "bAwSNfH8eOg" + title: "Lokale Funktionen" + description: + type: youtube + video_id: "bAwSNfH8eOg" + duration: 373 + - id: "tDrSEB6Bfu4" + title: "Infix Funktionen" + description: + type: youtube + video_id: "tDrSEB6Bfu4" + duration: 345 + - id: "woG7Nc1z5NQ" + title: "Funktionen höherer Ordnung" + description: + type: youtube + video_id: "woG7Nc1z5NQ" + duration: 639 + - id: "N6PHgmzeYhk" + title: "Übung zu Funktionstypen" + description: + type: youtube + video_id: "N6PHgmzeYhk" + duration: 412 + - id: section13 + title: "Generics und fortgeschrittene OOP" + description: + lectures: + - id: "9HfLkDeypFQ" + title: "Operatoren überladen" + description: + type: youtube + video_id: "9HfLkDeypFQ" + duration: 996 + - id: "wwsiwGh95zc" + title: "Generische Typen" + description: + type: youtube + video_id: "wwsiwGh95zc" + duration: 354 + - id: "YBS4RHNzbC4" + title: "Generics in Klassen" + description: + type: youtube + video_id: "YBS4RHNzbC4" + duration: 354 + - id: "ZPcgL86pXa4" + title: "Generics mit Constraints" + description: + type: youtube + video_id: "ZPcgL86pXa4" + duration: 561 + - id: "5MH9HID31co" + title: "Unterklassen von Generics" + description: + type: youtube + video_id: "5MH9HID31co" + duration: 346 + - id: "VATyoEFqlUQ" + title: "Variable Anzahl an Argumenten" + description: + type: youtube + video_id: "VATyoEFqlUQ" + duration: 266 + - id: "4MU2-Hkfr8U" + title: "dataclasses" + description: + type: youtube + video_id: "4MU2-Hkfr8U" + duration: 437 + - id: "gH2FZauJ-a0" + title: "Enums" + description: + type: youtube + video_id: "gH2FZauJ-a0" + duration: 452 + - id: "RjHrQtEorow" + title: "Enums mit Funktionen" + description: + type: youtube + video_id: "RjHrQtEorow" + duration: 337 + - id: "Q1y-Ft3zy0A" + title: "Innere und Nested Classes" + description: + type: youtube + video_id: "Q1y-Ft3zy0A" + duration: 467 + - id: "71q41swcZpU" + title: "Singletons und Objects" + description: + type: youtube + video_id: "71q41swcZpU" + duration: 379 + - id: "fms8_xhE0lA" + title: "Companion Objects" + description: + type: youtube + video_id: "fms8_xhE0lA" + duration: 226 + - id: "5YdAvw_foAo" + title: "Delegation" + description: + type: youtube + video_id: "5YdAvw_foAo" + duration: 393 + - id: section14 + title: "Java Interoperabilität" + description: + lectures: + - id: "bYtTZ3bH3GM" + title: "Java Code von Kotlin aufrufen" + description: + type: youtube + video_id: "bYtTZ3bH3GM" + duration: 187 + - id: "JRQMfT7E1vg" + title: "Kotlin Code von Java aufrufen" + description: + type: youtube + video_id: "JRQMfT7E1vg" + duration: 221 + - id: section15 + title: "Bonus" + description: + lectures: + - id: "ZMg00ibVR04" + title: "Vorerst abschließende Worte" + description: + type: youtube + video_id: "ZMg00ibVR04" + duration: 181 + - id: "a9DKTXPGMgk" + title: "Gradle" + description: + type: youtube + video_id: "a9DKTXPGMgk" + duration: 622 + - id: "QROlyLeOh1c" + title: "Eine Einführung zu SQL Datenbanken in Kotlin" + description: + type: youtube + video_id: "QROlyLeOh1c" + duration: 1251 diff --git a/academy_data/courses/kryptographie.yml b/academy_data/courses/kryptographie.yml new file mode 100644 index 00000000..ed24958a --- /dev/null +++ b/academy_data/courses/kryptographie.yml @@ -0,0 +1,678 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7pWwFv5APk240hrehtCJae- +title: "Theoretische Kryptographie" +description: "Kryptographie ist überall - ihr öffnet eine App? Ihr seid auf einer Website? Wäre ja ziemlich übel, wenn jeder eure Zahlungsdaten mitlesen kann. Ihr schreibt mit Freunden auf Signal? Wäre doof, wenn da jeder mitlesen kann. Zum Glück haben wir Kyptographie. Doch mathematisch ist sie noch spannender als ihr euch das vorstellen könnt!" +category: +language: de +image: https://static.bootstrap.academy/thumbnails/krypto.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665507104 +sections: + - id: section + title: "Historische Kryptographie" + description: + lectures: + - id: "-nK32SkZdgY" + title: "Die Cäsar-Verschlüsselung" + description: + type: youtube + video_id: "-nK32SkZdgY" + duration: 320 + - id: "C9Y7bdOSHVw" + title: "Monoalphabetische Ersetzung und die Häufigkeitsanalyse" + description: + type: youtube + video_id: "C9Y7bdOSHVw" + duration: 626 + - id: "eoYshijt3X4" + title: "Die Vigenère Chiffre" + description: + type: youtube + video_id: "eoYshijt3X4" + duration: 498 + - id: "UOAunUNaMVw" + title: "Grundkonzept von Verschlüsselungen" + description: + type: youtube + video_id: "UOAunUNaMVw" + duration: 448 + - id: "KVM0xNtVX_A" + title: "Das One-Time-Pad" + description: + type: youtube + video_id: "KVM0xNtVX_A" + duration: 536 + - id: "W4JnjVqxtuk" + title: "Das One-Time-Pad in Python" + description: + type: youtube + video_id: "W4JnjVqxtuk" + duration: 992 + - id: "HjShvOcSJJg" + title: "Sicherheit des OTP" + description: + type: youtube + video_id: "HjShvOcSJJg" + duration: 674 + - id: "4mhcrg_dtFA" + title: "Sicherheitsexperimente / -spiele" + description: + type: youtube + video_id: "4mhcrg_dtFA" + duration: 1046 + - id: "WO4gQJ51yqM" + title: "Effiziente Angreifer, Brute Force und Sicherheitsparameter" + description: + type: youtube + video_id: "WO4gQJ51yqM" + duration: 849 + - id: "5D98HSbEPIo" + title: "Vernachlässigbare Funktionen" + description: + type: youtube + video_id: "5D98HSbEPIo" + duration: 485 + - id: "fQcCDf4rHmA" + title: "Reduktionsbeweise am Beispiel vom OTP" + description: + type: youtube + video_id: "fQcCDf4rHmA" + duration: 499 + - id: "ISBf3hNe3ME" + title: "Padding" + description: + type: youtube + video_id: "ISBf3hNe3ME" + duration: 414 + - id: section2 + title: "Symmetrische Kryptographie" + description: + lectures: + - id: "byOeqSB5eFw" + title: "Pseudozufallsgeneratoren" + description: + type: youtube + video_id: "byOeqSB5eFw" + duration: 626 + - id: "yRd8zvzRPHQ" + title: "Beweis mit dem Pseudozufallsgenerator" + description: + type: youtube + video_id: "yRd8zvzRPHQ" + duration: 605 + - id: "SBVbR6oJCGE" + title: "CPA-Sicherheit und Chosen-Plaintext-Attacks" + description: + type: youtube + video_id: "SBVbR6oJCGE" + duration: 550 + - id: "flr659pLRAM" + title: "Stromchiffren aka Stream Ciphers" + description: + type: youtube + video_id: "flr659pLRAM" + duration: 720 + - id: "ZPVXI_Fs2bM" + title: "Blockchiffren und 2 von 4 Betriebsmodi" + description: + type: youtube + video_id: "ZPVXI_Fs2bM" + duration: 877 + - id: "Uf9QjoS-wOY" + title: "Output Feedback Mode und Counter Mode" + description: + type: youtube + video_id: "Uf9QjoS-wOY" + duration: 514 + - id: section3 + title: "Authentifizierung bei symmetrischer Verschlüsselung" + description: + lectures: + - id: "9UPexx86nQ4" + title: "Angriffe auf CPA und CCA Sicherheit" + description: + type: youtube + video_id: "9UPexx86nQ4" + duration: 581 + - id: "7inpl-u5dv8" + title: "Message Authenfication Codes" + description: + type: youtube + video_id: "7inpl-u5dv8" + duration: 403 + - id: "AX3oPX9t7g4" + title: "eine MAC Konstruktion" + description: + type: youtube + video_id: "AX3oPX9t7g4" + duration: 776 + - id: "6Bek2lRIrYE" + title: "CBC-MAC" + description: + type: youtube + video_id: "6Bek2lRIrYE" + duration: 402 + - id: "4RtqOgyapg4" + title: "Verschlüsselung und Authentifikation in Einem" + description: + type: youtube + video_id: "4RtqOgyapg4" + duration: 537 + - id: section4 + title: "Praktisch relevante symmetrische Verschlüsselungsverfahren" + description: + lectures: + - id: "wH6KCWblSh4" + title: "Feistel - Netzwerke" + description: + type: youtube + video_id: "wH6KCWblSh4" + duration: 380 + - id: "m-BoKOi0lds" + title: "Der DES (Data Encryption Standard)" + description: + type: youtube + video_id: "m-BoKOi0lds" + duration: 787 + - id: "fP4DkIDRjZs" + title: "Varianten des DES" + description: + type: youtube + video_id: "fP4DkIDRjZs" + duration: 523 + - id: "w8BXOJ-G9Dw" + title: "Der Meet-in-the-Middle-Angriff auf 2-DES" + description: + type: youtube + video_id: "w8BXOJ-G9Dw" + duration: 673 + - id: "23H_kaE8DMk" + title: "Der AES (Advanced Encryption Standard)" + description: + type: youtube + video_id: "23H_kaE8DMk" + duration: 616 + - id: section5 + title: "Asymmetrische Kryptographie" + description: + lectures: + - id: "L3Q7lPQ8V0M" + title: "Einleitung zur Asymmetrische Kryptographie" + description: + type: youtube + video_id: "L3Q7lPQ8V0M" + duration: 416 + - id: "O0PeIKuF0Nc" + title: "ein bisschen Mathe (zyklische Gruppen)" + description: + type: youtube + video_id: "O0PeIKuF0Nc" + duration: 443 + - id: "_E0SGl7aN70" + title: "Der Diffie-Hellman-Schlüsselaustausch" + description: + type: youtube + video_id: "_E0SGl7aN70" + duration: 362 + - id: "4UAJ-pixR6g" + title: "Das DLOG-Problem" + description: + type: youtube + video_id: "4UAJ-pixR6g" + duration: 417 + - id: "gqxX7udeohQ" + title: "Der Decisional-Diffie-Hellman (DDH)" + description: + type: youtube + video_id: "gqxX7udeohQ" + duration: 361 + - id: "9NORRZ8N4Xw" + title: "El-Gamal Verschlüsselung" + description: + type: youtube + video_id: "9NORRZ8N4Xw" + duration: 566 + - id: "gPnou4AiAPE" + title: "Beweis für CPA-Sicherheit von El Gamal" + description: + type: youtube + video_id: "gPnou4AiAPE" + duration: 787 + - id: "VWOeTrK7clA" + title: "Das Cramer Shoup Lite Kryptosystem" + description: + type: youtube + video_id: "VWOeTrK7clA" + duration: 890 + - id: "e6HsC0ScSh4" + title: "Das Cramer Shoup Kryptosystem" + description: + type: youtube + video_id: "e6HsC0ScSh4" + duration: 725 + - id: "3Qr3aAsS5-Q" + title: "Das RSA-Problem" + description: + type: youtube + video_id: "3Qr3aAsS5-Q" + duration: 768 + - id: "So8us8HUsFg" + title: "RSA Verschlüsselung aus dem Lehrbuch" + description: + type: youtube + video_id: "So8us8HUsFg" + duration: 697 + - id: "ViJPhBijUt0" + title: "RSA PKCS #1 v1 5" + description: + type: youtube + video_id: "ViJPhBijUt0" + duration: 314 + - id: "WISyWBimSFY" + title: "RSA ES OAEP" + description: + type: youtube + video_id: "WISyWBimSFY" + duration: 413 + - id: "il3tkQnSk2c" + title: "Der Rabin-Miller Primzahlgenerator" + description: + type: youtube + video_id: "il3tkQnSk2c" + duration: 589 + - id: "pLn_AqLIdT0" + title: "n-CPA-Sicherheit" + description: + type: youtube + video_id: "pLn_AqLIdT0" + duration: 358 + - id: "Nkk5-HPMyOQ" + title: "n-CPA-Sicherheitsbeweis" + description: + type: youtube + video_id: "Nkk5-HPMyOQ" + duration: 1302 + - id: "5BmtNcG3wF8" + title: "Hybride Verschlüsselung" + description: + type: youtube + video_id: "5BmtNcG3wF8" + duration: 263 + - id: "KaUR8swZda8" + title: "Das McEliece Verfahren - Einleitung: Fehlerbehebungscodes" + description: + type: youtube + video_id: "KaUR8swZda8" + duration: 837 + - id: "TB9L3Nsha34" + title: "Das McEliece Verfahren" + description: + type: youtube + video_id: "TB9L3Nsha34" + duration: 738 + - id: "tK8ajKjeyrU" + title: "CCA1 vs. CCA2-Sicherheit" + description: + type: youtube + video_id: "tK8ajKjeyrU" + duration: 190 + - id: "9_SfpVW1zsc" + title: "k-Repetition-McEliece" + description: + type: youtube + video_id: "9_SfpVW1zsc" + duration: 384 + - id: "VCAdeN5zPL8" + title: "eine CCA1-sichere Variante von McEliece" + description: + type: youtube + video_id: "VCAdeN5zPL8" + duration: 596 + - id: "z5-0ZrKZ0P0" + title: "CCA1-Sicherheits-Beweis für McEliece" + description: + type: youtube + video_id: "z5-0ZrKZ0P0" + duration: 670 + - id: "ToyLBOT_BaU" + title: "CCA2-sicheres McEliece" + description: + type: youtube + video_id: "ToyLBOT_BaU" + duration: 478 + - id: section6 + title: "Kurze Einführung zu Hashfunktionen" + description: + lectures: + - id: "cwePvOfsmUM" + title: "Hashfunktionen" + description: + type: youtube + video_id: "cwePvOfsmUM" + duration: 587 + - id: "P-C6rBuXU8o" + title: "Das Random Oracle Modell" + description: + type: youtube + video_id: "P-C6rBuXU8o" + duration: 270 + - id: "jM6FiSiHzdY" + title: "Die Merkle-Damgard Konstruktion" + description: + type: youtube + video_id: "jM6FiSiHzdY" + duration: 267 + - id: "8H-itWPZDXM" + title: "Die Fast Wide-Pipe Konstruktion" + description: + type: youtube + video_id: "8H-itWPZDXM" + duration: 574 + - id: "a72_qvh6tVE" + title: "Birthday Attacks auf Hashfunktionen" + description: + type: youtube + video_id: "a72_qvh6tVE" + duration: 546 + - id: section7 + title: "Digitale Signaturen" + description: + lectures: + - id: "OdroDXn9xbI" + title: "Digitale Signaturen" + description: + type: youtube + video_id: "OdroDXn9xbI" + duration: 388 + - id: "jhzljqicOCg" + title: "formale Angreifermodelle" + description: + type: youtube + video_id: "jhzljqicOCg" + duration: 819 + - id: "bPHDd6dIqQM" + title: "Lamport Einmalsignaturen" + description: + type: youtube + video_id: "bPHDd6dIqQM" + duration: 870 + - id: "8R8eCL1NlYE" + title: "Einmalsignaturen mit DLOG" + description: + type: youtube + video_id: "8R8eCL1NlYE" + duration: 621 + - id: "hXMw1yhTRrU" + title: "Sicherheitsbeweis zu Einmalsignaturen mit DLOG" + description: + type: youtube + video_id: "hXMw1yhTRrU" + duration: 671 + - id: "bpyCxVBGrig" + title: "Einmalsignaturen mit RSA" + description: + type: youtube + video_id: "bpyCxVBGrig" + duration: 633 + - id: "QaZjcjkdmbA" + title: "Shamir's Trick" + description: + type: youtube + video_id: "QaZjcjkdmbA" + duration: 449 + - id: "w1tFsjhs2sU" + title: "Sicherheitsbeweis des RSA Einmalsignaturverfahrens" + description: + type: youtube + video_id: "w1tFsjhs2sU" + duration: 751 + - id: "yX2VoXHyTgI" + title: "Merkle Trees" + description: + type: youtube + video_id: "yX2VoXHyTgI" + duration: 617 + - id: "6C1puViTjqE" + title: "EUF-CMA Sicherheit bauen" + description: + type: youtube + video_id: "6C1puViTjqE" + duration: 492 + - id: "cUsH9RzgHDM" + title: "Sicherheitsbeweis für die Transformation" + description: + type: youtube + video_id: "cUsH9RzgHDM" + duration: 1283 + - id: "J0ND-bSNRJE" + title: "Chamäleon-Hashfunktionen" + description: + type: youtube + video_id: "J0ND-bSNRJE" + duration: 497 + - id: "xVsJw3UE6gs" + title: "Chamäleon-Hashfunktionen basierend auf DLOG" + description: + type: youtube + video_id: "xVsJw3UE6gs" + duration: 454 + - id: "lwpzcqBbfnI" + title: "Chamäleon-Hashfunktionen basierend auf RSA" + description: + type: youtube + video_id: "lwpzcqBbfnI" + duration: 521 + - id: "2CZ3v8kLrL4" + title: "Chamäleon-Signaturverfahren" + description: + type: youtube + video_id: "2CZ3v8kLrL4" + duration: 484 + - id: "jhLvL4hhXwA" + title: "sEUF-CMA-Sicherheit und Chamäleon-Hashfunktionen als Einmalsignaturverfahren" + description: + type: youtube + video_id: "jhLvL4hhXwA" + duration: 545 + - id: "xgtkvbDI3N4" + title: "Transformation zu sEUF-CMA Sicherheit" + description: + type: youtube + video_id: "xgtkvbDI3N4" + duration: 375 + - id: "7LE03Vachj0" + title: "Lehrbuch RSA-Signaturen" + description: + type: youtube + video_id: "7LE03Vachj0" + duration: 345 + - id: "o2ZIRmQ6rlM" + title: "Angriffe auf RSA Signaturen" + description: + type: youtube + video_id: "o2ZIRmQ6rlM" + duration: 598 + - id: "42B0azOVLmw" + title: "RSA Full Domain Hash" + description: + type: youtube + video_id: "42B0azOVLmw" + duration: 650 + - id: "O8veBaw-mZg" + title: "Die Strong RSA Annahme und GHR Signaturen" + description: + type: youtube + video_id: "O8veBaw-mZg" + duration: 373 + - id: "r61iuIu_YPM" + title: "Sicherheitsbeweis für GHR Signaturen" + description: + type: youtube + video_id: "r61iuIu_YPM" + duration: 686 + - id: "W1kQvijs2k4" + title: "Selektive Sicherheit / SUF" + description: + type: youtube + video_id: "W1kQvijs2k4" + duration: 498 + - id: "72XnzOIvgDY" + title: "Signaturverfahren von Hohenberger und Waters" + description: + type: youtube + video_id: "72XnzOIvgDY" + duration: 681 + - id: "lG4m8vLMhAE" + title: "Der RSA-Signaturstandard" + description: + type: youtube + video_id: "lG4m8vLMhAE" + duration: 698 + - id: "qHEqKIDF1yE" + title: "El-Gamal Signaturen" + description: + type: youtube + video_id: "qHEqKIDF1yE" + duration: 702 + - id: "oa-BwIMMj10" + title: "Schnorr Signaturen" + description: + type: youtube + video_id: "oa-BwIMMj10" + duration: 399 + - id: "vq-PxYzLGCY" + title: "Was passiert mit miesem Zufall" + description: + type: youtube + video_id: "vq-PxYzLGCY" + duration: 331 + - id: "mNZaG6CCJs0" + title: "Der Digital Signature Algorithm DSA" + description: + type: youtube + video_id: "mNZaG6CCJs0" + duration: 778 + - id: "99cBBSB0kZA" + title: "Pairings" + description: + type: youtube + video_id: "99cBBSB0kZA" + duration: 467 + - id: "A53AHVRZ-No" + title: "Joux's 3 Parteien Protokoll" + description: + type: youtube + video_id: "A53AHVRZ-No" + duration: 304 + - id: "WzVOzBkGSZY" + title: "BLS-Signaturen" + description: + type: youtube + video_id: "WzVOzBkGSZY" + duration: 702 + - id: "nH-s1Ukh-EY" + title: "Sicherheitsbeweis für BLS-Signaturen" + description: + type: youtube + video_id: "nH-s1Ukh-EY" + duration: 523 + - id: "2FRa2tfOd9A" + title: "Programmierbare Hashfunktionen" + description: + type: youtube + video_id: "2FRa2tfOd9A" + duration: 848 + - id: "IsJ0ArfAZVQ" + title: "Waters Signaturen" + description: + type: youtube + video_id: "IsJ0ArfAZVQ" + duration: 445 + - id: "xd5fzxbvuok" + title: "EUF-CMA Sicherheitsbeweis für Waters Signaturen" + description: + type: youtube + video_id: "xd5fzxbvuok" + duration: 1462 + - id: section8 + title: "Zero Knowledge und Commitments" + description: + lectures: + - id: "1FQRU1SUr3g" + title: "Zero Knowledge - ich kann Gedanken lesen" + description: + type: youtube + video_id: "1FQRU1SUr3g" + duration: 883 + - id: "Wk-SNFQFjU0" + title: "Hardcore Bits" + description: + type: youtube + video_id: "Wk-SNFQFjU0" + duration: 463 + - id: "B4XHyarT27o" + title: "Asymmetrische Verschlüsselung mit Trapdoor OWPs und HCBs" + description: + type: youtube + video_id: "B4XHyarT27o" + duration: 694 + - id: "hy6AV8_QMes" + title: "Commitment Schemes" + description: + type: youtube + video_id: "hy6AV8_QMes" + duration: 452 + - id: "P4bapsK7_iw" + title: "Pedersen Commitments und das Erreichen von Zero-Knowledge" + description: + type: youtube + video_id: "P4bapsK7_iw" + duration: 542 + - id: section9 + title: "Kryptoanalyse" + description: + lectures: + - id: "CZsh2IT7Iz0" + title: "lineare Kryptoanalyse am Beispiel FEAL" + description: + type: youtube + video_id: "CZsh2IT7Iz0" + duration: 761 + - id: "Hm5L0Sgv2Yg" + title: "lineare Kryptoanalyse am Beispiel FEAL #2" + description: + type: youtube + video_id: "Hm5L0Sgv2Yg" + duration: 537 + - id: "2u9GQZ0yk1w" + title: "lineare Kryptoanalyse von DES" + description: + type: youtube + video_id: "2u9GQZ0yk1w" + duration: 1010 + - id: "JoNP1U0leao" + title: "differentielle Kryptoanalyse von DES" + description: + type: youtube + video_id: "JoNP1U0leao" + duration: 588 + - id: "yUZzJx-f19Y" + title: "differentielle Kryptoanalyse von DES auf mehr als 2 Runden" + description: + type: youtube + video_id: "yUZzJx-f19Y" + duration: 412 + - id: section10 + title: "Bonus" + description: + lectures: + - id: "C-NNAk4ccaM" + title: "Der Wettbewerb für Post-Quanten-Kryptographie ist vorbei!" + description: + type: youtube + video_id: "C-NNAk4ccaM" + duration: 838 diff --git a/academy_data/courses/lambda_kalkuel.yml b/academy_data/courses/lambda_kalkuel.yml new file mode 100644 index 00000000..3060537c --- /dev/null +++ b/academy_data/courses/lambda_kalkuel.yml @@ -0,0 +1,120 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7oBz3PP5sGIkLnmBbw10UUP +title: "Der Lambda Kalkül" +description: "Äh, wut? Der Lambda Kalkül ist wohl der theoretischste Ansatz zu Programmierung, den ihr je gesehen habt. Er versucht Funktionen und Co zu formalisieren und macht das.. mit ein paar extra Windungen im Gehirn. Nehmt euch nen Tee und gleich noch einen Kaffee dazu und gönnt euch." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/lamda.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506696 +sections: + - id: section + title: "Der Lambda Kalkül" + description: + lectures: + - id: "KJmaND1V4r4" + title: "Einführung" + description: + type: youtube + video_id: "KJmaND1V4r4" + duration: 751 + - id: "CeU5CrvsPuw" + title: "Alpha-Äquivalenz" + description: + type: youtube + video_id: "CeU5CrvsPuw" + duration: 346 + - id: "9sFgP105EJg" + title: "Beta Reduktion" + description: + type: youtube + video_id: "9sFgP105EJg" + duration: 452 + - id: "rNmPopvqAzc" + title: "Normalreihenfolge und Normalform" + description: + type: youtube + video_id: "rNmPopvqAzc" + duration: 282 + - id: "LBLCiM34S6Q" + title: "Call-by-Name und Call-by-Value" + description: + type: youtube + video_id: "LBLCiM34S6Q" + duration: 335 + - id: "qx5h6-uLork" + title: "natürliche Zahlen - Church Zahlen" + description: + type: youtube + video_id: "qx5h6-uLork" + duration: 572 + - id: "L1YbhqcBXDw" + title: "Addition von Church-Zahlen" + description: + type: youtube + video_id: "L1YbhqcBXDw" + duration: 477 + - id: "dubTJQ-iGLk" + title: "Multiplikation von Church Zahlen" + description: + type: youtube + video_id: "dubTJQ-iGLk" + duration: 357 + - id: "r4V2fQv8y9g" + title: "True, False, If und AND" + description: + type: youtube + video_id: "r4V2fQv8y9g" + duration: 499 + - id: "xgQRhVQY3mM" + title: "Typsysteme" + description: + type: youtube + video_id: "xgQRhVQY3mM" + duration: 418 + - id: "dQnoxO4SQUI" + title: "Typsysteme: Abstraktionsregel" + description: + type: youtube + video_id: "dQnoxO4SQUI" + duration: 382 + - id: "raTfwW-A-PY" + title: "Typsysteme: Applikationsregel" + description: + type: youtube + video_id: "raTfwW-A-PY" + duration: 462 + - id: "mLt7PIypMvk" + title: "Typsysteme: Konstanten- und Variablenregel" + description: + type: youtube + video_id: "mLt7PIypMvk" + duration: 281 + - id: "F0x6_11fHqM" + title: "Typsysteme: variable Typen" + description: + type: youtube + video_id: "F0x6_11fHqM" + duration: 369 + - id: "ZL3kqMmMyZg" + title: "Typsysteme: Let Regel" + description: + type: youtube + video_id: "ZL3kqMmMyZg" + duration: 874 + - id: "FF-bmQBUzlM" + title: "Typsysteme: Ein Beispielbaum" + description: + type: youtube + video_id: "FF-bmQBUzlM" + duration: 726 + - id: "Bx6-OoYk6H0" + title: "Typsysteme: Unifikation" + description: + type: youtube + video_id: "Bx6-OoYk6H0" + duration: 747 diff --git a/academy_data/courses/latex.yml b/academy_data/courses/latex.yml new file mode 100644 index 00000000..4ebcd1e9 --- /dev/null +++ b/academy_data/courses/latex.yml @@ -0,0 +1,480 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7phxF5hBRWNJx9-KtIHjVYv +title: "LaTeX: Wissenschaftliche Arbeiten schreiben" +description: "Ja, irgendwer muss diese ganzen digitalen Bücher auch layouten, irgendwer muss die Formeln hübsch aussehen lassen - und stellt euch vor, mit Word ist man deutlich langsamer. Deswegen LaTeX." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/latex.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 3000 +learning_goals: [] +requirements: [] +last_update: 1665508460 +sections: + - id: section + title: "LaTeX Tutorial für die Supporter" + description: + lectures: + - id: "yg-KET15Poc" + title: "Einleitung und Installation" + description: + type: youtube + video_id: "yg-KET15Poc" + duration: 1163 + - id: "LOLg_C9QvDg" + title: "Grundlagen" + description: + type: youtube + video_id: "LOLg_C9QvDg" + duration: 718 + - id: "B_ZSw7O35ZY" + title: "Dokument Klassen" + description: + type: youtube + video_id: "B_ZSw7O35ZY" + duration: 781 + - id: section2 + title: "Struktur des Dokuments" + description: + lectures: + - id: "uHbhaCuHLtE" + title: "Titelfolien" + description: + type: youtube + video_id: "uHbhaCuHLtE" + duration: 238 + - id: "MXKOTwoLtto" + title: "Abstracts" + description: + type: youtube + video_id: "MXKOTwoLtto" + duration: 388 + - id: "KCCA5Ycyld8" + title: "Kapitel und Strukturen" + description: + type: youtube + video_id: "KCCA5Ycyld8" + duration: 767 + - id: "Zmmvy_W7E0A" + title: "Inhaltsverzeichnis" + description: + type: youtube + video_id: "Zmmvy_W7E0A" + duration: 383 + - id: "AYbFdDVnPCk" + title: "Neue Seiten und Tiefen im Inhaltsverzeichnis" + description: + type: youtube + video_id: "AYbFdDVnPCk" + duration: 391 + - id: "Ph6FjGecGGU" + title: "Buchlayout" + description: + type: youtube + video_id: "Ph6FjGecGGU" + duration: 331 + - id: section3 + title: "Seitenlayouts und Textformatierung" + description: + lectures: + - id: "FViujku8Fww" + title: "Zeilenabstand" + description: + type: youtube + video_id: "FViujku8Fww" + duration: 491 + - id: "AozCVl1Fe74" + title: "hfill und vfill" + description: + type: youtube + video_id: "AozCVl1Fe74" + duration: 251 + - id: "i1GgMUg4UXU" + title: "Silbentrennung" + description: + type: youtube + video_id: "i1GgMUg4UXU" + duration: 580 + - id: "FAlaTtHNNNY" + title: "Anführungstriche" + description: + type: youtube + video_id: "FAlaTtHNNNY" + duration: 294 + - id: "eqJxuj1NBY0" + title: "Ein ganzer Haufen Textcommands" + description: + type: youtube + video_id: "eqJxuj1NBY0" + duration: 713 + - id: "eo0PmltAji8" + title: "Bündigkeit und Zentrieren" + description: + type: youtube + video_id: "eo0PmltAji8" + duration: 345 + - id: "Iqnm5-IP_2Y" + title: "Paragrapheneinzug" + description: + type: youtube + video_id: "Iqnm5-IP_2Y" + duration: 394 + - id: "mfSO-0AdRQ8" + title: "Mehr zu Paragraphen" + description: + type: youtube + video_id: "mfSO-0AdRQ8" + duration: 499 + - id: section4 + title: "Schrift" + description: + lectures: + - id: "259rSKC0qis" + title: "Die Umgebungen Verbatim und alltt" + description: + type: youtube + video_id: "259rSKC0qis" + duration: 422 + - id: "t18LfokdO_w" + title: "Farben" + description: + type: youtube + video_id: "t18LfokdO_w" + duration: 887 + - id: "ZkJKwWQa7L8" + title: "Schriftart" + description: + type: youtube + video_id: "ZkJKwWQa7L8" + duration: 638 + - id: "3COEZNDQUD0" + title: "Schriftgrößen" + description: + type: youtube + video_id: "3COEZNDQUD0" + duration: 556 + - id: "Y-S9TM3nyY4" + title: "Schriftarten wechseln" + description: + type: youtube + video_id: "Y-S9TM3nyY4" + duration: 343 + - id: "u589dG2gwDY" + title: "Kurze Worte zu Schriftenkodierung" + description: + type: youtube + video_id: "u589dG2gwDY" + duration: 190 + - id: section5 + title: "Listen" + description: + lectures: + - id: "6vlM7R_wVxk" + title: "Listen" + description: + type: youtube + video_id: "6vlM7R_wVxk" + duration: 405 + - id: "qxtwdrO4DaM" + title: "Das Paket enumitem" + description: + type: youtube + video_id: "qxtwdrO4DaM" + duration: 788 + - id: section6 + title: "Tabellen" + description: + lectures: + - id: "T4rR2vpuGPs" + title: "Tabellen" + description: + type: youtube + video_id: "T4rR2vpuGPs" + duration: 702 + - id: "LiB9pfqJxZI" + title: "Text in Tabellen" + description: + type: youtube + video_id: "LiB9pfqJxZI" + duration: 409 + - id: "RpQ7HD5rqdo" + title: "Platzhalter" + description: + type: youtube + video_id: "RpQ7HD5rqdo" + duration: 379 + - id: "0U1TzAImhLQ" + title: "Multicolumns" + description: + type: youtube + video_id: "0U1TzAImhLQ" + duration: 250 + - id: "iO8Z018nj20" + title: "Tabellenunterschriften" + description: + type: youtube + video_id: "iO8Z018nj20" + duration: 146 + - id: "c82iYBIrpSs" + title: "Farben in Tabellen und vereinzelte Vertikale Striche" + description: + type: youtube + video_id: "c82iYBIrpSs" + duration: 463 + - id: section7 + title: "Grafiken" + description: + lectures: + - id: "bWl_gi06shs" + title: "Grafiken importieren" + description: + type: youtube + video_id: "bWl_gi06shs" + duration: 425 + - id: "4j3KzT826N4" + title: "Positionierung von Grafiken und Tabellen" + description: + type: youtube + video_id: "4j3KzT826N4" + duration: 498 + - id: "xyh-rAvlm8g" + title: "Bildbeschreibungen aka Captions" + description: + type: youtube + video_id: "xyh-rAvlm8g" + duration: 472 + - id: "xAMxcu-MXKM" + title: "Textumfluss bei Grafiken" + description: + type: youtube + video_id: "xAMxcu-MXKM" + duration: 430 + - id: "Obw-sNGiV44" + title: "Subfigures" + description: + type: youtube + video_id: "Obw-sNGiV44" + duration: 616 + - id: section8 + title: "Referenzieren und Links" + description: + lectures: + - id: "IEK7JeYlJ8w" + title: "Referenzieren" + description: + type: youtube + video_id: "IEK7JeYlJ8w" + duration: 369 + - id: "HCK2-ZP6HIo" + title: "Referenzieren mit hyperref" + description: + type: youtube + video_id: "HCK2-ZP6HIo" + duration: 347 + - id: "TkQ0d3k0swE" + title: "URLs darstellen" + description: + type: youtube + video_id: "TkQ0d3k0swE" + duration: 462 + - id: "mWHmPw2akBo" + title: "PDF Metadaten und Setups" + description: + type: youtube + video_id: "mWHmPw2akBo" + duration: 572 + - id: "IsIAZuN5exI" + title: "Fußnoten" + description: + type: youtube + video_id: "IsIAZuN5exI" + duration: 760 + - id: section9 + title: "Nochmal Layouts" + description: + lectures: + - id: "M0nOOR0Rah8" + title: "eigene Titelseiten" + description: + type: youtube + video_id: "M0nOOR0Rah8" + duration: 280 + - id: "sxCzZ1Uubf8" + title: "Seitenlayout" + description: + type: youtube + video_id: "sxCzZ1Uubf8" + duration: 546 + - id: "shuyTHZJAp0" + title: "Kapitelüberschriften formatieren" + description: + type: youtube + video_id: "shuyTHZJAp0" + duration: 628 + - id: "N93ixQZFh1Q" + title: "Mehrere Spalten" + description: + type: youtube + video_id: "N93ixQZFh1Q" + duration: 266 + - id: "xo8necL-UEc" + title: "Ein Brief in LaTeX" + description: + type: youtube + video_id: "xo8necL-UEc" + duration: 412 + - id: section10 + title: "Zitieren und Bibliographien" + description: + lectures: + - id: "YDH3L9tudnY" + title: "Bibliographie und zitieren" + description: + type: youtube + video_id: "YDH3L9tudnY" + duration: 584 + - id: "0fGEhXQeUgo" + title: "Bibliographie: Einträge" + description: + type: youtube + video_id: "0fGEhXQeUgo" + duration: 320 + - id: "ugsHpU_l30k" + title: "Zitatoptionen" + description: + type: youtube + video_id: "ugsHpU_l30k" + duration: 320 + - id: "7Z0msgsQ5gQ" + title: "Bibliographiestile" + description: + type: youtube + video_id: "7Z0msgsQ5gQ" + duration: 605 + - id: section11 + title: "Mathematik" + description: + lectures: + - id: "MLrBA2pr4eg" + title: "Mathematik Umgebungen" + description: + type: youtube + video_id: "MLrBA2pr4eg" + duration: 386 + - id: "9O13UFtK4ek" + title: "griechische Buchstaben und Sonderzeichen" + description: + type: youtube + video_id: "9O13UFtK4ek" + duration: 485 + - id: "90LFzhrG4uY" + title: "Formeln" + description: + type: youtube + video_id: "90LFzhrG4uY" + duration: 636 + - id: "1M_gXZ2QFw4" + title: "Klammern" + description: + type: youtube + video_id: "1M_gXZ2QFw4" + duration: 328 + - id: "rjnCDanjRdU" + title: "Matrizen und Vektoren" + description: + type: youtube + video_id: "rjnCDanjRdU" + duration: 537 + - id: "1_ZMStvjTGQ" + title: "Theoreme und Beweise" + description: + type: youtube + video_id: "1_ZMStvjTGQ" + duration: 260 + - id: section12 + title: "Mehr wissenschaftliche Arbeiten" + description: + lectures: + - id: "aAcFd8LxkYc" + title: "Algorithmen" + description: + type: youtube + video_id: "aAcFd8LxkYc" + duration: 337 + - id: "3AVcNn7xnhc" + title: "Quellcode" + description: + type: youtube + video_id: "3AVcNn7xnhc" + duration: 296 + - id: "QYw5uqp8wuU" + title: "Quellcode mit Farbe" + description: + type: youtube + video_id: "QYw5uqp8wuU" + duration: 649 + - id: "_GtjWcF6SIg" + title: "Bäume" + description: + type: youtube + video_id: "_GtjWcF6SIg" + duration: 284 + - id: "ElwzJOQq4DA" + title: "Chemie" + description: + type: youtube + video_id: "ElwzJOQq4DA" + duration: 498 + - id: section13 + title: "Bonus" + description: + lectures: + - id: "TACIGZecwho" + title: "PDF-Dateien importieren" + description: + type: youtube + video_id: "TACIGZecwho" + duration: 422 + - id: "rb2yELiWsc0" + title: "Include und input - Tex Dateien kombinieren" + description: + type: youtube + video_id: "rb2yELiWsc0" + duration: 439 + - id: "a0CDkfCYd3k" + title: "Der Glossar" + description: + type: youtube + video_id: "a0CDkfCYd3k" + duration: 628 + - id: "AIf6CVceIL8" + title: "Mehr zum Glossar: Inhaltsverzeichnis, Plural und Sortierung" + description: + type: youtube + video_id: "AIf6CVceIL8" + duration: 660 + - id: "NbRwcPiYSRg" + title: "Kopf- und Fußzeilen" + description: + type: youtube + video_id: "NbRwcPiYSRg" + duration: 674 + - id: "p-zvPUI6EF4" + title: "Bibliographiestlyes selbst erstellen mit makebst" + description: + type: youtube + video_id: "p-zvPUI6EF4" + duration: 2005 + - id: "-J4LN81cLok" + title: "Flyer erstellen mit Leaflet" + description: + type: youtube + video_id: "-J4LN81cLok" + duration: 504 + - id: "aZvi5WQw994" + title: "Lebenslauf" + description: + type: youtube + video_id: "aZvi5WQw994" + duration: 1195 diff --git a/academy_data/courses/linux.yml b/academy_data/courses/linux.yml new file mode 100644 index 00000000..8d4c59f1 --- /dev/null +++ b/academy_data/courses/linux.yml @@ -0,0 +1,222 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7oaopPUB0SEmzZLf3aE5msy +title: "Erste Schritte mit Linux" +description: "Linux ist überall - auf Servern, auf eurem Handy und vermutlich nach dieser Serie auch auf eurem Rechner :) Viel Spaß." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/linux.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665507322 +sections: + - id: section + title: "Installation von Linux" + description: + lectures: + - id: "bjkyaeseb7g" + title: "Kali Linux: Installation als virtuelle Maschine 2019 - die einfache Variante" + description: + type: youtube + video_id: "bjkyaeseb7g" + duration: 818 + - id: "9lmGxgq7O1Q" + title: "Kali Linux: In Virtualbox installieren 2020 - als virtuelle Maschine: die einfache Variante" + description: + type: youtube + video_id: "9lmGxgq7O1Q" + duration: 833 + - id: "Jf7g0xh8HVU" + title: "Richtige Installation mit Virtual Box" + description: + type: youtube + video_id: "Jf7g0xh8HVU" + duration: 902 + - id: "Gg0suugWa4E" + title: "Auf USB installieren, VirtualBox von USB starten" + description: + type: youtube + video_id: "Gg0suugWa4E" + duration: 427 + - id: "ycnC1j9usTM" + title: "Persistente Installation auf USB" + description: + type: youtube + video_id: "ycnC1j9usTM" + duration: 749 + - id: "J0LjWe36fyU" + title: "Installieren von Linux" + description: + type: youtube + video_id: "J0LjWe36fyU" + duration: 722 + - id: section2 + title: "Grundlagen im Linux Terminal" + description: + lectures: + - id: "aZJlQpiTVkw" + title: "Dateien und Grundbefehle" + description: + type: youtube + video_id: "aZJlQpiTVkw" + duration: 661 + - id: "2RgpNc7AEQU" + title: "Rechte und Rechteverwaltung" + description: + type: youtube + video_id: "2RgpNc7AEQU" + duration: 393 + - id: "EaUt-BC94dY" + title: "Verzeichnisse" + description: + type: youtube + video_id: "EaUt-BC94dY" + duration: 423 + - id: "NkVqUj9GfUg" + title: "Prozessverwaltung" + description: + type: youtube + video_id: "NkVqUj9GfUg" + duration: 364 + - id: "reHytpY3suc" + title: "Filtern" + description: + type: youtube + video_id: "reHytpY3suc" + duration: 580 + - id: "mFOEdorIgQY" + title: "Pipes" + description: + type: youtube + video_id: "mFOEdorIgQY" + duration: 313 + - id: "m5YvHeW3hGg" + title: "Installieren und Archive" + description: + type: youtube + video_id: "m5YvHeW3hGg" + duration: 502 + - id: "MtpOZG_zlgk" + title: "Finden von Dateien" + description: + type: youtube + video_id: "MtpOZG_zlgk" + duration: 330 + - id: "bIkXMVu2fvM" + title: "Links" + description: + type: youtube + video_id: "bIkXMVu2fvM" + duration: 390 + - id: section3 + title: "Nützliches und Spaßiges" + description: + lectures: + - id: "EpbViz5QPjE" + title: "Wetter anzeigen im Terminal mit einer Zeile" + description: + type: youtube + video_id: "EpbViz5QPjE" + duration: 58 + - id: "-aQFREGMXnE" + title: "Dem Terminal Charakter verpassen" + description: + type: youtube + video_id: "-aQFREGMXnE" + duration: 62 + - id: "hSbtq_T_PqU" + title: "Star Wars Episode 4 als ASCII Art" + description: + type: youtube + video_id: "hSbtq_T_PqU" + duration: 132 + - id: "a3yclTCHB8U" + title: "rlwrap" + description: + type: youtube + video_id: "a3yclTCHB8U" + duration: 107 + - id: "3ImniGhMZHI" + title: "Ein einzeiliger Speedtest im Terminal" + description: + type: youtube + video_id: "3ImniGhMZHI" + duration: 84 + - id: "gYcoQaq-iRQ" + title: "Videos konvertieren, schneiden und mehr mit ffmpeg" + description: + type: youtube + video_id: "gYcoQaq-iRQ" + duration: 691 + - id: "lzalyyHuepQ" + title: "Passwort mit Sternchen sichtbar machen" + description: + type: youtube + video_id: "lzalyyHuepQ" + duration: 82 + - id: "HSdPqoFOlAI" + title: "automatisches Herunterfahren" + description: + type: youtube + video_id: "HSdPqoFOlAI" + duration: 164 + - id: "-5HF6eNOUnk" + title: "Autostart" + description: + type: youtube + video_id: "-5HF6eNOUnk" + duration: 182 + - id: "I2-9egjFYJw" + title: "Grub Bootloader anpassen" + description: + type: youtube + video_id: "I2-9egjFYJw" + duration: 219 + - id: "tL1PSKIjPcQ" + title: "Ubuntu im Browser testen" + description: + type: youtube + video_id: "tL1PSKIjPcQ" + duration: 103 + - id: "yyybv6H03YU" + title: "PDF Dateien vereinigen" + description: + type: youtube + video_id: "yyybv6H03YU" + duration: 76 + - id: "R6tpJojTedA" + title: "Bild in Ascii Art konvertieren" + description: + type: youtube + video_id: "R6tpJojTedA" + duration: 107 + - id: section5 + title: "Mehr nützliche Features und Tools" + description: + lectures: + - id: "84ItGdw3Kvk" + title: "DNS Server ändern" + description: + type: youtube + video_id: "84ItGdw3Kvk" + duration: 254 + - id: "vTZen7efha8" + title: "top zur Überwachung der Auslastung" + description: + type: youtube + video_id: "vTZen7efha8" + duration: 594 + - id: "Ur9bf-RMMLA" + title: "Cpulimit" + description: + type: youtube + video_id: "Ur9bf-RMMLA" + duration: 181 + - id: "xzU4I5UO1Qg" + title: "Der Shell-Vergleich: Bash vs ZSH | ZSH und Oh-My-ZSH installieren" + description: + type: youtube + video_id: "xzU4I5UO1Qg" + duration: 1451 diff --git a/academy_data/courses/linux_autokey.yml b/academy_data/courses/linux_autokey.yml new file mode 100644 index 00000000..98161501 --- /dev/null +++ b/academy_data/courses/linux_autokey.yml @@ -0,0 +1,60 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7qCtvw6fiki0ihkwv7tIWN_ +title: "Linux Desktop Automatisierung mit AutoKey" +description: "Ihr wollt Dinge automatisieren, Makros schreiben, schneller unterwegs sein. Ihr leidet an demselben Problem, das ich auch kenne.. und ich hab hier die Lösung für euch. AutoKey." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/linux.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665508161 +sections: + - id: section + title: "AutoKey" + description: + lectures: + - id: "-aSol5omu0U" + title: "Installation" + description: + type: youtube + video_id: "-aSol5omu0U" + duration: 618 + - id: "7thmKIMmq8E" + title: "Zwischenablage" + description: + type: youtube + video_id: "7thmKIMmq8E" + duration: 610 + - id: "dpo-WwEQS1E" + title: "Dialoge" + description: + type: youtube + video_id: "dpo-WwEQS1E" + duration: 1204 + - id: "ZOvkTlZcRGA" + title: "Maus" + description: + type: youtube + video_id: "ZOvkTlZcRGA" + duration: 452 + - id: "o1zI5X_zxI8" + title: "Tastatur" + description: + type: youtube + video_id: "o1zI5X_zxI8" + duration: 753 + - id: "3fGSaBPNO1c" + title: "Fenster" + description: + type: youtube + video_id: "3fGSaBPNO1c" + duration: 752 + - id: "DSKDqv3U7Wc" + title: "Globale Werte" + description: + type: youtube + video_id: "DSKDqv3U7Wc" + duration: 376 diff --git a/academy_data/courses/linux_distributionen.yml b/academy_data/courses/linux_distributionen.yml new file mode 100644 index 00000000..b7d1d717 --- /dev/null +++ b/academy_data/courses/linux_distributionen.yml @@ -0,0 +1,102 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7o15uBS2J9Ryz-pM-P9xcWJ +title: "Linux Distributionen - Vergleich und News" +description: "Ja, ich weiß, Linux ist geil. Aber welches? Da streiten sich die Experten. Aber soll ich euch was sagen? Das ist individuell und jeder darf mögen, was er mag. Schaut euch hier in dieser kleinen Auswahl gerne um." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/linux.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665507306 +sections: + - id: section + title: "Linux Distributionen - Vergleich und News" + description: + lectures: + - id: "W4aHf4_FsHc" + title: "Linux für absolute Einsteiger - Linux Mint kurz vorgestellt und installiert" + description: + type: youtube + video_id: "W4aHf4_FsHc" + duration: 1588 + - id: "2qFfo1Uapa0" + title: "Manjaro Linux - der einfache Alleskönner - kurz vorgestellt und installiert" + description: + type: youtube + video_id: "2qFfo1Uapa0" + duration: 1380 + - id: "VUHUzyvQ2J0" + title: "Das MacOS Linux - Elementary OS - kurz vorgestellt und installiert" + description: + type: youtube + video_id: "VUHUzyvQ2J0" + duration: 1150 + - id: "2xNqD85Qx1s" + title: "Das Bekannteste Linux - Ubuntu Linux" + description: + type: youtube + video_id: "2xNqD85Qx1s" + duration: 1596 + - id: "eyDaalvuOYE" + title: "Linux Tails - Maximale Anonymität - kurz vorgestellt und installiert" + description: + type: youtube + video_id: "eyDaalvuOYE" + duration: 1195 + - id: "bjkyaeseb7g" + title: "Kali Linux Installation als virtuelle Maschine 2019 - die einfache Variante" + description: + type: youtube + video_id: "bjkyaeseb7g" + duration: 818 + - id: "dtlku-GSDw0" + title: "Security und Pentesting Linux - Parrot Linux kurz vorgestellt und installiert" + description: + type: youtube + video_id: "dtlku-GSDw0" + duration: 948 + - id: "NIezfynoMbI" + title: "MX Linux - Einfach und doch flexibel" + description: + type: youtube + video_id: "NIezfynoMbI" + duration: 1214 + - id: "1PBE2YcXXxY" + title: "ReactOS - Windows Open Source" + description: + type: youtube + video_id: "1PBE2YcXXxY" + duration: 487 + - id: "ZIBBPznic_c" + title: "Linux Vergleich - Welche Distribution passt für euch?" + description: + type: youtube + video_id: "ZIBBPznic_c" + duration: 932 + - id: "b0v8yXIE2GU" + title: "Installation von Arch Linux" + description: + type: youtube + video_id: "b0v8yXIE2GU" + duration: 2084 + - id: "Vbzz-EEUSkg" + title: "GrapheneOS Installation | Android in ANONYMER und SICHERER" + description: + type: youtube + video_id: "Vbzz-EEUSkg" + duration: 807 + - id: "ycnC1j9usTM" + title: "[2021] KALI PERSISTENT auf USB installieren" + description: + type: youtube + video_id: "ycnC1j9usTM" + duration: 749 + - id: "JDWtFbwd708" + title: "QubesOS: Das SICHERSTE und ANONYMSTE persistente Betriebssystem" + description: + type: youtube + video_id: "JDWtFbwd708" + duration: 1585 diff --git a/academy_data/courses/linux_gnupg.yml b/academy_data/courses/linux_gnupg.yml new file mode 100644 index 00000000..96705f56 --- /dev/null +++ b/academy_data/courses/linux_gnupg.yml @@ -0,0 +1,36 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7pUKpzMbzggvudByxULkut- +title: "GnuPG unter Linux" +description: "Wir waren uns ja einig: Verschlüsseln ist absolut essentiell. Aber.. wie? Dazu gibt's unter Linux GnuPG." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/krypto.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665508174 +sections: + - id: section + title: "GnuPG unter Linux" + description: + lectures: + - id: "YPQh1Z5zlqw" + title: "Schlüssel generieren" + description: + type: youtube + video_id: "YPQh1Z5zlqw" + duration: 416 + - id: "hVjcKBUAvxk" + title: "Schlüssel austauschen" + description: + type: youtube + video_id: "hVjcKBUAvxk" + duration: 384 + - id: "oitvqDTWQBs" + title: "Verschlüsseln und Signieren" + description: + type: youtube + video_id: "oitvqDTWQBs" + duration: 673 diff --git a/academy_data/courses/llms.yml b/academy_data/courses/llms.yml new file mode 100644 index 00000000..0e4022c5 --- /dev/null +++ b/academy_data/courses/llms.yml @@ -0,0 +1,189 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7r4pg1j8eFsEQp3nL0w4jJz +title: "Mit Large Language Models arbeiten" +description: | + Dieser Kurs bietet eine umfassende Einführung in die Arbeit mit Large Language Models (LLMs) wie ChatGPT und Midjourney. Die Teilnehmer lernen, wie sie diese leistungsstarken Tools als Entwickler nutzen können, warum der Aufbau eigener Modelle oft nicht die beste Option ist und wie sie die Installation von LLMs wie LLama meistern können. + + Der Kurs behandelt auch spezifische Anwendungsfälle und Techniken, wie das Prompt Engineering, um die besten Ergebnisse aus ChatGPT und Midjourney zu erzielen. Die Teilnehmer lernen, wie sie Anweisungen erstellen, Diagramme und Tabellen generieren und die Rollenfunktionen von ChatGPT nutzen können. + + Darüber hinaus werden fortgeschrittene Themen wie das Generieren von Bildern mit Midjourney und Dall-E, die Verbesserung von ChatGPT mit Beispielen (Few-Shot vs. Zero-Shot Prompting) und die Verwendung von ChatGPT und Python zur Identifizierung illegaler Tweets behandelt. + + Der Kurs endet mit einem Blick auf die Zukunft und diskutiert, wie Open-Source-KI bereits mit ChatGPT mithalten kann. + + **Zielgruppe:** + + Dieser Kurs richtet sich an Entwickler, Datenwissenschaftler und alle, die daran interessiert sind, die Möglichkeiten von Large Language Models zu nutzen und zu verstehen. +category: +language: de +image: https://static.bootstrap.academy/thumbnails/llms.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: + - Die Grundlagen und Anwendungen von Large Language Models zu verstehen. + - ChatGPT und andere LLMs effizient für verschiedene Aufgaben einzusetzen. + - Fortgeschrittene Techniken wie Prompt Engineering und Bildgenerierung zu beherrschen. + - Die Grenzen und Möglichkeiten von Open-Source-KI im Vergleich zu proprietären Modellen wie ChatGPT zu verstehen. +requirements: [] +last_update: 1686300755 +sections: + - id: section + title: "Mit Large Language Models arbeiten" + description: + lectures: + - id: "Bll_Ws_NNtk" + title: "Wie ITler ChatGPT realistisch nutzen können!" + description: + type: youtube + video_id: "Bll_Ws_NNtk" + duration: 735 + - id: "r6DIFKA4OiQ" + title: "Warum ChatGPT selbst bauen keine Option ist" + description: + type: youtube + video_id: "r6DIFKA4OiQ" + duration: 825 + - id: "j2mXlzOZ4V4" + title: "GPT-3 einfach ERKLÄRT - DAS steckt HINTER der beliebten KI" + description: + type: youtube + video_id: "j2mXlzOZ4V4" + duration: 615 + - id: "qX_7VGEmTAg" + title: "ChatGPT-Klon LLama: Tutorial für die Installation" + description: + type: youtube + video_id: "qX_7VGEmTAg" + duration: 1201 + - id: "SwALa9WHsLE" + title: "Prompt Engineering: Die besten Ergebnisse aus ChatGPT, Midjourney und Co bekommen | Tutorial #01" + description: + type: youtube + video_id: "SwALa9WHsLE" + duration: 527 + - id: "rq3Ot9RfNhY" + title: "SO müsst ihr ChatGPT etc. Anweisungen geben | Tutorial #02" + description: + type: youtube + video_id: "rq3Ot9RfNhY" + duration: 811 + - id: "aW9F1_2bOTc" + title: "Aus ChatGPT und Co Diagramme, Tabellen etc generieren | Tutorial #03" + description: + type: youtube + video_id: "aW9F1_2bOTc" + duration: 1064 + - id: "-9b9DoYb_g4" + title: "ChatGPT, sei mein Alleskönner: Die Macht von Rollen! | Tutorial #04" + description: + type: youtube + video_id: "-9b9DoYb_g4" + duration: 727 + - id: "MKF5LWgEXow" + title: "ChatGPT KANN Logik: Chain of Thought Prompting | Tutorial #05" + description: + type: youtube + video_id: "MKF5LWgEXow" + duration: 404 + - id: "S8xdCCucFWE" + title: "Mit Beispielen ChatGPT verbessern: Few-Shot vs Zero-Shot Prompting | Tutorial #06" + description: + type: youtube + video_id: "S8xdCCucFWE" + duration: 427 + - id: "KTMI8_mZw7w" + title: "Bessere Texte verfassen: ChatGPT und CoT Prompting | Tutorial #07" + description: + type: youtube + video_id: "KTMI8_mZw7w" + duration: 1115 + - id: "OgMDJZWsst0" + title: "Mit ChatGPT und Whisper Meetings zusammenfassen | Tutorial #08" + description: + type: youtube + video_id: "OgMDJZWsst0" + duration: 646 + - id: "Mi3UFQwCkbg" + title: "Einstufung mit Sinn: Self-Consistency für ChatGPT und Co | Tutorial #09" + description: + type: youtube + video_id: "Mi3UFQwCkbg" + duration: 679 + - id: "4BLpzxVLwH8" + title: "Eine Einführung zu Bildgenerierung mit Midjourney, Dall-E und Co | Tutorial #01" + description: + type: youtube + video_id: "4BLpzxVLwH8" + duration: 500 + - id: "86Hvl-_hrBI" + title: "Iterative Bildgenerierung mit Midjourney, Dall-E und Co | Tutorial #02" + description: + type: youtube + video_id: "86Hvl-_hrBI" + duration: 614 + - id: "0vy3HG-3SmE" + title: "Midjourney: Gewichte und nie wieder schlechte Hände | Tutorial #03" + description: + type: youtube + video_id: "0vy3HG-3SmE" + duration: 497 + - id: "f_8G4_PQw9c" + title: "Midjourney: Seed, Chaos und Stil erklärt | Tutorial #04" + description: + type: youtube + video_id: "f_8G4_PQw9c" + duration: 623 + - id: "Vcd8HDh-9_A" + title: "Midjourney und Co: Tipps für FOTOREALISTISCHE Menschen | Tutorial #05" + description: + type: youtube + video_id: "Vcd8HDh-9_A" + duration: 593 + - id: "OF9ns2xjouE" + title: "Midjourney: Bilder als EINGABE | Tutorial #06" + description: + type: youtube + video_id: "OF9ns2xjouE" + duration: 397 + - id: "pAwodqn6Pg0" + title: "ChatGPT und Midjourney im Tandem für schnellere Prompts | Tutorial #07" + description: + type: youtube + video_id: "pAwodqn6Pg0" + duration: 361 + - id: "WjdGmiblRF8" + title: "Midjourney: Ultimate Guide zu LOGOs | Tutorial #08" + description: + type: youtube + video_id: "WjdGmiblRF8" + duration: 620 + - id: "SFVE_HzEW5c" + title: "Midjourney: Beleuchtung und Perspektiven | Tutorial #09" + description: + type: youtube + video_id: "SFVE_HzEW5c" + duration: 653 + - id: "cshoZdn-gWA" + title: "Web Design mit Midjourney erledigen | Tutorial #10" + description: + type: youtube + video_id: "cshoZdn-gWA" + duration: 502 + - id: "QdbbWI-I_Ww" + title: "ChatGPT und Python um illegale Tweets zu finden" + description: + type: youtube + video_id: "QdbbWI-I_Ww" + duration: 1149 + - id: "K54SMQRCnoc" + title: "Wir bauen die Satire-KI mit ChatGPT" + description: + type: youtube + video_id: "K54SMQRCnoc" + duration: 588 + - id: "UjeHGXbiqLQ" + title: "GPT4All: Open-Source KI kann schon fast mit ChatGPT mithalten!" + description: + type: youtube + video_id: "UjeHGXbiqLQ" + duration: 1222 diff --git a/academy_data/courses/logik.yml b/academy_data/courses/logik.yml new file mode 100644 index 00000000..cf9d16c5 --- /dev/null +++ b/academy_data/courses/logik.yml @@ -0,0 +1,244 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7r7ztDWJ66pMNRYaa_TUjKP +title: "Formale Logik" +description: "If True ... Else If False... - aber was wenn es etwas komplexer sein darf? Was wenn ein ganzes Gleichungssystem daherkommt? Vielleicht sogar noch Funktionen dazu? Jup, das kann man auch rechnen." +category: +language: de +image: "https://static.bootstrap.academy/thumbnails/formale logik.jpg" +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506249 +sections: + - id: section + title: "Aussagenlogik" + description: + lectures: + - id: "ABuhSltG8yY" + title: "Und, Oder, Nicht" + description: + type: youtube + video_id: "ABuhSltG8yY" + duration: 591 + - id: "4FvPKAlknfQ" + title: "Implikation und Äquivalenz" + description: + type: youtube + video_id: "4FvPKAlknfQ" + duration: 514 + - id: "36KmhqViegI" + title: "XOR, NOR, NAND" + description: + type: youtube + video_id: "36KmhqViegI" + duration: 455 + - id: "365sKG0BKSE" + title: "Die De Morgan'schen Gesetze" + description: + type: youtube + video_id: "365sKG0BKSE" + duration: 370 + - id: "MhS_NHY-aRI" + title: "boolsche Funktionen" + description: + type: youtube + video_id: "MhS_NHY-aRI" + duration: 558 + - id: "vsCfuQZ4Tj4" + title: "Logische Grundgesetze" + description: + type: youtube + video_id: "vsCfuQZ4Tj4" + duration: 806 + - id: "y7oPW-b-2DM" + title: "Normalformen" + description: + type: youtube + video_id: "y7oPW-b-2DM" + duration: 619 + - id: "N9VISlcJhQE" + title: "Vollständige Normalformen aus Wahrheitstabelle" + description: + type: youtube + video_id: "N9VISlcJhQE" + duration: 704 + - id: "5anTmbtGSjk" + title: "Normalformen umwandeln" + description: + type: youtube + video_id: "5anTmbtGSjk" + duration: 833 + - id: "1J1wtrEVUtw" + title: "Shannon Formeln, Bäume und deren Reduktion" + description: + type: youtube + video_id: "1J1wtrEVUtw" + duration: 777 + - id: "N8sK28aWYyQ" + title: "Basen" + description: + type: youtube + video_id: "N8sK28aWYyQ" + duration: 222 + - id: "gNGaJzUS0KY" + title: "Metasprache und das Craigsche Interpolationslemma" + description: + type: youtube + video_id: "gNGaJzUS0KY" + duration: 759 + - id: "keILzTb0Soo" + title: "SatSolving und der DPLL Algorithmus" + description: + type: youtube + video_id: "keILzTb0Soo" + duration: 1762 + - id: "tevFX3e0Tj8" + title: "Ein Sudokusolver in Java mit Sat4J" + description: + type: youtube + video_id: "tevFX3e0Tj8" + duration: 2879 + - id: "rcAZ8oIvcUY" + title: "Modelle, Interpretationen, Folgerungen und Äquivalenz" + description: + type: youtube + video_id: "rcAZ8oIvcUY" + duration: 894 + - id: "OG8haxPgIgc" + title: "Horn Formeln und der Markierungsalgorithmus" + description: + type: youtube + video_id: "OG8haxPgIgc" + duration: 585 + - id: section2 + title: "Prädikatenlogik" + description: + lectures: + - id: "Y4tfUA62mKk" + title: "Quantoren" + description: + type: youtube + video_id: "Y4tfUA62mKk" + duration: 756 + - id: "oTBKRKC2dDE" + title: "Funktions- und Prädikatensymbole" + description: + type: youtube + video_id: "oTBKRKC2dDE" + duration: 1044 + - id: "--tfLmTGS4U" + title: "Ein Beispielrätsel" + description: + type: youtube + video_id: "--tfLmTGS4U" + duration: 770 + - id: "LhjaxFBZYog" + title: "Freie und gebundene Variablen" + description: + type: youtube + video_id: "LhjaxFBZYog" + duration: 618 + - id: "2ITUIJhiRMQ" + title: "Substitutionen" + description: + type: youtube + video_id: "2ITUIJhiRMQ" + duration: 550 + - id: "A2ch63AYO5Y" + title: "Unifikation" + description: + type: youtube + video_id: "A2ch63AYO5Y" + duration: 649 + - id: "6obfErOT0WU" + title: "Normalformen" + description: + type: youtube + video_id: "6obfErOT0WU" + duration: 290 + - id: "GpZ9SbRTEZA" + title: "Die pränexe Normalform" + description: + type: youtube + video_id: "GpZ9SbRTEZA" + duration: 364 + - id: "SGrIrYkNSaU" + title: "Skolemnormalform" + description: + type: youtube + video_id: "SGrIrYkNSaU" + duration: 519 + - id: section3 + title: "Kalküle" + description: + lectures: + - id: "Y0_51xizzCo" + title: "Der Hilbertkalkül #1" + description: + type: youtube + video_id: "Y0_51xizzCo" + duration: 1076 + - id: "LvSEglTwlUs" + title: "Der Hilbertkalkül #2" + description: + type: youtube + video_id: "LvSEglTwlUs" + duration: 682 + - id: "fVNoVGACo2o" + title: "Der Hilbertkalkül #3" + description: + type: youtube + video_id: "fVNoVGACo2o" + duration: 1202 + - id: "bUwRfrfrsgc" + title: "Resolutionskalkül #1" + description: + type: youtube + video_id: "bUwRfrfrsgc" + duration: 332 + - id: "RbQhqSNPmqw" + title: "Reduktionssysteme" + description: + type: youtube + video_id: "RbQhqSNPmqw" + duration: 896 + - id: section4 + title: "Weitere Logiken" + description: + lectures: + - id: "4tbuQrrvUvg" + title: "Modallogik" + description: + type: youtube + video_id: "4tbuQrrvUvg" + duration: 508 + - id: "U-nBLdYg0iA" + title: "Lineare Temporal-Logik (LTL)" + description: + type: youtube + video_id: "U-nBLdYg0iA" + duration: 523 + - id: "TwdeZDvArGg" + title: "Fuzzy Logic" + description: + type: youtube + video_id: "TwdeZDvArGg" + duration: 384 + - id: section5 + title: "Extras" + description: + lectures: + - id: "hOoa0KiyspQ" + title: "Der Sequenzenkalkül der Aussagenlogik" + description: + type: youtube + video_id: "hOoa0KiyspQ" + duration: 1086 + - id: "amdZMtiFNU8" + title: "Der Sequenzenkalkül der Prädikatenlogik" + description: + type: youtube + video_id: "amdZMtiFNU8" + duration: 690 diff --git a/academy_data/courses/lustige_web_ui_effekte.yml b/academy_data/courses/lustige_web_ui_effekte.yml new file mode 100644 index 00000000..b2e59487 --- /dev/null +++ b/academy_data/courses/lustige_web_ui_effekte.yml @@ -0,0 +1,163 @@ +title: "Lustige Web UI Effekte" +description: | + In dieser Reihe seht ihr eine ganze Reihe von Videos zu verschiedenen UI Effekten und Animationen, die nicht immer großen Sinn in Projekten machen, aber viel Spaß erzeugen beim Bauen und damit Rumspielen. Im Laufe der einzelnen Videos, die jedes für sich geschlossene Parts umfassen, könnt ihr bereits erlangtes CSS und JavaScript Basis Wissen in kreativen und sicher auch neuen Möglichkeiten unter Beweis stellen. + Dabei muss jedoch festgehalten werden, dass keines der Videos für absolute Anfänger geeignet ist und hier definitiv Wissen in CSS, HTML & JavaScript vorhanden sein muss. +category: +language: de +image: https://static.bootstrap.academy/thumbnails/algorithmen.jpg +authors: + - name: "Unleashed Design" + url: "https://www.youtube.com/@UnleashedDesign" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1667584883 +sections: + - id: section + title: "Lustige Web UI Effekte" + description: + lectures: + - id: "xgRB7cYCr7g" + title: "Der dümmste Weg einer Button Validation mit CSS & JavaScript" + description: + type: youtube + video_id: "xgRB7cYCr7g" + duration: 784 + - id: "9VzQO_kHN2A" + title: "Epic Store Content Slider selbst bauen!" + description: + type: youtube + video_id: "9VzQO_kHN2A" + duration: 2329 + - id: "u1JIbYYZxFw" + title: "Frustfreie Eingabe von OTPs in euren Anwendungen mit JavaScript & CSS" + description: + type: youtube + video_id: "u1JIbYYZxFw" + duration: 1311 + - id: "j7qE1nUpdTU" + title: "Magnetische Paralax UI der neue Frontend Trend 2022!" + description: + type: youtube + video_id: "j7qE1nUpdTU" + duration: 1094 + - id: "aQ26xzxJ_bY" + title: "Einfacher 🎉 Party Button für eure Website in Minuten!" + description: + type: youtube + video_id: "aQ26xzxJ_bY" + duration: 592 + - id: "7RF7TL39Clc" + title: "CSS3 Neon-Gradient-Animation für einen extra Design Boost!" + description: + type: youtube + video_id: "7RF7TL39Clc" + duration: 829 + - id: "_2p8DgNZgBw" + title: "Awesome Flex Image Slider für dein nächstes Web Design Projekt 2022 mit CSS & JavaScript!" + description: + type: youtube + video_id: "_2p8DgNZgBw" + duration: 1661 + - id: "8zJhe-uMnGg" + title: "🦥 Lazy Loading ⌛ von Bildern mit JavaScript (mit Animation)!" + description: + type: youtube + video_id: "8zJhe-uMnGg" + duration: 932 + - id: "7iTOXlrEHks" + title: "Eine einfache Front-End Suche mit Fuse.js bauen!" + description: + type: youtube + video_id: "7iTOXlrEHks" + duration: 897 + - id: "BSgYBJan_SE" + title: "10 min Arbeit die ein Cooles von einem Langweiligen Menü unterschieden!" + description: + type: youtube + video_id: "BSgYBJan_SE" + duration: 1200 + - id: "KY_phw0uk6E" + title: "Coole & einfache 3D Sidebar für deine Website!" + description: + type: youtube + video_id: "KY_phw0uk6E" + duration: 1407 + - id: "gW177MPaPfQ" + title: "Einfacher 👍 Button Animation mit CSS3 und JavaScript" + description: + type: youtube + video_id: "gW177MPaPfQ" + duration: 1110 + - id: "-G3_pKCH_wg" + title: "Coole Wiggle Button Animation mit CSS und JavaScript👍" + description: + type: youtube + video_id: "-G3_pKCH_wg" + duration: 540 + - id: "WOmagqxZR8c" + title: "Cooles & einfaches 3D Menü für deine Website!" + description: + type: youtube + video_id: "WOmagqxZR8c" + duration: 1649 + - id: "54TmQaHECwU" + title: "Der wohl beste Text Morph Effekt 😍 mit CSS & SVG Filtern?" + description: + type: youtube + video_id: "54TmQaHECwU" + duration: 1134 + - id: "3BOVlMQoQ24" + title: "Twitch 3D :hover Effekt mit CSS3" + description: + type: youtube + video_id: "3BOVlMQoQ24" + duration: 757 + - id: "hVkCyWT6ZMs" + title: "Nicht noch ein weiter CSS Loading-Spinner!" + description: + type: youtube + video_id: "hVkCyWT6ZMs" + duration: 970 + - id: "0jT49Ee89og" + title: "CSS Motion Path! Das wohl coolste CSS Feature!" + description: + type: youtube + video_id: "0jT49Ee89og" + duration: 765 + - id: "UVsyZmlZ0Iw" + title: "Einfacher Textmarker 🖍 Effekt mit CSS3 & JavaScript!" + description: + type: youtube + video_id: "UVsyZmlZ0Iw" + duration: 914 + - id: "v9MluXjcHPI" + title: "Content Slider mit Bullets, Pen Support & 100% Responsive" + description: + type: youtube + video_id: "v9MluXjcHPI" + duration: 2156 + - id: "k4A1U4dcEFg" + title: "Einfacher Menü Highlight Slider mit JavaScript & CSS!" + description: + type: youtube + video_id: "k4A1U4dcEFg" + duration: 607 + - id: "_CfIxmk3hho" + title: "BESTER BUTTON EFFEKT Ever?? CSS Only Gummy Animation oO" + description: + type: youtube + video_id: "_CfIxmk3hho" + duration: 1298 + - id: "cwkf5wN2WPA" + title: "Animierte Skillbar für deinen Lebenslauf mit CSS & JavaScript" + description: + type: youtube + video_id: "cwkf5wN2WPA" + duration: 1374 + - id: "ziIFE_fmj2g" + title: "🔪 Zerschneide Text mit CSS3?? Cooler Text Effekt!" + description: + type: youtube + video_id: "ziIFE_fmj2g" + duration: 625 diff --git a/academy_data/courses/machine_learning.yml b/academy_data/courses/machine_learning.yml new file mode 100644 index 00000000..0a46f0ad --- /dev/null +++ b/academy_data/courses/machine_learning.yml @@ -0,0 +1,736 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7qoIUw0MBYQ9qJffZAVdRWC +title: "Machine Learning und Künstliche Intelligenz" +description: "KI, klar, tolles Thema, aber was verbirgt sich eigentlich dahinter? Es stellt sich raus - zumindest in der Theorie reine Mathematik!" +category: +language: de +image: https://static.bootstrap.academy/thumbnails/machinelearning.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665507965 +sections: + - id: section + title: "Grundlagen" + description: + lectures: + - id: "GdsOLrqj42I" + title: "Einleitung und Infos zur Serie" + description: + type: youtube + video_id: "GdsOLrqj42I" + duration: 377 + - id: "BrIxs1TLHvw" + title: "Die Daten" + description: + type: youtube + video_id: "BrIxs1TLHvw" + duration: 506 + - id: "pq8Ea5GqOv4" + title: "Konzept vs Klassifikation vs Regression" + description: + type: youtube + video_id: "pq8Ea5GqOv4" + duration: 353 + - id: "MsD6hMnOSn0" + title: "Deduktion und Induktion" + description: + type: youtube + video_id: "MsD6hMnOSn0" + duration: 344 + - id: "fXHL2AkKAok" + title: "Überwachtes und Unüberwachtes Lernen" + description: + type: youtube + video_id: "fXHL2AkKAok" + duration: 415 + - id: "u4eDEIuVMtM" + title: "Fehlerminimierung" + description: + type: youtube + video_id: "u4eDEIuVMtM" + duration: 250 + - id: "g4oBLJcsq3Q" + title: "Gradientenabstieg" + description: + type: youtube + video_id: "g4oBLJcsq3Q" + duration: 486 + - id: "p8ypJFsWQNk" + title: "Overfitting" + description: + type: youtube + video_id: "p8ypJFsWQNk" + duration: 310 + - id: "pyJa2kpWYtM" + title: "Abstandsmaße und Levenshtein Distanz" + description: + type: youtube + video_id: "pyJa2kpWYtM" + duration: 732 + - id: section2 + title: "Instanzbasiertes Lernen" + description: + lectures: + - id: "FghB26KmQG0" + title: "k-Nearest Neighbours" + description: + type: youtube + video_id: "FghB26KmQG0" + duration: 450 + - id: "gMq4goRUg4k" + title: "k-Nearest Neighbours in Zahlen" + description: + type: youtube + video_id: "gMq4goRUg4k" + duration: 548 + - id: "1HZU5pHGOCY" + title: "gewichteter k-Nearest Neighbours" + description: + type: youtube + video_id: "1HZU5pHGOCY" + duration: 550 + - id: "i0j6f7gl4Rs" + title: 'Das Konzept "Case Based Reasoning"' + description: + type: youtube + video_id: "i0j6f7gl4Rs" + duration: 513 + - id: section3 + title: "Concept Learning" + description: + lectures: + - id: "C1cI7wUUg6M" + title: "Concept Learning aka Induktives Lernen #1" + description: + type: youtube + video_id: "C1cI7wUUg6M" + duration: 853 + - id: "kB6kI-aj3KA" + title: "Concept Learning aka Induktives Lernen #2" + description: + type: youtube + video_id: "kB6kI-aj3KA" + duration: 379 + - id: section4 + title: "Unüberwachtes Lernen" + description: + lectures: + - id: "TZqRpYiUS3k" + title: "k-Means Clustering" + description: + type: youtube + video_id: "TZqRpYiUS3k" + duration: 1124 + - id: "vLAgmZfdm1c" + title: "Fuzzy k-Means Clustering" + description: + type: youtube + video_id: "vLAgmZfdm1c" + duration: 621 + - id: "TiBFigwj5F4" + title: "Dendrogramme" + description: + type: youtube + video_id: "TiBFigwj5F4" + duration: 335 + - id: "ovI-KrOhvgc" + title: "Cobweb #1" + description: + type: youtube + video_id: "ovI-KrOhvgc" + duration: 790 + - id: "K6B3uKuyL6g" + title: "Cobweb #2" + description: + type: youtube + video_id: "K6B3uKuyL6g" + duration: 811 + - id: section5 + title: "Bayes" + description: + lectures: + - id: "xaBrFCPk-P8" + title: "Intro" + description: + type: youtube + video_id: "xaBrFCPk-P8" + duration: 519 + - id: "rY3NV1z6Kto" + title: "Das Bayes-Theorem" + description: + type: youtube + video_id: "rY3NV1z6Kto" + duration: 553 + - id: "kWv8HZXe9j4" + title: "MAP - Die Maximum A Posteriori Hypothese" + description: + type: youtube + video_id: "kWv8HZXe9j4" + duration: 378 + - id: "kzfVsRqAk_8" + title: "Konzeptlernen" + description: + type: youtube + video_id: "kzfVsRqAk_8" + duration: 497 + - id: "RQAjm5bvBMI" + title: "Funktionslernen" + description: + type: youtube + video_id: "RQAjm5bvBMI" + duration: 459 + - id: "HeWOxJFuZ6o" + title: "Optimaler Bayes" + description: + type: youtube + video_id: "HeWOxJFuZ6o" + duration: 429 + - id: "MXlnK5ZL8Ok" + title: "Der Naive Bayes-Klassifikator" + description: + type: youtube + video_id: "MXlnK5ZL8Ok" + duration: 479 + - id: "wuuGDuGuZ-I" + title: "Schätzen von Werten" + description: + type: youtube + video_id: "wuuGDuGuZ-I" + duration: 197 + - id: "7qKyMcxRHEA" + title: "Bayes'sche Netze" + description: + type: youtube + video_id: "7qKyMcxRHEA" + duration: 465 + - id: "Vg432zJ0UT4" + title: "Bedingte Unabhängigkeit #1" + description: + type: youtube + video_id: "Vg432zJ0UT4" + duration: 398 + - id: "t2yupeDM4f8" + title: "Bedingte Unabhängigkeit #2" + description: + type: youtube + video_id: "t2yupeDM4f8" + duration: 415 + - id: "5lqmo44NFDA" + title: "D-Separation" + description: + type: youtube + video_id: "5lqmo44NFDA" + duration: 373 + - id: "GXJVKuNM6LE" + title: "Objektorientierte Probabilistisch Relationale Modelle" + description: + type: youtube + video_id: "GXJVKuNM6LE" + duration: 362 + - id: "ZosvB9AXAys" + title: "Objektorientierte Probabilistisch Relationale Modelle - Parameter Schätzung" + description: + type: youtube + video_id: "ZosvB9AXAys" + duration: 461 + - id: "mfh1laaJU3o" + title: "Objektorientierte Probabilistisch Relationale Modelle - Strukturbestimmung" + description: + type: youtube + video_id: "mfh1laaJU3o" + duration: 520 + - id: "n3Z77g6lE5M" + title: "Der EM-Algorithmus" + description: + type: youtube + video_id: "n3Z77g6lE5M" + duration: 811 + - id: section6 + title: "Entscheidungsbäume" + description: + lectures: + - id: "-YW5s_an4z8" + title: "Decision Trees" + description: + type: youtube + video_id: "-YW5s_an4z8" + duration: 353 + - id: "SYyyuHG9qBs" + title: "Der ID3-Algorithmus" + description: + type: youtube + video_id: "SYyyuHG9qBs" + duration: 589 + - id: "lg1pb0YaAjI" + title: "Entropie und Informationsgewinn" + description: + type: youtube + video_id: "lg1pb0YaAjI" + duration: 400 + - id: "RXrgUPc0uDc" + title: "Reduced Error Pruning" + description: + type: youtube + video_id: "RXrgUPc0uDc" + duration: 312 + - id: "uQw93RacR1A" + title: "Attribute mit vielen Werten und kontinuierliche Werte" + description: + type: youtube + video_id: "uQw93RacR1A" + duration: 323 + - id: "y4PS6Y-Jn90" + title: "Random Forests" + description: + type: youtube + video_id: "y4PS6Y-Jn90" + duration: 186 + - id: section7 + title: "Markov Modelle" + description: + lectures: + - id: "NAgofzXNqWc" + title: "Diskrete Markov Modelle" + description: + type: youtube + video_id: "NAgofzXNqWc" + duration: 408 + - id: "Nqk_gPn2KS8" + title: "Hidden Markov Modelle" + description: + type: youtube + video_id: "Nqk_gPn2KS8" + duration: 327 + - id: "s3p-zNlpsA4" + title: "HMMs #2 - Das Evaluationsproblem - Forward Backward Algorithmus" + description: + type: youtube + video_id: "s3p-zNlpsA4" + duration: 553 + - id: "lDh8i7AV0bE" + title: "HMMs #3 - Das Dekodierungsproblem und der Viterbi Algorithmus" + description: + type: youtube + video_id: "lDh8i7AV0bE" + duration: 307 + - id: "L1ZKbncUHuw" + title: "HMMs #4 - Der Baum Welch Algorithmus" + description: + type: youtube + video_id: "L1ZKbncUHuw" + duration: 794 + - id: "BJIQ7rUk1WM" + title: "HMMs #5 - Der Baum Welch Algorithmus #2" + description: + type: youtube + video_id: "BJIQ7rUk1WM" + duration: 527 + - id: "CLYcaO11h2E" + title: "HMMs #6 - Typen" + description: + type: youtube + video_id: "CLYcaO11h2E" + duration: 310 + - id: section8 + title: "Deduktives Lernen" + description: + lectures: + - id: "YAGWJ0fycBA" + title: "Einleitung" + description: + type: youtube + video_id: "YAGWJ0fycBA" + duration: 256 + - id: "Fbd-Lwc9P8Y" + title: "Explanation Based Learning" + description: + type: youtube + video_id: "Fbd-Lwc9P8Y" + duration: 427 + - id: "M-Z58RmIq_g" + title: "Knowledge Based Neural Networks" + description: + type: youtube + video_id: "M-Z58RmIq_g" + duration: 423 + - id: section9 + title: "Markov Logik Netze" + description: + lectures: + - id: "kP3H_UksjJ4" + title: "Probabilstische Graphische Modelle" + description: + type: youtube + video_id: "kP3H_UksjJ4" + duration: 699 + - id: "UQGfYoAma6U" + title: "Markov Logik Netze #2" + description: + type: youtube + video_id: "UQGfYoAma6U" + duration: 448 + - id: "mRGBU5UmBfI" + title: "Der MAP Algorithmus" + description: + type: youtube + video_id: "mRGBU5UmBfI" + duration: 300 + - id: "mLrzdouGSlk" + title: "Generatives Lernen" + description: + type: youtube + video_id: "mLrzdouGSlk" + duration: 366 + - id: section10 + title: "Evolutionäre Algorithmen" + description: + lectures: + - id: "sxT71gpsA2k" + title: "Der Gundalgorithmus" + description: + type: youtube + video_id: "sxT71gpsA2k" + duration: 493 + - id: "Bp4Xh-alVT4" + title: "Mutationen" + description: + type: youtube + video_id: "Bp4Xh-alVT4" + duration: 529 + - id: "as3lijLxVAo" + title: "Rekombinationen" + description: + type: youtube + video_id: "as3lijLxVAo" + duration: 523 + - id: "uf--mf-7njg" + title: "Selektion" + description: + type: youtube + video_id: "uf--mf-7njg" + duration: 434 + - id: "k58CWZjorUE" + title: "Fitness Based Selection" + description: + type: youtube + video_id: "k58CWZjorUE" + duration: 301 + - id: "9Mk5Vq3zhxs" + title: "Ranking Based und Tournament Selection" + description: + type: youtube + video_id: "9Mk5Vq3zhxs" + duration: 371 + - id: section11 + title: "Reinforcement Learning" + description: + lectures: + - id: "qtZ9-jJsuCI" + title: "Lernen durch Bestrafung" + description: + type: youtube + video_id: "qtZ9-jJsuCI" + duration: 470 + - id: "XGFQMFZF-wo" + title: "Die State Value Function" + description: + type: youtube + video_id: "XGFQMFZF-wo" + duration: 400 + - id: "Z4GCytqt4uM" + title: "Q-Learning" + description: + type: youtube + video_id: "Z4GCytqt4uM" + duration: 387 + - id: "BLkNXkGhzbA" + title: "Living Reward und Exploration" + description: + type: youtube + video_id: "BLkNXkGhzbA" + duration: 517 + - id: "emqHD3T7Hv4" + title: "TD-Learning und SARSA" + description: + type: youtube + video_id: "emqHD3T7Hv4" + duration: 479 + - id: "jOW2VrXbcdo" + title: "Options und Semi-MDP" + description: + type: youtube + video_id: "jOW2VrXbcdo" + duration: 391 + - id: "A3Aial_3x88" + title: "Hierarchical Abstract Machines" + description: + type: youtube + video_id: "A3Aial_3x88" + duration: 385 + - id: section12 + title: "Support Vector Machines" + description: + lectures: + - id: "WKsWAqAnDBo" + title: "Support Vector Machines" + description: + type: youtube + video_id: "WKsWAqAnDBo" + duration: 373 + - id: "NnEcnULecrU" + title: "Die Lagrange Methode" + description: + type: youtube + video_id: "NnEcnULecrU" + duration: 724 + - id: "wlgvAar4pQE" + title: "Duales Optimierungsproblem" + description: + type: youtube + video_id: "wlgvAar4pQE" + duration: 372 + - id: "PXVxRXTS3_I" + title: "Soft Margin" + description: + type: youtube + video_id: "PXVxRXTS3_I" + duration: 269 + - id: "5zUHh-wNjNs" + title: "Nicht lineare SVM und der Kernel Trick" + description: + type: youtube + video_id: "5zUHh-wNjNs" + duration: 770 + - id: section13 + title: "Semi-Supervised Learning" + description: + lectures: + - id: "MRAvP7y-pPE" + title: "Semi Supervised Learning" + description: + type: youtube + video_id: "MRAvP7y-pPE" + duration: 407 + - id: "uUnAvesAVc4" + title: "Self Learning" + description: + type: youtube + video_id: "uUnAvesAVc4" + duration: 520 + - id: "GlKEwZl9s2k" + title: "Co-Training" + description: + type: youtube + video_id: "GlKEwZl9s2k" + duration: 467 + - id: "fQy2AN_nGNk" + title: "Unlabeling und SVMlight" + description: + type: youtube + video_id: "fQy2AN_nGNk" + duration: 657 + - id: "EGs-6ymY7Fs" + title: "Aktives Lernen" + description: + type: youtube + video_id: "EGs-6ymY7Fs" + duration: 491 + - id: section14 + title: "Neuronale Netze" + description: + lectures: + - id: "8gYmuU_PNto" + title: "Perzeptronen" + description: + type: youtube + video_id: "8gYmuU_PNto" + duration: 397 + - id: "FWXaG99LhQo" + title: "Perzeptron Training" + description: + type: youtube + video_id: "FWXaG99LhQo" + duration: 653 + - id: "DgacrjH-32c" + title: "Perzeptron Training Varianten" + description: + type: youtube + video_id: "DgacrjH-32c" + duration: 306 + - id: "soFCzvytJyE" + title: "Die Phi / Aktivierungs - Funktion" + description: + type: youtube + video_id: "soFCzvytJyE" + duration: 355 + - id: "oT1qdYMzgzY" + title: "Mean Squared Error" + description: + type: youtube + video_id: "oT1qdYMzgzY" + duration: 594 + - id: "3H7Fzj_63o4" + title: "Multiclass Problem der Perzeptronen" + description: + type: youtube + video_id: "3H7Fzj_63o4" + duration: 258 + - id: "2MEs2EHt7ow" + title: "Feed-Forward Neuronale Netze" + description: + type: youtube + video_id: "2MEs2EHt7ow" + duration: 416 + - id: "emUOJaHXgdA" + title: "Backpropagation" + description: + type: youtube + video_id: "emUOJaHXgdA" + duration: 529 + - id: "IXUDyrOisEE" + title: "Backpropagation: Rechnung der Output Neuronen" + description: + type: youtube + video_id: "IXUDyrOisEE" + duration: 641 + - id: "R9XaPACZWyM" + title: "Rechnung der anderen Neuronen" + description: + type: youtube + video_id: "R9XaPACZWyM" + duration: 624 + - id: "qx8l-LmdgEk" + title: "Die Softmax-Aktivierung" + description: + type: youtube + video_id: "qx8l-LmdgEk" + duration: 425 + - id: "oUEnzS5P5JM" + title: "Cross Entropy Error" + description: + type: youtube + video_id: "oUEnzS5P5JM" + duration: 347 + - id: "AiUqfCJbgEk" + title: "Überspringen von Beispielen" + description: + type: youtube + video_id: "AiUqfCJbgEk" + duration: 191 + - id: "W3wkhcoe1dc" + title: "dynamische Lernraten" + description: + type: youtube + video_id: "W3wkhcoe1dc" + duration: 355 + - id: "Ixx7S3iZws4" + title: "Initiale Gewichte und Offsets" + description: + type: youtube + video_id: "Ixx7S3iZws4" + duration: 395 + - id: "Uos7B_cPz68" + title: "Quickprop" + description: + type: youtube + video_id: "Uos7B_cPz68" + duration: 231 + - id: "pWZQ8r07vn8" + title: "Weight Elimination und Weight Decay" + description: + type: youtube + video_id: "pWZQ8r07vn8" + duration: 302 + - id: "mBhzVbKxX0U" + title: "Optimal Brain Damage" + description: + type: youtube + video_id: "mBhzVbKxX0U" + duration: 244 + - id: "TaDWE0UtfbU" + title: "Cascade Correlation" + description: + type: youtube + video_id: "TaDWE0UtfbU" + duration: 604 + - id: "hHo8gIWz6I8" + title: "Deep Neural Networks" + description: + type: youtube + video_id: "hHo8gIWz6I8" + duration: 211 + - id: "dRm5H3BQCpc" + title: "Hopfield Netze" + description: + type: youtube + video_id: "dRm5H3BQCpc" + duration: 706 + - id: "N4anBqCIVA4" + title: "(Restricted) Boltzmann Machines" + description: + type: youtube + video_id: "N4anBqCIVA4" + duration: 378 + - id: "2gxrt1bO_Ug" + title: "Cascaded Restricted Boltzmann Machines" + description: + type: youtube + video_id: "2gxrt1bO_Ug" + duration: 441 + - id: "1xVgIkAR398" + title: "Autoencoder" + description: + type: youtube + video_id: "1xVgIkAR398" + duration: 464 + - id: "aDq1O2FIfbk" + title: "Denoising Autoencoder" + description: + type: youtube + video_id: "aDq1O2FIfbk" + duration: 334 + - id: "a5Sl5KnT4Bc" + title: "Bottleneck Features" + description: + type: youtube + video_id: "a5Sl5KnT4Bc" + duration: 320 + - id: "bd4cpFGhGaM" + title: "Reinforcement Learning - Lernen für Spiele" + description: + type: youtube + video_id: "bd4cpFGhGaM" + duration: 608 + - id: "c17PPaGVG3Y" + title: "Reinforcement Learning - Monte Carlo Search Trees" + description: + type: youtube + video_id: "c17PPaGVG3Y" + duration: 517 + - id: "LqG_MosgnPI" + title: "Convolutional Neural Networks für Bilderkennung" + description: + type: youtube + video_id: "LqG_MosgnPI" + duration: 780 + - id: "1mNNX9_z2ac" + title: "Rekurrente Neuronale Netze" + description: + type: youtube + video_id: "1mNNX9_z2ac" + duration: 572 + - id: "ydBzqYiV4rw" + title: "Linear Short Term Memory" + description: + type: youtube + video_id: "ydBzqYiV4rw" + duration: 606 + - id: "mVYTEKed0LM" + title: "GAN: Generative Adversarial Neuronale Netze: Dall-E und Co" + description: + type: youtube + video_id: "mVYTEKed0LM" + duration: 323 diff --git a/academy_data/courses/medienkompetenz.yml b/academy_data/courses/medienkompetenz.yml new file mode 100644 index 00000000..efac9092 --- /dev/null +++ b/academy_data/courses/medienkompetenz.yml @@ -0,0 +1,174 @@ +# https://www.youtube.com/playlist?list=PL6RbeNL8jYDees12cwPupr49wMArrVQEX +title: "Medienkompetenz" +description: Wir nutzen alle das Internet, ob wir wollen oder nicht, doch dadurch machen wir uns angreifbar. In diesen Videos lernt ihr einige wichtige Themen kennen, mit denen man sich auseinandersetzen muss, wenn man dieses Neuland nutzen möchte +category: +language: de +image: https://static.bootstrap.academy/thumbnails/medienkompetenz.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1666444594 +sections: + - id: section + title: "Medienkompetenz" + description: + lectures: + - id: "zWHWXOhcyeE" + title: "Wirklich noch CHROME? | Vergleich: BROWSER können VIEL MEHR" + description: + type: youtube + video_id: "zWHWXOhcyeE" + duration: 2309 + - id: "fw67-ichp6w" + title: "10 Arten wie Gamer GEHACKT werden" + description: + type: youtube + video_id: "fw67-ichp6w" + duration: 564 + - id: "OmLOYKOpJuY" + title: "Uber GEHACKT: 17 Jähriger VERHAFTET" + description: + type: youtube + video_id: "OmLOYKOpJuY" + duration: 981 + - id: "xu2kxkES-fg" + title: "Wird KÜNSTLICHE INTELLIGENZ uns AUSLÖSCHEN?" + description: + type: youtube + video_id: "xu2kxkES-fg" + duration: 1002 + - id: "r29cLPUoU2Y" + title: "Morddrohungen im Netz: Anonymous erklärt Querdenkern den Krieg ft. @Kanzlei WBS" + description: + type: youtube + video_id: "r29cLPUoU2Y" + duration: 2417 + - id: "D7oNEbdAQx8" + title: "Die Ursache für Hass im Netz" + description: + type: youtube + video_id: "D7oNEbdAQx8" + duration: 1627 + - id: "anmUlcD36bQ" + title: "Kaputte Software-Industrie | OPEN-SOURCE ist so KEINE Lösung" + description: + type: youtube + video_id: "anmUlcD36bQ" + duration: 1165 + - id: "YwbE2iLmAT0" + title: "Ein Vergleich von PASSWORTMANAGERN: Das essentiellste Tool für IT Sicherheit" + description: + type: youtube + video_id: "YwbE2iLmAT0" + duration: 1210 + - id: "BQFw8M8qiQk" + title: "Das kannst DU gegen ZENSUR IM NETZ tun" + description: + type: youtube + video_id: "BQFw8M8qiQk" + duration: 1221 + - id: "wxkoOYU1oYE" + title: "Personenbezogene WERBUNG ZERSTÖRT unsere Gesellschaft" + description: + type: youtube + video_id: "wxkoOYU1oYE" + duration: 1017 + - id: "WxbDL54jrjI" + title: "Das METAVERSE: Riesige Chance UND fürchterliche Gefahr" + description: + type: youtube + video_id: "WxbDL54jrjI" + duration: 1498 + - id: "6IitUwrqtbo" + title: "Selbstexperiment: Alternatives Smartphone OHNE Google oder iOS" + description: + type: youtube + video_id: "6IitUwrqtbo" + duration: 1203 + - id: "8R9s9EpdMt0" + title: "Was tun, wenn man RANSOMWARE hat?" + description: + type: youtube + video_id: "8R9s9EpdMt0" + duration: 1054 + - id: "OCC_65l1qIo" + title: "Welcher E-Mail Anbieter ist SICHER und ANONYM?" + description: + type: youtube + video_id: "OCC_65l1qIo" + duration: 1627 + - id: "yf9o0XL7eFk" + title: "PEGASUS | Wie ein Staatstrojaner MORD und FOLTER ermöglichte" + description: + type: youtube + video_id: "yf9o0XL7eFk" + duration: 952 + - id: "CgGWs0zNOQY" + title: "Vergesst Google | Vergleich: SUCHMASCHINEN können VIEL MEHR" + description: + type: youtube + video_id: "CgGWs0zNOQY" + duration: 1149 + - id: "xnK2kJWcjBY" + title: "Wie Youtuber gehackt werden" + description: + type: youtube + video_id: "xnK2kJWcjBY" + duration: 929 + - id: "YKxtY2GE3hE" + title: "Wie DU den STAATSTROJANER NICHT bekommst" + description: + type: youtube + video_id: "YKxtY2GE3hE" + duration: 862 + - id: "l01LR9CTA6s" + title: "Selbstexperiment geht schief | EIN TAG STAATSTROJANER" + description: + type: youtube + video_id: "l01LR9CTA6s" + duration: 856 + - id: "kHhWxDxLooE" + title: "In die Trends und Charts mit gekauften Klicks?" + description: + type: youtube + video_id: "kHhWxDxLooE" + duration: 987 + - id: "YRvbKnb8ALc" + title: "KI vs. Computervirus - Wie kann das gehen?" + description: + type: youtube + video_id: "YRvbKnb8ALc" + duration: 692 + - id: "NGdF0wEIeQM" + title: "Wie Firmen nun Websites BLOCKIEREN | CUII und Netzneutralität erklärt" + description: + type: youtube + video_id: "NGdF0wEIeQM" + duration: 778 + - id: "rO37rz1dhkQ" + title: "Die Daten von WhatsApp - Was WIRKLICH möglich ist (Metadaten)" + description: + type: youtube + video_id: "rO37rz1dhkQ" + duration: 1117 + - id: "yWj5G-rrtDg" + title: "Ist dein Messenger noch SICHER? [Messenger-Vergleich]" + description: + type: youtube + video_id: "yWj5G-rrtDg" + duration: 795 + - id: "3JK_0_gZGMA" + title: "Die Probleme von TELEGRAM" + description: + type: youtube + video_id: "3JK_0_gZGMA" + duration: 787 + - id: "cD-rb8bo71k" + title: "GOOGLE One VPN - vielleicht doch nicht so schlecht?" + description: + type: youtube + video_id: "cD-rb8bo71k" + duration: 613 diff --git a/academy_data/courses/mengenlehre.yml b/academy_data/courses/mengenlehre.yml new file mode 100644 index 00000000..65c4b03b --- /dev/null +++ b/academy_data/courses/mengenlehre.yml @@ -0,0 +1,228 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7q_xBcMAlQ2K18HjMpAe0Nm +title: "Mengenlehre" +description: "Mengenlehre, eine fundamentale Thematik für die Mathematik, in der es um Mengen, Ringe, Körper und deren Rechenregeln geht." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/mengenlehre.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1678802776 +sections: + - id: section + title: "Mengenlehre" + description: + lectures: + - id: "rsYgZTHjfTQ" + title: "Mathematik: Mengenlehre #1 - Was sind Mengen?" + description: + type: youtube + video_id: "rsYgZTHjfTQ" + duration: 401 + - id: "RNVEOu6yXmQ" + title: "Mathe in Code: Mengenlehre #1.5 - Mengen in Python" + description: + type: youtube + video_id: "RNVEOu6yXmQ" + duration: 320 + - id: "NSQxleOe_Dg" + title: "Mathematik: Mengenlehre #2 - Teilmengen" + description: + type: youtube + video_id: "NSQxleOe_Dg" + duration: 310 + - id: "H9tgO49YGQI" + title: "Mathematik: Mengenlehre #3 - Der Schnitt" + description: + type: youtube + video_id: "H9tgO49YGQI" + duration: 422 + - id: "g3-aoISf2sI" + title: "Mathematik: Mengenlehre #4 - Vereinigung" + description: + type: youtube + video_id: "g3-aoISf2sI" + duration: 380 + - id: "KstSdHRc96w" + title: "Mathematik: Mengenlehre #5 - Die Differenz" + description: + type: youtube + video_id: "KstSdHRc96w" + duration: 461 + - id: "mlfmaVqKdRk" + title: "Mathematik: Mengenlehre #6 - Die Symmetrische Differenz" + description: + type: youtube + video_id: "mlfmaVqKdRk" + duration: 635 + - id: "SwOxlWrDUiY" + title: "Mathe in Code: Mengenlehre #6.5 - Mengenoperationen in Python" + description: + type: youtube + video_id: "SwOxlWrDUiY" + duration: 751 + - id: "5vcYYQOVW1s" + title: "Mathematik: Mengenlehre #7 - Potenzmengen" + description: + type: youtube + video_id: "5vcYYQOVW1s" + duration: 517 + - id: "VJBZi-HD5_c" + title: "Mathematik: Mengenlehre #8 - Das Kartesische Produkt" + description: + type: youtube + video_id: "VJBZi-HD5_c" + duration: 683 + - id: "h3NPutvl49U" + title: "Mathematik: Abbildungen und Relationen #1 - Funktionen" + description: + type: youtube + video_id: "h3NPutvl49U" + duration: 475 + - id: "rfZvGoTh4Bk" + title: "Mathematik: Abbildungen und Relationen #2 - Das Bild" + description: + type: youtube + video_id: "rfZvGoTh4Bk" + duration: 286 + - id: "vkLn1jSIkJM" + title: "Mathematik: Abbildungen und Relationen #3 - Das Urbild" + description: + type: youtube + video_id: "vkLn1jSIkJM" + duration: 367 + - id: "T_75W5CkY14" + title: "Mathematik: Abbildungen und Relationen #4 - Injektivität, Surjektivität, Bijektivität" + description: + type: youtube + video_id: "T_75W5CkY14" + duration: 826 + - id: "b6fm4uUvQyU" + title: "Mathematik: Abbildungen und Relationen #5 - Komposition" + description: + type: youtube + video_id: "b6fm4uUvQyU" + duration: 497 + - id: "yQlF7_EeMsM" + title: "Mathematik: Abbildungen und Relationen #6 - Die Identität" + description: + type: youtube + video_id: "yQlF7_EeMsM" + duration: 97 + - id: "g-86WCp19RE" + title: "Mathematik: Abbildungen und Relationen #7 - Die Umkehrabbildung" + description: + type: youtube + video_id: "g-86WCp19RE" + duration: 689 + - id: "AgLxcYZ3MZk" + title: "Mathematik: Abbildungen und Relationen #8 - Relationen" + description: + type: youtube + video_id: "AgLxcYZ3MZk" + duration: 428 + - id: "wDdck0dvkYc" + title: "Mathematik: Relationen #9 - Reflexivität, Symmetrie, Transitivität" + description: + type: youtube + video_id: "wDdck0dvkYc" + duration: 469 + - id: "gceIKmaedso" + title: "Mathematik: Relationen #10 - Äquivalenzklassen und der Quotientenraum" + description: + type: youtube + video_id: "gceIKmaedso" + duration: 591 + - id: "MhH41HA9OJw" + title: "Mathematik: Zahlen #1 - Natürliche, Ganze, Rationale und Reelle Zahlen" + description: + type: youtube + video_id: "MhH41HA9OJw" + duration: 596 + - id: "q3UrMVPAINk" + title: "Mathematik: Zahlen #2 - Komplexe Zahlen" + description: + type: youtube + video_id: "q3UrMVPAINk" + duration: 287 + - id: "AXwlPYp6L-4" + title: "Mathematik: Zahlen #3 - Große Operatoren" + description: + type: youtube + video_id: "AXwlPYp6L-4" + duration: 493 + - id: "f0kK3Ekzmy8" + title: "Mathematik: Beweise #1 - Der Direkte Beweis" + description: + type: youtube + video_id: "f0kK3Ekzmy8" + duration: 518 + - id: "fUT7lXkP9Ko" + title: "Mathematik: Beweise #2 - Der Indirekte Beweis" + description: + type: youtube + video_id: "fUT7lXkP9Ko" + duration: 515 + - id: "NyPkBssGe4E" + title: "Mathematik: Beweise #3 - Vollständige Induktion" + description: + type: youtube + video_id: "NyPkBssGe4E" + duration: 1092 + - id: "GFVrItmzn0o" + title: "Mathematik: Gruppen #1 - Was sind Gruppen?" + description: + type: youtube + video_id: "GFVrItmzn0o" + duration: 981 + - id: "m1bkfddyZWk" + title: "Mathematik: Gruppen #2 - Untergruppen" + description: + type: youtube + video_id: "m1bkfddyZWk" + duration: 484 + - id: "br9Qk7dLHW8" + title: "Mathematik: Gruppen #3 - Gruppenhomomorphismen" + description: + type: youtube + video_id: "br9Qk7dLHW8" + duration: 613 + - id: "VKfRfsSoS2I" + title: "Mathematik: Gruppen #4 - Ringe" + description: + type: youtube + video_id: "VKfRfsSoS2I" + duration: 693 + - id: "z-hS9iaW4cE" + title: "Mathematik: Gruppen #5 - Körper" + description: + type: youtube + video_id: "z-hS9iaW4cE" + duration: 562 + - id: "7yxlMS10lR4" + title: "Mathematik: Gruppen #6 - Angeordnete Körper" + description: + type: youtube + video_id: "7yxlMS10lR4" + duration: 518 + - id: "hIyjSAIxQuI" + title: "Mathematik: Gruppen #7 - Rechenregeln für Ungleichungen" + description: + type: youtube + video_id: "hIyjSAIxQuI" + duration: 1212 + - id: "mOTrAKFeB7M" + title: "Mathematik: Gruppen #8 - Betrag und Signum" + description: + type: youtube + video_id: "mOTrAKFeB7M" + duration: 853 + - id: "48hLi8R3dVM" + title: "Mathematik: Gruppen #9 - Vollständige Körper" + description: + type: youtube + video_id: "48hLi8R3dVM" + duration: 685 diff --git a/academy_data/courses/netzsicherheit.yml b/academy_data/courses/netzsicherheit.yml new file mode 100644 index 00000000..dfccb6cd --- /dev/null +++ b/academy_data/courses/netzsicherheit.yml @@ -0,0 +1,218 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7ovwsL-PKfByCX-jGuZAopM +title: "Netzsicherheit - IT Security in Netzwerken" +description: "Haltet eure Netzwerke frei von Angreifern - dazu braucht ihr Zertifikate, IPSec und mehr" +category: +language: de +image: https://static.bootstrap.academy/thumbnails/netzsicherheit.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506743 +sections: + - id: section + title: "Grundlagen" + description: + lectures: + - id: "UVdDfyuzpz8" + title: "Einleitung" + description: + type: youtube + video_id: "UVdDfyuzpz8" + duration: 1629 + - id: "6X8FSF1XXpc" + title: "Extended Validation Zertifikate und andere Zertifikate" + description: + type: youtube + video_id: "6X8FSF1XXpc" + duration: 407 + - id: "jaRJq9XYhVc" + title: "OCSP - Status von Zertifikaten prüfen" + description: + type: youtube + video_id: "jaRJq9XYhVc" + duration: 472 + - id: "h31hMJ6ztVM" + title: "Password Authentication Protocol PAP" + description: + type: youtube + video_id: "h31hMJ6ztVM" + duration: 413 + - id: "u355Z0YyN84" + title: "CHAP" + description: + type: youtube + video_id: "u355Z0YyN84" + duration: 320 + - id: "iQyXs3EX2PM" + title: "S-Key" + description: + type: youtube + video_id: "iQyXs3EX2PM" + duration: 432 + - id: "OkcvnG6Qjok" + title: "EAP" + description: + type: youtube + video_id: "OkcvnG6Qjok" + duration: 462 + - id: "AO29zGa_JHc" + title: "Authentifikation bei mehreren Ressourcen" + description: + type: youtube + video_id: "AO29zGa_JHc" + duration: 319 + - id: section2 + title: "Kerberos" + description: + lectures: + - id: "ooe1G24vzYI" + title: "Kerberos Einführung" + description: + type: youtube + video_id: "ooe1G24vzYI" + duration: 442 + - id: "tSLvaWczpNM" + title: "Das Ticket Granting Ticket" + description: + type: youtube + video_id: "tSLvaWczpNM" + duration: 719 + - id: "ftS7jyK-Sqc" + title: "Ressourcenzugriff" + description: + type: youtube + video_id: "ftS7jyK-Sqc" + duration: 593 + - id: "ewcKF5RJ7TM" + title: "Mehrstufige Netze" + description: + type: youtube + video_id: "ewcKF5RJ7TM" + duration: 491 + - id: section3 + title: "IPSec" + description: + lectures: + - id: "5wjEJurs_Mo" + title: "Angriffe auf IP" + description: + type: youtube + video_id: "5wjEJurs_Mo" + duration: 299 + - id: "Oy8lWxjAqZU" + title: "Übersicht zu IPSec" + description: + type: youtube + video_id: "Oy8lWxjAqZU" + duration: 451 + - id: "CJGfic-O4K0" + title: "Die Datenbanken von IPSec" + description: + type: youtube + video_id: "CJGfic-O4K0" + duration: 449 + - id: "uVWVT4c3kuE" + title: "Tunnelmodus und Transportmodus" + description: + type: youtube + video_id: "uVWVT4c3kuE" + duration: 505 + - id: "yymR6zqtdT8" + title: "AH - Authentication Header" + description: + type: youtube + video_id: "yymR6zqtdT8" + duration: 517 + - id: "L9UtqLy42XI" + title: "ESP - Encapsulation Security Payload" + description: + type: youtube + video_id: "L9UtqLy42XI" + duration: 463 + - id: "eSoIL71Ri0M" + title: "Der Internet Key Exchange - IKE" + description: + type: youtube + video_id: "eSoIL71Ri0M" + duration: 631 + - id: section4 + title: "TLS" + description: + lectures: + - id: "sye1azuEZXw" + title: "Einleitung" + description: + type: youtube + video_id: "sye1azuEZXw" + duration: 570 + - id: "vuMJAgx87TM" + title: "Angriffe auf TLS" + description: + type: youtube + video_id: "vuMJAgx87TM" + duration: 533 + - id: "Y_SR0qIZR8w" + title: "Das Record Protocol" + description: + type: youtube + video_id: "Y_SR0qIZR8w" + duration: 362 + - id: "BmyAIFPcWyc" + title: "Schlüsselgenerierung bei TLS" + description: + type: youtube + video_id: "BmyAIFPcWyc" + duration: 221 + - id: section5 + title: "Netzzugang" + description: + lectures: + - id: "Vqh19T66rhM" + title: "Einleitung" + description: + type: youtube + video_id: "Vqh19T66rhM" + duration: 285 + - id: "C6m8wCNJrfA" + title: "Netzzugang über LAN" + description: + type: youtube + video_id: "C6m8wCNJrfA" + duration: 287 + - id: "L1-CqVfkFFg" + title: "Netzzugang bei VPNs" + description: + type: youtube + video_id: "L1-CqVfkFFg" + duration: 402 + - id: "U82i104RAHc" + title: "Netzzugang bei VPNs #2 - OpenVPN" + description: + type: youtube + video_id: "U82i104RAHc" + duration: 279 + - id: "Dyhq9SPSN-Y" + title: "WEP" + description: + type: youtube + video_id: "Dyhq9SPSN-Y" + duration: 459 + - id: "CflJNJCt6Bs" + title: "WPA2" + description: + type: youtube + video_id: "CflJNJCt6Bs" + duration: 548 + - id: section6 + title: "Bonus" + description: + lectures: + - id: "a5-83uboWzs" + title: "JSON Web Tokens" + description: + type: youtube + video_id: "a5-83uboWzs" + duration: 876 diff --git a/academy_data/courses/netzwerktechnik.yml b/academy_data/courses/netzwerktechnik.yml new file mode 100644 index 00000000..5f13d9ab --- /dev/null +++ b/academy_data/courses/netzwerktechnik.yml @@ -0,0 +1,492 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7rjW6OL4aGL-L1SzBUijh8r +title: "Netzwerktechnik" +description: "In einer Welt, in der jeder mit jedem immer verbunden sein kann, braucht es eine Grundlage, auf welcher das basiert: Das Internet. Bestehend aus zig Protokollen und vielen wichtigen Regeln, ist es wichtig, zu verstehen, was genau das eigentlich bedeutet!" +category: +language: de +image: +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506949 +sections: + - id: section + title: "Grundlagen" + description: + lectures: + - id: "QEsQkpG6I4w" + title: "Einleitung" + description: + type: youtube + video_id: "QEsQkpG6I4w" + duration: 224 + - id: "n4FpSd-ApTY" + title: "Dienste" + description: + type: youtube + video_id: "n4FpSd-ApTY" + duration: 554 + - id: "LiyA3mEedYM" + title: "Das ISO-OSI Referenzmodell" + description: + type: youtube + video_id: "LiyA3mEedYM" + duration: 684 + - id: section2 + title: "Schicht 1: Die physische Schicht" + description: + lectures: + - id: "VSOK-jK4Q6k" + title: "Simplex, Duplex und Halbduplex" + description: + type: youtube + video_id: "VSOK-jK4Q6k" + duration: 292 + - id: "zNRkP2I7TMs" + title: "Signalklassen" + description: + type: youtube + video_id: "zNRkP2I7TMs" + duration: 411 + - id: "xK6a0VKE3KA" + title: "Binäre Leitungscodes - Non Return to Zero" + description: + type: youtube + video_id: "xK6a0VKE3KA" + duration: 250 + - id: "SWeUIgvja4A" + title: "Biphasen Leitungscodes - Non Return to Zero Inverted, Manchester Code" + description: + type: youtube + video_id: "SWeUIgvja4A" + duration: 506 + - id: "4mt883GmToA" + title: "Ternäre Leitungscodes" + description: + type: youtube + video_id: "4mt883GmToA" + duration: 379 + - id: "w20Ku3iy3b0" + title: "Blockcodes" + description: + type: youtube + video_id: "w20Ku3iy3b0" + duration: 367 + - id: "BOSHIt_f2lM" + title: "Störungen und Repeater" + description: + type: youtube + video_id: "BOSHIt_f2lM" + duration: 431 + - id: "SWVjv0RjAEA" + title: "Mehrfachnutzung und Multiplexen" + description: + type: youtube + video_id: "SWVjv0RjAEA" + duration: 319 + - id: section3 + title: "Schicht 2: Die Sicherungsschicht" + description: + lectures: + - id: "0UnYQ-VHavM" + title: "Netztopologien" + description: + type: youtube + video_id: "0UnYQ-VHavM" + duration: 450 + - id: "Up5-3kOkeTY" + title: "Paketverluste und Quittungen" + description: + type: youtube + video_id: "Up5-3kOkeTY" + duration: 614 + - id: "rUsjT_5wLnQ" + title: "ARQ - Automatic Repeat Request" + description: + type: youtube + video_id: "rUsjT_5wLnQ" + duration: 748 + - id: "j975yg5SAyo" + title: "CRC: zyklische Redundanzprüfung" + description: + type: youtube + video_id: "j975yg5SAyo" + duration: 448 + - id: "TCXp91RdTH8" + title: "Flusskontrolle" + description: + type: youtube + video_id: "TCXp91RdTH8" + duration: 391 + - id: "3GLRDOD4GBo" + title: "Handshakes" + description: + type: youtube + video_id: "3GLRDOD4GBo" + duration: 362 + - id: "JxSeX9QbwNc" + title: "HDLC" + description: + type: youtube + video_id: "JxSeX9QbwNc" + duration: 754 + - id: "2YzAIvEEUI8" + title: "Aloha" + description: + type: youtube + video_id: "2YzAIvEEUI8" + duration: 688 + - id: "VuuW8n1TVCk" + title: "Carrier Sense Multiple Access - CSMA" + description: + type: youtube + video_id: "VuuW8n1TVCk" + duration: 684 + - id: "LnIw2Rr2oiA" + title: "CSMA-CD vs- CSMA-CA" + description: + type: youtube + video_id: "LnIw2Rr2oiA" + duration: 334 + - id: "haKY_Q1gMG0" + title: "Ethernet" + description: + type: youtube + video_id: "haKY_Q1gMG0" + duration: 940 + - id: "J670n74SpG4" + title: "Kollisionsdomänen" + description: + type: youtube + video_id: "J670n74SpG4" + duration: 494 + - id: "2-G8ZhcB_yQ" + title: "Token Ring" + description: + type: youtube + video_id: "2-G8ZhcB_yQ" + duration: 295 + - id: "9ndcP8qoUAc" + title: "Brücken und Switches" + description: + type: youtube + video_id: "9ndcP8qoUAc" + duration: 668 + - id: "i8FZbRislpo" + title: "Das Bridge Protocol" + description: + type: youtube + video_id: "i8FZbRislpo" + duration: 804 + - id: "fvX_k7rV6-Y" + title: "Fast Ethernet, Gigabit Ethernet und 10 Gigabit Ethernet" + description: + type: youtube + video_id: "fvX_k7rV6-Y" + duration: 394 + - id: section4 + title: "Schicht 3: Routing" + description: + lectures: + - id: "gAS1PxqRKf8" + title: "Routing Grundlagen" + description: + type: youtube + video_id: "gAS1PxqRKf8" + duration: 456 + - id: "4NjTX88u-fw" + title: "In Line Speed" + description: + type: youtube + video_id: "4NjTX88u-fw" + duration: 226 + - id: "kkvB3OE4sIw" + title: "IP Forwarding Tabelle" + description: + type: youtube + video_id: "kkvB3OE4sIw" + duration: 619 + - id: "R1hAZU8R-dU" + title: "Binäre Tries und Patricia Tries" + description: + type: youtube + video_id: "R1hAZU8R-dU" + duration: 608 + - id: "79gHEOsFJOo" + title: "Content Adressable Memory" + description: + type: youtube + video_id: "79gHEOsFJOo" + duration: 464 + - id: "eDtmcV4oK54" + title: "IP Datenpakete" + description: + type: youtube + video_id: "eDtmcV4oK54" + duration: 1136 + - id: "2E6WXnXlQBk" + title: "Routing Algorithmen" + description: + type: youtube + video_id: "2E6WXnXlQBk" + duration: 557 + - id: "Rt04_sYCELU" + title: "Distanz Vektor Algorithmen" + description: + type: youtube + video_id: "Rt04_sYCELU" + duration: 453 + - id: "2SdvR9KdC30" + title: "Distanz Vektor Algorithmen #2" + description: + type: youtube + video_id: "2SdvR9KdC30" + duration: 456 + - id: "qyGqQWM2YTk" + title: "Link State Algorithmen" + description: + type: youtube + video_id: "qyGqQWM2YTk" + duration: 588 + - id: "ipDhLgJxwXA" + title: "Das Address Resolution Protocol ARP" + description: + type: youtube + video_id: "ipDhLgJxwXA" + duration: 471 + - id: "PU6xFCkj0Yg" + title: "Internet Control Message Protocol ICMP" + description: + type: youtube + video_id: "PU6xFCkj0Yg" + duration: 271 + - id: "E-dAE5sARWQ" + title: "Autonome Systeme aka Netz aus Netzen" + description: + type: youtube + video_id: "E-dAE5sARWQ" + duration: 754 + - id: "uWadG3fWxBQ" + title: "Content Delivery Provider und Networks" + description: + type: youtube + video_id: "uWadG3fWxBQ" + duration: 350 + - id: "bKca4gfgA_I" + title: "Internet Exchange Points IXP" + description: + type: youtube + video_id: "bKca4gfgA_I" + duration: 316 + - id: "LUmajjJEq24" + title: "Das Border Gateway Protocol BGP" + description: + type: youtube + video_id: "LUmajjJEq24" + duration: 1068 + - id: "lQ2eIHwnHhE" + title: "Adressknappheit und NATs" + description: + type: youtube + video_id: "lQ2eIHwnHhE" + duration: 730 + - id: "nB3rA_H4I4s" + title: "IPv6" + description: + type: youtube + video_id: "nB3rA_H4I4s" + duration: 631 + - id: section5 + title: "Schicht 4: Die Transportschicht" + description: + lectures: + - id: "bmvISgR-C_4" + title: "Die Transportschicht" + description: + type: youtube + video_id: "bmvISgR-C_4" + duration: 465 + - id: "7FWb0cHeikc" + title: "User Datagram Protocol UDP" + description: + type: youtube + video_id: "7FWb0cHeikc" + duration: 301 + - id: "SUD2cUnNQMw" + title: "Transmission Control Protocol TCP" + description: + type: youtube + video_id: "SUD2cUnNQMw" + duration: 591 + - id: "vnoZsk50w5E" + title: "TCP #2" + description: + type: youtube + video_id: "vnoZsk50w5E" + duration: 494 + - id: "VgwYpsvzZlQ" + title: "Flusskontrolle" + description: + type: youtube + video_id: "VgwYpsvzZlQ" + duration: 365 + - id: "uDYIxXqk5Ok" + title: "SYN Flooding Angriffe und SYN Cookies" + description: + type: youtube + video_id: "uDYIxXqk5Ok" + duration: 522 + - id: "5jT-q71xNKw" + title: "TCP Option Window Scaling" + description: + type: youtube + video_id: "5jT-q71xNKw" + duration: 260 + - id: "u2xJtSsSvYY" + title: "Staukontrolle" + description: + type: youtube + video_id: "u2xJtSsSvYY" + duration: 374 + - id: "9_LEr3SSJtc" + title: "Random Early Detection RED" + description: + type: youtube + video_id: "9_LEr3SSJtc" + duration: 540 + - id: "IJulDEZHJW0" + title: "Slow Start" + description: + type: youtube + video_id: "IJulDEZHJW0" + duration: 508 + - id: "gATuauC2lJA" + title: "Der Retransmission Timer" + description: + type: youtube + video_id: "gATuauC2lJA" + duration: 588 + - id: "yAnEWhMACxc" + title: "weitere TCP Features" + description: + type: youtube + video_id: "yAnEWhMACxc" + duration: 498 + - id: "Xs70Fdz3jy8" + title: "Congestion Avoidance" + description: + type: youtube + video_id: "Xs70Fdz3jy8" + duration: 257 + - id: "-U0LkNcZVNQ" + title: "TCP Tahoe" + description: + type: youtube + video_id: "-U0LkNcZVNQ" + duration: 436 + - id: "G7-yFCs3RI4" + title: "TCP Reno" + description: + type: youtube + video_id: "G7-yFCs3RI4" + duration: 539 + - id: "eSunM5kNcT8" + title: "TCP Fairness" + description: + type: youtube + video_id: "eSunM5kNcT8" + duration: 496 + - id: "lgTqC9ubkw4" + title: "Einige Formeln zur Leistung von TCP" + description: + type: youtube + video_id: "lgTqC9ubkw4" + duration: 744 + - id: "w_5B382keNw" + title: "Linux - Cubic TCP" + description: + type: youtube + video_id: "w_5B382keNw" + duration: 517 + - id: "CcjCUGeCO00" + title: "Windows - Compound TCP" + description: + type: youtube + video_id: "CcjCUGeCO00" + duration: 710 + - id: section6 + title: "Schicht 7: Die Anwendungsschicht" + description: + lectures: + - id: "eOv5H-yD2go" + title: "HTTP - Hyper Text Transfer Protocol" + description: + type: youtube + video_id: "eOv5H-yD2go" + duration: 630 + - id: "HA3WAWV1AWg" + title: "HTTP Anfragen in der Praxis" + description: + type: youtube + video_id: "HA3WAWV1AWg" + duration: 379 + - id: "daE9hBS6VtA" + title: "HTTP-Statuscodes" + description: + type: youtube + video_id: "daE9hBS6VtA" + duration: 315 + - id: "LH3I3oXvWrU" + title: "SSH - Secure Shell" + description: + type: youtube + video_id: "LH3I3oXvWrU" + duration: 359 + - id: "ITXcKBXkRFs" + title: "SSH Verschlüsselung" + description: + type: youtube + video_id: "ITXcKBXkRFs" + duration: 431 + - id: "_8CfylnwXmA" + title: "SSH - Connection Protocol" + description: + type: youtube + video_id: "_8CfylnwXmA" + duration: 422 + - id: "m8-rfv5oceE" + title: "FTP - File Transfer Protocol" + description: + type: youtube + video_id: "m8-rfv5oceE" + duration: 346 + - id: "PfpvpCm4C90" + title: "SMTP - Simple Mail Transfer Protocol" + description: + type: youtube + video_id: "PfpvpCm4C90" + duration: 535 + - id: "CPWZ-U9j3HQ" + title: "POP - Post Office Protocol" + description: + type: youtube + video_id: "CPWZ-U9j3HQ" + duration: 260 + - id: "Y3gtTX4hvMc" + title: "Bittorrent" + description: + type: youtube + video_id: "Y3gtTX4hvMc" + duration: 482 + - id: section7 + title: "Bonus" + description: + lectures: + - id: "6BmqSrBteY0" + title: "Die Top 6 Netzwerk-Protokolle für Internet of Things" + description: + type: youtube + video_id: "6BmqSrBteY0" + duration: 960 diff --git a/academy_data/courses/nmap.yml b/academy_data/courses/nmap.yml new file mode 100644 index 00000000..c6afc6c2 --- /dev/null +++ b/academy_data/courses/nmap.yml @@ -0,0 +1,143 @@ +# https://www.dropbox.com/t/StNqLy6nuirPr18C +title: "NMap: Netzscans in der Praxis" +description: "NMap ist das am meisten genutzte Tool, um Netzwerke zu scannen - welche Geräte gibt es, wo sind diese erreichbar. Damit ist es das wohl am meisten genutzte Tool für IT-Security überhaupt." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/nmap.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 3000 +learning_goals: [] +requirements: [] +last_update: 1665584088 +sections: + - id: section + title: "NMap" + description: + lectures: + - id: "1_was_ist_nmap" + title: "Was ist Nmap?" + description: + type: mp4 + duration: 469 + - id: "2_der_erste_scan" + title: "Der erste Scan" + description: + type: mp4 + duration: 590 + - id: "3_subnetze_scannen" + title: "Subnetze scannen" + description: + type: mp4 + duration: 464 + - id: "4_nicht_alles_scannen" + title: "Nicht alles scannen" + description: + type: mp4 + duration: 457 + - id: "5_ausgaben" + title: "Ausgaben" + description: + type: mp4 + duration: 506 + - id: "6_wichtige_ports" + title: "Wichtige Ports" + description: + type: mp4 + duration: 647 + - id: "7_tcp_und_udp_scans" + title: "TCP und UDP Scans" + description: + type: mp4 + duration: 449 + - id: "8_einzelne_ports_und_port_bereiche" + title: "Einzelne Ports und Port-Bereiche" + description: + type: mp4 + duration: 237 + - id: "9_syn_scans" + title: "Syn Scans" + description: + type: mp4 + duration: 364 + - id: "10_ack_scans" + title: "Ack Scans" + description: + type: mp4 + duration: 384 + - id: "11_x_mas_fin_und_null_scans" + title: "X-Mas, Fin und Null Scans" + description: + type: mp4 + duration: 414 + - id: "12_timeouts_und_geschwindigkeiten" + title: "Timeouts und Geschwindigkeiten" + description: + type: mp4 + duration: 345 + - id: "13_hostgroups" + title: "Hostgroups" + description: + type: mp4 + duration: 317 + - id: "14_hosts_gleichzeitig_scannen" + title: "Hosts gleichzeitig scannen" + description: + type: mp4 + duration: 226 + - id: "15_host_timeouts_vs_rtt_timeouts" + title: "Host Timeouts vs RTT Timeouts" + description: + type: mp4 + duration: 373 + - id: "16_ping_sweeps_list_scans_und_disable_pings" + title: "Ping Sweeps, List Scans und Disable Pings" + description: + type: mp4 + duration: 592 + - id: "17_tcp_windows_scan" + title: "TCP Windows Scan" + description: + type: mp4 + duration: 314 + - id: "18_tcp_maimon_scan" + title: "TCP Maimon Scan" + description: + type: mp4 + duration: 150 + - id: "19_service_und_versionserkennung_einleitung" + title: "Service und Versionserkennung - Einleitung" + description: + type: mp4 + duration: 477 + - id: "20_service_und_versionserkennung_praxis" + title: "Service und Versionserkennung - Praxis" + description: + type: mp4 + duration: 645 + - id: "21_betriebssysteme_erkennen" + title: "Betriebssysteme erkennen" + description: + type: mp4 + duration: 423 + - id: "22_nmap_scripting_engine" + title: "Nmap Scripting Engine" + description: + type: mp4 + duration: 459 + - id: "23_nmap_scripting_engine_viele_möglichkeiten_scripte_auszuführen" + title: "Nmap Scripting Engine - viele Möglichkeiten Scripte auszuführen" + description: + type: mp4 + duration: 330 + - id: "24_nmap_scripting_engine_die_scripte" + title: "Nmap Scripting Engine - Die Scripte" + description: + type: mp4 + duration: 1383 + - id: "25_letzte_worte" + title: "Letzte Worte" + description: + type: mp4 + duration: 124 diff --git a/academy_data/courses/nodejs.yml b/academy_data/courses/nodejs.yml new file mode 100644 index 00000000..6b1df5f0 --- /dev/null +++ b/academy_data/courses/nodejs.yml @@ -0,0 +1,132 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7o-5JThNbEVW6CGAhWJwnkA +title: "Node.js Tutorial - Serverseitiges JavaScript" +description: "Ihr wollt serverseitig JavaScript laufen lassen? Dann geht das mit NodeJS. Diese Tutorials werden stark von der Express Reihe ergänzt und ergänzen diese Reihe ebenso." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/javascript.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 3000 +learning_goals: [] +requirements: [] +last_update: 1665507460 +sections: + - id: section + title: "Node.js Tutorial - Serverseitiges JavaScript" + description: + lectures: + - id: "IyNpu4t30e8" + title: "NodeJS: JavaScript sinnvoll erweitern" + description: + type: youtube + video_id: "IyNpu4t30e8" + duration: 431 + - id: "f15kMS0z5iU" + title: "NPM - Paketmanager für Javascript" + description: + type: youtube + video_id: "f15kMS0z5iU" + duration: 411 + - id: "pRZ5qdJxxgE" + title: "Abhängigkeiten definieren und Projekte weitergeben mit der Package.json" + description: + type: youtube + video_id: "pRZ5qdJxxgE" + duration: 355 + - id: "Ei7-YOR8oRU" + title: "NPM - Automatisierte Builds und Browserify" + description: + type: youtube + video_id: "Ei7-YOR8oRU" + duration: 1002 + - id: "9mTQPlhNvb8" + title: "Mit nodemon unkompliziert schnelleres serverseitiges Arbeiten ermöglichen" + description: + type: youtube + video_id: "9mTQPlhNvb8" + duration: 257 + - id: "NQEPx_m8T_c" + title: "Ein Node Server mit JavaScript" + description: + type: youtube + video_id: "NQEPx_m8T_c" + duration: 514 + - id: "3yamCfm0DSU" + title: "Die Event Loop" + description: + type: youtube + video_id: "3yamCfm0DSU" + duration: 545 + - id: "IWtwvRiVryA" + title: "Das Request Object" + description: + type: youtube + video_id: "IWtwvRiVryA" + duration: 484 + - id: "fSYdusZmdEw" + title: "Das Response Object" + description: + type: youtube + video_id: "fSYdusZmdEw" + duration: 441 + - id: "J1i19TAIffw" + title: "POST Requests verarbeiten" + description: + type: youtube + video_id: "J1i19TAIffw" + duration: 1103 + - id: "GGp7doY0OpQ" + title: "Dateien schreiben" + description: + type: youtube + video_id: "GGp7doY0OpQ" + duration: 597 + - id: "U_hIbwbiyw4" + title: "Mit MySQL verbinden" + description: + type: youtube + video_id: "U_hIbwbiyw4" + duration: 696 + - id: "w-_81TcrgyA" + title: "Mit SQL arbeiten" + description: + type: youtube + video_id: "w-_81TcrgyA" + duration: 438 + - id: "yGqllZCqDP8" + title: "Einfache und effektive Datenbank Integration mit Sequelize" + description: + type: youtube + video_id: "yGqllZCqDP8" + duration: 524 + - id: "UJIwEkAPIP4" + title: "Das User Model und einfügen von neuen Usern" + description: + type: youtube + video_id: "UJIwEkAPIP4" + duration: 750 + - id: "9b-pJKbBcxI" + title: "Einträge mit Sequelize holen" + description: + type: youtube + video_id: "9b-pJKbBcxI" + duration: 708 + - id: "mQfhgSMhK0k" + title: "Operatoren in Sequelize" + description: + type: youtube + video_id: "mQfhgSMhK0k" + duration: 542 + - id: "K4JKnVHcJOc" + title: "Assoziationen" + description: + type: youtube + video_id: "K4JKnVHcJOc" + duration: 786 + - id: "a4CHruqUzEo" + title: "Assoziationen schreiben und holen" + description: + type: youtube + video_id: "a4CHruqUzEo" + duration: 574 diff --git a/academy_data/courses/password_cracking.yml b/academy_data/courses/password_cracking.yml new file mode 100644 index 00000000..adc49272 --- /dev/null +++ b/academy_data/courses/password_cracking.yml @@ -0,0 +1,276 @@ +# https://www.dropbox.com/t/aeL10y4q9c3b5V5M +title: "Passwort Cracking" +description: "Was macht denn eigentlich ein sicheres Passwort aus und warum ist es schlecht, wenn ihr es wiederverwende? In dieser Reihe seht ihr in der Praxis, wie Passwörter geknackt werden und wie man das verhindern kann." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/pentesting.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 3000 +learning_goals: [] +requirements: [] +last_update: 1665584088 +sections: + - id: section + title: "Grundlagen" + description: + lectures: + - id: "passwort_cracking_tutorial_1_einleitung" + title: "Einleitung" + description: + type: mp4 + duration: 479 + - id: "passwort_cracking_tutorial_2_hashes_und_passwörter" + title: "Hashes und Passwörter" + description: + type: mp4 + duration: 553 + - id: "passwort_cracking_tutorial_3_brute_force_cracking" + title: "Brute Force Cracking" + description: + type: mp4 + duration: 229 + - id: "passwort_cracking_tutorial_4_hashfunktionen_in_der_übersicht" + title: "Hashfunktionen in der Übersicht" + description: + type: mp4 + duration: 506 + - id: section2 + title: "Menschliches Versagen" + description: + lectures: + - id: "passwort_cracking_tutorial_5_menschliche_passwörter" + title: "Menschliche Passwörter" + description: + type: mp4 + duration: 826 + - id: "passwort_cracking_tutorial_6_dictionary_attacks" + title: "Dictionary Attacks" + description: + type: mp4 + duration: 405 + - id: "passwort_cracking_tutorial_7_öffentliche_wordlists_rockyou.txt" + title: "Öffentliche Wordlists - Rockyou.txt" + description: + type: mp4 + duration: 296 + - id: "passwort_cracking_tutorial_8_cewl_wordlisten_generieren" + title: "CeWL - Wordlisten generieren" + description: + type: mp4 + duration: 541 + - id: "passwort_cracking_tutorial_9_rainbowtables" + title: "Rainbowtables" + description: + type: mp4 + duration: 352 + - id: "passwort_cracking_tutorial_10_rainbowcrack" + title: "rainbowcrack" + description: + type: mp4 + duration: 665 + - id: section3 + title: "Hashes Identifizieren" + description: + lectures: + - id: "passwort_cracking_tutorial_11_hashid_zum_herausfinden_des_genutzten_hashes" + title: "HashID zum herausfinden des genutzten Hashes" + description: + type: mp4 + duration: 304 + - id: section4 + title: "Hashcat" + description: + lectures: + - id: "passwort_cracking_tutorial_12_hashcat_installation" + title: "Installation" + description: + type: mp4 + duration: 659 + - id: "passwort_cracking_tutorial_13_hashcat_ein_kurzer_blick_durch_die_hilfe" + title: "ein kurzer Blick durch die Hilfe" + description: + type: mp4 + duration: 370 + - id: "passwort_cracking_tutorial_14_hashcat_benchmark_und_kernel_timeout_fehler" + title: "Benchmark und Kernel Timeout Fehler" + description: + type: mp4 + duration: 419 + - id: "passwort_cracking_tutorial_15_hashcat_wie_lange_dauert_der_crackvorgang" + title: "Wie lange dauert der Crackvorgang" + description: + type: mp4 + duration: 595 + - id: "passwort_cracking_tutorial_16_hashcat_ein_dictionary_angriff" + title: "Ein Dictionary Angriff" + description: + type: mp4 + duration: 183 + - id: "passwort_cracking_tutorial_17_hashcat_brute_force_angriffe" + title: "Brute Force Angriffe" + description: + type: mp4 + duration: 517 + - id: "passwort_cracking_tutorial_18_hashcat_fortgeschrittene_mask_attacks" + title: "Fortgeschrittene Mask Attacks" + description: + type: mp4 + duration: 351 + - id: "passwort_cracking_tutorial_19_hashcat_eigene_charsets" + title: "Eigene Charsets" + description: + type: mp4 + duration: 724 + - id: "passwort_cracking_tutorial_20_hashcat_eigene_charsets_in_maskendateien" + title: "Eigene Charsets in Maskendateien" + description: + type: mp4 + duration: 325 + - id: "passwort_cracking_tutorial_21_hashcat_ein_python_script_zum_generieren_von_masken" + title: "Ein Python Script zum generieren von Masken" + description: + type: mp4 + duration: 266 + - id: "passwort_cracking_tutorial_22_hashcat_combinator_attacks" + title: "Combinator Attacks" + description: + type: mp4 + duration: 390 + - id: "passwort_cracking_tutorial_23_hashcat_combinator_attacks_mit_sonderzeichen_dazwischen" + title: "Combinator Attacks mit Sonderzeichen dazwischen" + description: + type: mp4 + duration: 240 + - id: "passwort_cracking_tutorial_24_hashcat_hybrid_attacks" + title: "Hybrid Attacks" + description: + type: mp4 + duration: 465 + - id: "passwort_cracking_tutorial_25_hashcat_rule_based_attacks" + title: "Rule based Attacks" + description: + type: mp4 + duration: 565 + - id: "passwort_cracking_tutorial_26_hashcat_limitierungen_von_hashcat" + title: "Limitierungen von hashcat" + description: + type: mp4 + duration: 515 + - id: "passwort_cracking_tutorial_27_hashcat_online_im_team_cracken" + title: "Online im Team cracken" + description: + type: mp4 + duration: 542 + - id: section5 + title: "Ein kurzer Einblick in THC Hydra" + description: + lectures: + - id: "passwort_cracking_tutorial_28_thc_hydra_passwörter_im_netzwerk_cracken" + title: "Passwörter im Netzwerk cracken" + description: + type: mp4 + duration: 838 + - id: "passwort_cracking_tutorial_29_thc_hydra_generierte_passwörter" + title: "Generierte Passwörter" + description: + type: mp4 + duration: 256 + - id: section6 + title: "Praktische Beispiele" + description: + lectures: + - id: "passwort_cracking_tutorial_30_wordpress_weblogin_cracken_mit_thc_hydra" + title: "Wordpress Weblogin cracken mit THC Hydra" + description: + type: mp4 + duration: 603 + - id: "passwort_cracking_tutorial_31_wordpress_datenbanken_cracken_mit_hashcat" + title: "Wordpress Datenbanken cracken mit Hashcat" + description: + type: mp4 + duration: 485 + - id: "passwort_cracking_tutorial_32_mysql_zugang_knacken_mit_thc_hydra" + title: "MySQL Zugang knacken mit thc hydra" + description: + type: mp4 + duration: 345 + - id: "passwort_cracking_tutorial_33_wpa_handshakes_mit_hashcat_cracken" + title: "WPA Handshakes mit hashcat cracken" + description: + type: mp4 + duration: 245 + - id: "passwort_cracking_tutorial_34_phpbb_passwörter_auslesen_und_mit_hashcat_cracken" + title: "PHPBB Passwörter auslesen und mit hashcat cracken" + description: + type: mp4 + duration: 670 + - id: "passwort_cracking_tutorial_35_7zip_passwörter_cracken_mit_hashcat" + title: "7Zip Passwörter cracken mit Hashcat" + description: + type: mp4 + duration: 505 + - id: "passwort_cracking_tutorial_36_truecrypt_archive_cracken_mit_hashcat" + title: "TrueCrypt Archive cracken mit Hashcat" + description: + type: mp4 + duration: 386 + - id: "passwort_cracking_tutorial_37_veracrypt_archive_cracken_mit_hashcat" + title: "VeraCrypt Archive cracken mit Hashcat" + description: + type: mp4 + duration: 389 + - id: section7 + title: "John The Ripper als Erweiterung" + description: + lectures: + - id: "passwort_cracking_tutorial_38_john_the_ripper_installation" + title: "Installation" + description: + type: mp4 + duration: 354 + - id: "passwort_cracking_tutorial_39_ms_office_cracken_mit_hashcat_und_john_the_ripper_installation" + title: "MS Office cracken" + description: + type: mp4 + duration: 376 + - id: "passwort_cracking_tutorial_40_pdfs_cracken_mit_hashcat_und_john_the_ripper_installation" + title: "PDFs cracken" + description: + type: mp4 + duration: 396 + - id: "passwort_cracking_tutorial_41_winrar_archive_cracken_mit_hashcat_und_john_the_ripper_installation" + title: "WinRar Archive cracken" + description: + type: mp4 + duration: 494 + - id: "passwort_cracking_tutorial_42_linux_passwörter_cracken_mit_hashcat" + title: "Linux Passwörter cracken" + description: + type: mp4 + duration: 292 + - id: "passwort_cracking_tutorial_43_ssh_zugänge_cracken_mit_thc_hydra" + title: "SSH Zugänge cracken mit THC Hydra" + description: + type: mp4 + duration: 342 + - id: section8 + title: "Ein Blick über den Tellerrand" + description: + lectures: + - id: "passwort_cracking_tutorial_44_wordlisten_aufteilen_um_im_team_zu_cracken_python" + title: "Wordlisten aufteilen um im Team zu cracken - Python" + description: + type: mp4 + duration: 536 + - id: "passwort_cracking_tutorial_45_hashcracking_in_der_cloud" + title: "Hashcracking in der Cloud" + description: + type: mp4 + duration: 316 + - id: "passwort_cracking_tutorial_46_applikationen_vor_crackern_schützen" + title: "Applikationen vor Crackern schützen" + description: + type: mp4 + duration: 435 diff --git a/academy_data/courses/pentesting_grundlagen.yml b/academy_data/courses/pentesting_grundlagen.yml new file mode 100644 index 00000000..c6ce1ba4 --- /dev/null +++ b/academy_data/courses/pentesting_grundlagen.yml @@ -0,0 +1,310 @@ +# https://www.dropbox.com/t/zSbvLhXHePo5x92u +title: "Pentesting Grundlagen" +description: | + Hacker-Angriffe gibt es überall. Aber wie gehen Hacker wirklich vor? Was nutzen sie? + Diese Serie fasst meine alten Playlists zu allgemeinem Pentesting zusammen - wird aber noch ergänzt, da ich mit vielem nicht mehr ganz so zufrieden bin und noch einiges fehlt! +category: +language: de +image: https://static.bootstrap.academy/thumbnails/pentesting.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665584088 +sections: + - id: section + title: "Pre-Engagement" + description: + lectures: + - id: "was_tun_hacker" + title: "Was tun Hacker" + description: + type: mp4 + duration: 897 + - id: "pentesting_1_einleitung" + title: "Was ist Pentesting?" + description: + type: mp4 + duration: 530 + - id: "pentesting_2_pre_engagement" + title: "Pre-engagement" + description: + type: mp4 + duration: 646 + - id: section2 + title: "Information Gathering" + description: + lectures: + - id: "pentesting_2_a_information_gathering" + title: "Information Gathering" + description: + type: mp4 + duration: 398 + - id: "pentesting_3_welche_informationen_uns_ping_verschafft" + title: "Welche Informationen uns Ping verschafft" + description: + type: mp4 + duration: 681 + - id: "pentesting_4_whois" + title: "WHOIS" + description: + type: mp4 + duration: 248 + - id: "pentesting_5_dns_einträge" + title: "DNS-Einträge" + description: + type: mp4 + duration: 290 + - id: "hacken_tutorial_dnsrecon" + title: "DNSRecon" + description: + type: mp4 + duration: 459 + - id: "pentesting_6_http_reponse_headers" + title: "HTTP-Reponse Headers" + description: + type: mp4 + duration: 426 + - id: "pentesting_7_google_hacking_database" + title: "Google Hacking Database" + description: + type: mp4 + duration: 249 + - id: "pentesting_8_google_commands" + title: "Google Commands" + description: + type: mp4 + duration: 552 + - id: "pentesting_9_the_harvester" + title: "The Harvester" + description: + type: mp4 + duration: 251 + - id: "TV-uJHR5v-Q" + title: "Überprüfen, ob eine Email Adresse auf dem Server existiert" + description: + type: youtube + video_id: "TV-uJHR5v-Q" + duration: 324 + - id: "pentesting_10_netcraft" + title: "Netcraft" + description: + type: mp4 + duration: 242 + - id: "pentesting_11_port_scanning" + title: "Port Scanning" + description: + type: mp4 + duration: 396 + - id: "EzKy7gDQh6A" + title: "RustScan: Das schnellere nmap" + description: + type: youtube + video_id: "EzKy7gDQh6A" + duration: 393 + - id: "pentesting_12_port_scanning_arten" + title: "Port Scanning Arten" + description: + type: mp4 + duration: 568 + - id: "pentesting_13_vulnerability_scanner" + title: "Vulnerability Scanner" + description: + type: mp4 + duration: 382 + - id: "pentesting_14_input_fuzzing" + title: "Input Fuzzing" + description: + type: mp4 + duration: 185 + - id: "GLmpLeghM2Y" + title: "WLan angreifen - WPA/WPA2 über Handshake - Bruteforce" + description: + type: youtube + video_id: "GLmpLeghM2Y" + duration: 1103 + - id: "DltSGCQ4KWE" + title: "WLan angreifen - WPS mit Reaver" + description: + type: youtube + video_id: "DltSGCQ4KWE" + duration: 746 + - id: "K0DkuJewt-s" + title: "einen Evil Twin erstellen" + description: + type: youtube + video_id: "K0DkuJewt-s" + duration: 775 + - id: "hacking_4_sniffen_mit_einem_evil_twin" + title: "Sniffen mit einem Evil Twin" + description: + type: mp4 + duration: 521 + - id: "hacking_5_macchanger" + title: "Macchanger" + description: + type: mp4 + duration: 463 + - id: "lr9NnFqZlMo" + title: "Dateien von Windows retten" + description: + type: youtube + video_id: "lr9NnFqZlMo" + duration: 303 + - id: "PlDg6vNSYnk" + title: "Shodan - Suchengine für Hacker" + description: + type: youtube + video_id: "PlDg6vNSYnk" + duration: 171 + - id: "hacking_15_server_herausfinden_mit_netcat" + title: "Server herausfinden mit Netcat" + description: + type: mp4 + duration: 190 + - id: "hacking_16_serveranalyse_mit_httprint" + title: "Serveranalyse mit httprint" + description: + type: mp4 + duration: 316 + - id: "hacking_20_scans_mit_xprobe" + title: "Scans mit xprobe" + description: + type: mp4 + duration: 135 + - id: "hacking_vulnerability_scans_mit_uniscan_mit_disclaimer" + title: "Vulnerability Scans mit uniscan" + description: + type: mp4 + duration: 377 + - id: section3 + title: "Threat Modelling" + description: + lectures: [] + - id: section4 + title: "Vulnerability Analysis" + description: + lectures: [] + - id: section5 + title: "Exploitation" + description: + lectures: + - id: "pentesting_15_zugriff_bekommen" + title: "Zugriff bekommen" + description: + type: mp4 + duration: 432 + - id: "hacking_18_einen_socket_server_erstellen_mit_netcat" + title: "Einen Socket Server erstellen mit Netcat" + description: + type: mp4 + duration: 178 + - id: "hacking_19_browser_hacken_mit_beef" + title: "Browser Hacken mit beEF" + description: + type: mp4 + duration: 421 + - id: "hacking_14_dos_angriffe_unter_linux" + title: "DoS Angriffe unter Linux" + description: + type: mp4 + duration: 284 + - id: "hacking_8_dos_angriffe_auf_router" + title: "DoS - Angriffe auf Router" + description: + type: mp4 + duration: 426 + - id: "hacking_9_dos_mit_loic" + title: "DoS mit LOIC" + description: + type: mp4 + duration: 352 + - id: "hacking_slowloris_ddos_tool" + title: "Slowloris DDoS Tool" + description: + type: mp4 + duration: 265 + - id: "hacking_dns_spoofing_mit_ettercap_vollständig" + title: "DNS Spoofing mit Ettercap" + description: + type: mp4 + duration: 595 + - id: "hacking_qr_codes_mit_disclaimer" + title: "QR Codes" + description: + type: mp4 + duration: 229 + - id: "hacking_social_engineering_mail_fälschen_mit_disclaimer" + title: "Hacking - Social Engineering - Mail fälschen mit Disclaimer" + description: + type: mp4 + duration: 375 + - id: section6 + title: "Einschub: Metasploit" + description: + lectures: + - id: "metasploit_1_basics" + title: "Basics" + description: + type: mp4 + duration: 346 + - id: "metasploit_2_armitage" + title: "Armitage" + description: + type: mp4 + duration: 330 + - id: "metasploit_3_payload_generieren" + title: "Payload generieren" + description: + type: mp4 + duration: 420 + - id: "metasploit_4_veil_evasion" + title: "Veil-Evasion" + description: + type: mp4 + duration: 470 + - id: "metasploit_5_meterpreter_und_tokens" + title: "Meterpreter und Tokens" + description: + type: mp4 + duration: 667 + - id: "metasploit_admin_rechte_erzwingen" + title: "Admin Rechte erzwingen" + description: + type: mp4 + duration: 360 + - id: "metasploit_übers_internet" + title: "Metasploit Übers Internet" + description: + type: mp4 + duration: 483 + - id: section7 + title: "Post Exploitation" + description: + lectures: + - id: "metasploit_6_webcam_screenshot_und_keylogger" + title: "Webcam, Screenshot und Keylogger" + description: + type: mp4 + duration: 557 + - id: "metasploit_7_adminrechte_erhalten" + title: "Adminrechte erhalten" + description: + type: mp4 + duration: 321 + - id: "metasploit_8_sessions_die_windows_shell_und_eigene_skripte_ausführen" + title: "Sessions, die Windows Shell und eigene Skripte ausführen" + description: + type: mp4 + duration: 341 + - id: "metasploit_9_antivirenschutz_abschießen_und_automatisches_verbinden_bei_neustart" + title: "Antivirenschutz abschießen und Automatisches Verbinden bei Neustart" + description: + type: mp4 + duration: 442 + - id: section8 + title: "Reporting" + description: + lectures: [] diff --git a/academy_data/courses/php_fuer_anfaenger.yml b/academy_data/courses/php_fuer_anfaenger.yml new file mode 100644 index 00000000..aad0b962 --- /dev/null +++ b/academy_data/courses/php_fuer_anfaenger.yml @@ -0,0 +1,298 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7rZMP1lj32Qyp4bkarvzCGm +title: "PHP Programmierung" +description: "PHP, meine erste serverseitige Programmiersprache und vermutlich das, was ihr von alten Browsergames kennt. Mittlerweile nur noch in Wordpress und alten Websites... doch halt! Was ist das? Moderne Anwendungen, APIs, ja, das geht auch mit PHP und kommt gerade immer mehr!" +category: +language: de +image: https://static.bootstrap.academy/thumbnails/php.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665507563 +sections: + - id: section + title: "Grundlagen von PHP" + description: + lectures: + - id: "SW1fgMxj9a4" + title: "Installation" + description: + type: youtube + video_id: "SW1fgMxj9a4" + duration: 811 + - id: "uXNZTw2X2Uo" + title: "Variablen" + description: + type: youtube + video_id: "uXNZTw2X2Uo" + duration: 548 + - id: "BBH36wuYWNE" + title: "Datentypen" + description: + type: youtube + video_id: "BBH36wuYWNE" + duration: 212 + - id: "Wi6hzkPsHhE" + title: "Arithmetische Operatoren" + description: + type: youtube + video_id: "Wi6hzkPsHhE" + duration: 300 + - id: "I8gclpRQUhA" + title: "Logische Operatoren" + description: + type: youtube + video_id: "I8gclpRQUhA" + duration: 276 + - id: "KpBOBtcj-p8" + title: "if-Bedingungen" + description: + type: youtube + video_id: "KpBOBtcj-p8" + duration: 519 + - id: "qM7fybZ10Cc" + title: "Das switch-case-Statement" + description: + type: youtube + video_id: "qM7fybZ10Cc" + duration: 418 + - id: "YGkSgFD_a8I" + title: "while-Schleifen" + description: + type: youtube + video_id: "YGkSgFD_a8I" + duration: 347 + - id: "pZJBZsfhe4Y" + title: "Die Do-While-Schleife" + description: + type: youtube + video_id: "pZJBZsfhe4Y" + duration: 209 + - id: "fJRKomvlRq8" + title: "Arrays" + description: + type: youtube + video_id: "fJRKomvlRq8" + duration: 519 + - id: "cPEtayniHIs" + title: "Die Foreach-Schleife" + description: + type: youtube + video_id: "cPEtayniHIs" + duration: 174 + - id: "6y6g5SEh1g0" + title: "Assoziative Arrays" + description: + type: youtube + video_id: "6y6g5SEh1g0" + duration: 282 + - id: "XYoGuWCytN4" + title: "Strings" + description: + type: youtube + video_id: "XYoGuWCytN4" + duration: 542 + - id: "yEOY85tjRLY" + title: "Arrays Sortieren" + description: + type: youtube + video_id: "yEOY85tjRLY" + duration: 324 + - id: "HnKxQJjPp68" + title: "Loopcontrol mit Break und Continue" + description: + type: youtube + video_id: "HnKxQJjPp68" + duration: 267 + - id: "X4WRSRjerds" + title: "Kommentare, ===, die und exit" + description: + type: youtube + video_id: "X4WRSRjerds" + duration: 327 + - id: "m5xzlquvf0g" + title: "Funktionen" + description: + type: youtube + video_id: "m5xzlquvf0g" + duration: 422 + - id: "7QsOU0Gvb3U" + title: "Funktionen mit Parametern" + description: + type: youtube + video_id: "7QsOU0Gvb3U" + duration: 369 + - id: "Ebj2luXPPqw" + title: "Funktionen mit Defaultparametern und Rückgabewerten" + description: + type: youtube + video_id: "Ebj2luXPPqw" + duration: 445 + - id: "F19VwkwPW3A" + title: "Rekursive Funktionen" + description: + type: youtube + video_id: "F19VwkwPW3A" + duration: 649 + - id: section2 + title: "Web-spezifische Themen" + description: + lectures: + - id: "_ui0nclZK24" + title: "Forms auswerten" + description: + type: youtube + video_id: "_ui0nclZK24" + duration: 641 + - id: "CaQVfH7ei30" + title: "Form und $_SERVER" + description: + type: youtube + video_id: "CaQVfH7ei30" + duration: 437 + - id: "G9_owD5vBl4" + title: "Cross Site Scripting - Sicherheit von Forms" + description: + type: youtube + video_id: "G9_owD5vBl4" + duration: 560 + - id: "Rt8mCnIHdbM" + title: "Validierung von Forms" + description: + type: youtube + video_id: "Rt8mCnIHdbM" + duration: 402 + - id: section3 + title: "Datenbanken" + description: + lectures: + - id: "pdd1fnTcuzU" + title: "Eine MySQL Datenbank über phpmyadmin" + description: + type: youtube + video_id: "pdd1fnTcuzU" + duration: 634 + - id: "QBFlR-46aC0" + title: "auf die MySQL Datenbank verbinden" + description: + type: youtube + video_id: "QBFlR-46aC0" + duration: 440 + - id: "mklFZGBPUzI" + title: "SQL Statements in PHP" + description: + type: youtube + video_id: "mklFZGBPUzI" + duration: 727 + - id: "R9W3TCGW2Fk" + title: "SQL Injections und Gegenmaßnahmen" + description: + type: youtube + video_id: "R9W3TCGW2Fk" + duration: 697 + - id: section4 + title: "Tipps und Tricks" + description: + lectures: + - id: "Hz9AlK8Rt-M" + title: "Datum und Uhrzeit" + description: + type: youtube + video_id: "Hz9AlK8Rt-M" + duration: 449 + - id: "bR2Z3vEXT8c" + title: "Include und Require" + description: + type: youtube + video_id: "bR2Z3vEXT8c" + duration: 305 + - id: "Ov_rBQ0qMWo" + title: "File Uploads - Dateien auf den Server hochladen" + description: + type: youtube + video_id: "Ov_rBQ0qMWo" + duration: 820 + - id: "clE-f1NRNWU" + title: "Den File Upload überprüfen" + description: + type: youtube + video_id: "clE-f1NRNWU" + duration: 734 + - id: "Rz1muj_ACYQ" + title: "Dateien lesen und schreiben" + description: + type: youtube + video_id: "Rz1muj_ACYQ" + duration: 645 + - id: "MeeoG5W8lNE" + title: "Cookies" + description: + type: youtube + video_id: "MeeoG5W8lNE" + duration: 632 + - id: "-qRblIR14k0" + title: "Sessions" + description: + type: youtube + video_id: "-qRblIR14k0" + duration: 316 + - id: "1_24npIWaJ8" + title: "sicheres Speichern von Passwörtern" + description: + type: youtube + video_id: "1_24npIWaJ8" + duration: 308 + - id: "jWn6rR4y5uQ" + title: "wirklich sicheres Speichern mit salted Passwort Hashes" + description: + type: youtube + video_id: "jWn6rR4y5uQ" + duration: 538 + - id: section5 + title: "OOP in PHP" + description: + lectures: + - id: "iLghOcEFybE" + title: "Klassen" + description: + type: youtube + video_id: "iLghOcEFybE" + duration: 613 + - id: "xc3PtywceoY" + title: "Konstruktoren" + description: + type: youtube + video_id: "xc3PtywceoY" + duration: 211 + - id: "7JeDMo3JKi4" + title: "Vererbung" + description: + type: youtube + video_id: "7JeDMo3JKi4" + duration: 371 + - id: "P0Z2ri47Cx0" + title: "Funktionen überschreiben" + description: + type: youtube + video_id: "P0Z2ri47Cx0" + duration: 407 + - id: "W-eHyeK9eSI" + title: "Private, Public und Protected" + description: + type: youtube + video_id: "W-eHyeK9eSI" + duration: 634 + - id: "lKbClm76LKI" + title: "Interfaces, Abstrakte Klassen und Mehrfachvererbung" + description: + type: youtube + video_id: "lKbClm76LKI" + duration: 842 + - id: "vV-Hsebm9is" + title: "letzte Worte zu Klassen, final und parent constructor" + description: + type: youtube + video_id: "vV-Hsebm9is" + duration: 451 diff --git a/academy_data/courses/programmieren_lernen.yml b/academy_data/courses/programmieren_lernen.yml new file mode 100644 index 00000000..b5951e1f --- /dev/null +++ b/academy_data/courses/programmieren_lernen.yml @@ -0,0 +1,650 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7onyAB57T0xqV2ZVSZOo79a +title: "Gemeinsamkeiten von Programmiersprachen" +description: "Ihr lernt Java, Python, C++, .... wann ist endlich mal gut? Naja, vielleicht sind euch ja einige Gemeinsamkeiten aufgefallen? Diese Konzepte und Mechanismen besprechen wir in dieser Serie." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/progsprachen.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506634 +sections: + - id: section + title: "Grundlagen der Programmierung" + description: + lectures: + - id: "nVMlDghNcHg" + title: "Einleitung" + description: + type: youtube + video_id: "nVMlDghNcHg" + duration: 384 + - id: "l7M7jG-d7c4" + title: "Variablen und der Codefluss" + description: + type: youtube + video_id: "l7M7jG-d7c4" + duration: 602 + - id: "-UA65GBxEtI" + title: "Integer - Ganzzahlen" + description: + type: youtube + video_id: "-UA65GBxEtI" + duration: 669 + - id: "j2YhHdfgmko" + title: "Fließkommazahlen" + description: + type: youtube + video_id: "j2YhHdfgmko" + duration: 562 + - id: "oNpV4luYx2I" + title: "Buchstaben - Character" + description: + type: youtube + video_id: "oNpV4luYx2I" + duration: 274 + - id: "Z3IRchso41A" + title: "Kommentare" + description: + type: youtube + video_id: "Z3IRchso41A" + duration: 227 + - id: "yiXbAG2vrlg" + title: "Arrays" + description: + type: youtube + video_id: "yiXbAG2vrlg" + duration: 490 + - id: "vtyBWsyRU-o" + title: "Mehrdimensionale Arrays" + description: + type: youtube + video_id: "vtyBWsyRU-o" + duration: 528 + - id: "EgleYPhgUU4" + title: "Listen" + description: + type: youtube + video_id: "EgleYPhgUU4" + duration: 585 + - id: "Am0YUgyOybM" + title: "Strings" + description: + type: youtube + video_id: "Am0YUgyOybM" + duration: 568 + - id: "GEjfGiVCvfs" + title: "arithmetische Operatoren" + description: + type: youtube + video_id: "GEjfGiVCvfs" + duration: 647 + - id: "8EdMk4VKXdA" + title: "if - Verzweigungen" + description: + type: youtube + video_id: "8EdMk4VKXdA" + duration: 572 + - id: "vGS1u9Ioy-g" + title: "Booleans und Vergleichsoperatoren" + description: + type: youtube + video_id: "vGS1u9Ioy-g" + duration: 399 + - id: "UehOgM4D914" + title: "logische Operatoren" + description: + type: youtube + video_id: "UehOgM4D914" + duration: 540 + - id: "K0kgwBMGSjg" + title: "bitweise Operatoren" + description: + type: youtube + video_id: "K0kgwBMGSjg" + duration: 832 + - id: "PKHf-KQLp2s" + title: "while Schleifen" + description: + type: youtube + video_id: "PKHf-KQLp2s" + duration: 455 + - id: "BFuzKat5gL0" + title: "Die for-Schleife" + description: + type: youtube + video_id: "BFuzKat5gL0" + duration: 482 + - id: "JqKw80YDuVI" + title: "foreach Schleifen" + description: + type: youtube + video_id: "JqKw80YDuVI" + duration: 278 + - id: "DSO4ITu9nYI" + title: "break und continue" + description: + type: youtube + video_id: "DSO4ITu9nYI" + duration: 431 + - id: section2 + title: "Einführung in die funktionale Programmierung" + description: + lectures: + - id: "F1AGkBrQnXU" + title: "Funktionen" + description: + type: youtube + video_id: "F1AGkBrQnXU" + duration: 501 + - id: "KlSubMpETSg" + title: "Rückgabewerte" + description: + type: youtube + video_id: "KlSubMpETSg" + duration: 562 + - id: "M_s3j6oYMfc" + title: "Parameter" + description: + type: youtube + video_id: "M_s3j6oYMfc" + duration: 425 + - id: "4dut6s0E1vs" + title: "Rekursion" + description: + type: youtube + video_id: "4dut6s0E1vs" + duration: 589 + - id: "jL-2n9wkMfs" + title: "Default Argumente" + description: + type: youtube + video_id: "jL-2n9wkMfs" + duration: 249 + - id: "-_oHc7YtF54" + title: "Call-by-Value vs Call-by-Reference" + description: + type: youtube + video_id: "-_oHc7YtF54" + duration: 703 + - id: "XaFU2JHcWM4" + title: "Lazy Evaluation" + description: + type: youtube + video_id: "XaFU2JHcWM4" + duration: 398 + - id: "KcIlkkOcGwQ" + title: "Funktionen sind auch nur Variablen - Function Pointer" + description: + type: youtube + video_id: "KcIlkkOcGwQ" + duration: 365 + - id: "MZKVP6wNYuA" + title: "Lambda Funktionen" + description: + type: youtube + video_id: "MZKVP6wNYuA" + duration: 292 + - id: "jlvKo3eFKD4" + title: "Inline Funktionen" + description: + type: youtube + video_id: "jlvKo3eFKD4" + duration: 799 + - id: "dDKmkOjcaZE" + title: "Code lesen - wie wird's gemacht" + description: + type: youtube + video_id: "dDKmkOjcaZE" + duration: 1078 + - id: section3 + title: "Einführung in die objektorientierte Programmierung" + description: + lectures: + - id: "MIKUT5mvtcE" + title: "Klassen" + description: + type: youtube + video_id: "MIKUT5mvtcE" + duration: 610 + - id: "2oIXNBn-1ik" + title: "Methoden" + description: + type: youtube + video_id: "2oIXNBn-1ik" + duration: 411 + - id: "sZoyPJK6cB0" + title: "Konstruktoren" + description: + type: youtube + video_id: "sZoyPJK6cB0" + duration: 499 + - id: "mmLpVW5uToI" + title: "Zugriffsmodifikatoren" + description: + type: youtube + video_id: "mmLpVW5uToI" + duration: 605 + - id: "aO4leORLrek" + title: "Static - Klassenvariablen" + description: + type: youtube + video_id: "aO4leORLrek" + duration: 415 + - id: "gt3FV9YhTts" + title: "Vererbung" + description: + type: youtube + video_id: "gt3FV9YhTts" + duration: 494 + - id: "2TA-Gcs5XFs" + title: "TypeCasts" + description: + type: youtube + video_id: "2TA-Gcs5XFs" + duration: 543 + - id: "3k3Pq3pJlHo" + title: "instanceof und typeof" + description: + type: youtube + video_id: "3k3Pq3pJlHo" + duration: 268 + - id: "gDXHBqRJ3lM" + title: "Überschreiben von Methoden" + description: + type: youtube + video_id: "gDXHBqRJ3lM" + duration: 329 + - id: section4 + title: "Fortgeschrittene Objektorientierung" + description: + lectures: + - id: "Rcnai3U0RcE" + title: "Enums" + description: + type: youtube + video_id: "Rcnai3U0RcE" + duration: 227 + - id: "pqwBUimLMYY" + title: "Operatoren überschreiben" + description: + type: youtube + video_id: "pqwBUimLMYY" + duration: 376 + - id: "Ktfjm9caHxc" + title: "Super" + description: + type: youtube + video_id: "Ktfjm9caHxc" + duration: 351 + - id: "nj7YcDQvTHU" + title: "Interfaces" + description: + type: youtube + video_id: "nj7YcDQvTHU" + duration: 447 + - id: "pnyTVFITVoY" + title: "Mehrfachvererbung und das Diamantenproblem" + description: + type: youtube + video_id: "pnyTVFITVoY" + duration: 424 + - id: "ofkuSg6dUf4" + title: "Abstrakte Klassen" + description: + type: youtube + video_id: "ofkuSg6dUf4" + duration: 298 + - id: "8UKrmsB4DiY" + title: "Der Zugriffsmodifikator protected" + description: + type: youtube + video_id: "8UKrmsB4DiY" + duration: 195 + - id: "Pmz_M92miP8" + title: "statische innere Klassen" + description: + type: youtube + video_id: "Pmz_M92miP8" + duration: 478 + - id: "b3V73ya2FS0" + title: "innere Klassen" + description: + type: youtube + video_id: "b3V73ya2FS0" + duration: 359 + - id: "VET4R9hd5ks" + title: "anonyme innere Klassen" + description: + type: youtube + video_id: "VET4R9hd5ks" + duration: 257 + - id: "Da2J0exYRN0" + title: "Module" + description: + type: youtube + video_id: "Da2J0exYRN0" + duration: 417 + - id: "zDxv2kI575Q" + title: "Dynamic vs Static Scoping" + description: + type: youtube + video_id: "zDxv2kI575Q" + duration: 460 + - id: "TWcosPyPfrY" + title: "Mixins" + description: + type: youtube + video_id: "TWcosPyPfrY" + duration: 301 + - id: section5 + title: "Generische Objektorientierung" + description: + lectures: + - id: "Bfr0-t7lXVs" + title: "Generics" + description: + type: youtube + video_id: "Bfr0-t7lXVs" + duration: 516 + - id: "w43Mhmr1_ec" + title: "generische Funktionen" + description: + type: youtube + video_id: "w43Mhmr1_ec" + duration: 575 + - id: "tcj7g_Q9Wnc" + title: "Typschranken" + description: + type: youtube + video_id: "tcj7g_Q9Wnc" + duration: 304 + - id: section6 + title: "Parallelität" + description: + lectures: + - id: "d50Nir52aS8" + title: "Prozesse vs Threads" + description: + type: youtube + video_id: "d50Nir52aS8" + duration: 702 + - id: "OzyV_tTlcZg" + title: "Threads erstellen" + description: + type: youtube + video_id: "OzyV_tTlcZg" + duration: 461 + - id: "5AYVw_YokEI" + title: "Nebenläufigkeit von Threads" + description: + type: youtube + video_id: "5AYVw_YokEI" + duration: 328 + - id: "8aNB2O9BtRU" + title: "Atomare Operationen" + description: + type: youtube + video_id: "8aNB2O9BtRU" + duration: 334 + - id: "AdzCb97qqRY" + title: "synchronized und locks" + description: + type: youtube + video_id: "AdzCb97qqRY" + duration: 451 + - id: "p2OEUX8tzLE" + title: "Semaphoren" + description: + type: youtube + video_id: "p2OEUX8tzLE" + duration: 154 + - id: "uy5X4iXFLD0" + title: "Deadlocks" + description: + type: youtube + video_id: "uy5X4iXFLD0" + duration: 414 + - id: "l-OOim0p3bE" + title: "Concurrent Programming Languages" + description: + type: youtube + video_id: "l-OOim0p3bE" + duration: 374 + - id: "ThAU874F3cs" + title: "Actors und Message Passing" + description: + type: youtube + video_id: "ThAU874F3cs" + duration: 349 + - id: "fjlotlmfH7U" + title: "Events" + description: + type: youtube + video_id: "fjlotlmfH7U" + duration: 322 + - id: "z6DQQhlQrI0" + title: "Event Driven Development" + description: + type: youtube + video_id: "z6DQQhlQrI0" + duration: 401 + - id: section7 + title: "Debugging" + description: + lectures: + - id: "t65-68pBfRA" + title: "Debugging und Breakpoints" + description: + type: youtube + video_id: "t65-68pBfRA" + duration: 594 + - id: "RhNBE6o7tJU" + title: "Testen" + description: + type: youtube + video_id: "RhNBE6o7tJU" + duration: 867 + - id: "f231K1LjKMU" + title: "Exceptions" + description: + type: youtube + video_id: "f231K1LjKMU" + duration: 599 + - id: "cL8xtQ1_6HU" + title: "eigene Exceptions" + description: + type: youtube + video_id: "cL8xtQ1_6HU" + duration: 484 + - id: section8 + title: "Best Practice" + description: + lectures: + - id: "EZ1atCGFhjw" + title: "RegEx - Reguläre Ausdrücke" + description: + type: youtube + video_id: "EZ1atCGFhjw" + duration: 761 + - id: "kubXOU01Ws8" + title: "Vektoren" + description: + type: youtube + video_id: "kubXOU01Ws8" + duration: 482 + - id: "_LF3yUium9o" + title: "Zufall" + description: + type: youtube + video_id: "_LF3yUium9o" + duration: 524 + - id: "TrOk3FNv-8c" + title: "Dateien" + description: + type: youtube + video_id: "TrOk3FNv-8c" + duration: 716 + - id: "RMS9WGEpBzI" + title: "Dateien - Modi" + description: + type: youtube + video_id: "RMS9WGEpBzI" + duration: 498 + - id: "pjGctthnDXI" + title: "Ascii und Unicode" + description: + type: youtube + video_id: "pjGctthnDXI" + duration: 487 + - id: "-_OEWwkJNqQ" + title: "Binäre Dateien" + description: + type: youtube + video_id: "-_OEWwkJNqQ" + duration: 299 + - id: "RM4oMOuzkEA" + title: "Objekt Serialisierung" + description: + type: youtube + video_id: "RM4oMOuzkEA" + duration: 337 + - id: "GRKkyF6Bkok" + title: "XML und JSON" + description: + type: youtube + video_id: "GRKkyF6Bkok" + duration: 627 + - id: "ED4nCctxfDo" + title: "Flushing" + description: + type: youtube + video_id: "ED4nCctxfDo" + duration: 287 + - id: "9H5INP4TNj8" + title: "Absolute und Relative Pfade" + description: + type: youtube + video_id: "9H5INP4TNj8" + duration: 578 + - id: "pHMHbI4cI6o" + title: "Logging" + description: + type: youtube + video_id: "pHMHbI4cI6o" + duration: 448 + - id: "e73Bxm4HsAs" + title: "Datum und Uhrzeit" + description: + type: youtube + video_id: "e73Bxm4HsAs" + duration: 857 + - id: "RFT1ioXYm-U" + title: "Networking" + description: + type: youtube + video_id: "RFT1ioXYm-U" + duration: 734 + - id: "Dcf0Ag49c38" + title: "Datenbanken" + description: + type: youtube + video_id: "Dcf0Ag49c38" + duration: 892 + - id: section9 + title: "Fortgeschrittene Funktionale Programmierung" + description: + lectures: + - id: "39GU7sZZrZA" + title: "Inferierte Typen" + description: + type: youtube + video_id: "39GU7sZZrZA" + duration: 226 + - id: "4NCeP9yclZM" + title: "Typinferenz von Funktionen" + description: + type: youtube + video_id: "4NCeP9yclZM" + duration: 461 + - id: "dUKIbPcXuyU" + title: "Funktionen höherer Ordnung und Currying" + description: + type: youtube + video_id: "dUKIbPcXuyU" + duration: 564 + - id: "eDOF0B6H2G4" + title: "Pattern Matching mit Listen" + description: + type: youtube + video_id: "eDOF0B6H2G4" + duration: 323 + - id: "1VIM4rml9BA" + title: "Wildcards im Pattern Matching" + description: + type: youtube + video_id: "1VIM4rml9BA" + duration: 167 + - id: "HoSWY0uK7to" + title: "Pattern Guards" + description: + type: youtube + video_id: "HoSWY0uK7to" + duration: 148 + - id: "bxsCzFHZrow" + title: "Case Classes" + description: + type: youtube + video_id: "bxsCzFHZrow" + duration: 277 + - id: "u5YWnmcTsn0" + title: "Map" + description: + type: youtube + video_id: "u5YWnmcTsn0" + duration: 332 + - id: "nVE68kbRypA" + title: "Zip" + description: + type: youtube + video_id: "nVE68kbRypA" + duration: 321 + - id: "M9-Scj76TTw" + title: "Unzip" + description: + type: youtube + video_id: "M9-Scj76TTw" + duration: 127 + - id: "eGhe755ryK8" + title: "Filter" + description: + type: youtube + video_id: "eGhe755ryK8" + duration: 246 + - id: "r6rRP5q1fTU" + title: "Reduce" + description: + type: youtube + video_id: "r6rRP5q1fTU" + duration: 520 + - id: "sdlQOyvKde8" + title: "Generatoren" + description: + type: youtube + video_id: "sdlQOyvKde8" + duration: 342 + - id: "ZRJ5BaSBQ8Q" + title: "Dekoratoren" + description: + type: youtube + video_id: "ZRJ5BaSBQ8Q" + duration: 363 + - id: "VobBC97dXcI" + title: "List Comprehensions" + description: + type: youtube + video_id: "VobBC97dXcI" + duration: 418 diff --git a/academy_data/courses/prolog.yml b/academy_data/courses/prolog.yml new file mode 100644 index 00000000..ead6ab05 --- /dev/null +++ b/academy_data/courses/prolog.yml @@ -0,0 +1,60 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7q7ODiEAnq2EnsP-8LMGtfw +title: "Prolog: Logische Programmierung" +description: "Habt ihr jemals von logischer Programmierung gehört? Prolog verfolgt ein grundlegend anderes Konzept als Python oder auch Haskell. Und so etwas ist immer spannend!" +category: +language: de +image: https://static.bootstrap.academy/thumbnails/prolog.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506685 +sections: + - id: section + title: "Prolog Programmierung" + description: + lectures: + - id: "8iUYNp5Z45o" + title: "Einführung" + description: + type: youtube + video_id: "8iUYNp5Z45o" + duration: 485 + - id: "9bCzsE-LamI" + title: "Regeln" + description: + type: youtube + video_id: "9bCzsE-LamI" + duration: 569 + - id: "hpQYxISZC74" + title: "Die Großeltern von Robb Stark" + description: + type: youtube + video_id: "hpQYxISZC74" + duration: 723 + - id: "DZeeXgOEjzs" + title: "Listen" + description: + type: youtube + video_id: "DZeeXgOEjzs" + duration: 772 + - id: "gyPChcbuok8" + title: "Zuweisungen" + description: + type: youtube + video_id: "gyPChcbuok8" + duration: 426 + - id: "tRYRwmkH9bA" + title: "Cuts" + description: + type: youtube + video_id: "tRYRwmkH9bA" + duration: 516 + - id: "-TxFZmCq_no" + title: "Send + More = Money" + description: + type: youtube + video_id: "-TxFZmCq_no" + duration: 770 diff --git a/academy_data/courses/python.yml b/academy_data/courses/python.yml new file mode 100644 index 00000000..427446a4 --- /dev/null +++ b/academy_data/courses/python.yml @@ -0,0 +1,550 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7q0ao69AIogD94oBgp3E9Zs +title: "Python Programmierung" +description: "Muss ich hierzu wirklich was sagen? Python - verwendet für APIs (auch bei dieser Website übrigens), Pentesting, Serveradministration, KI oder auch einfach normale Programme, die euch das Leben erleichtern. Python ist anfängerfreundlich, aber es gibt unfassbar viele Tricks, die die wenigsten Experten kennen. Und dann gibt's da noch die größte mögliche Anzahl an Bibliotheken für jeden Anwendungszweck! Python ist ein absolutes Must-Have." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/python.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506871 +sections: + - id: section + title: "Python Grundlagen" + description: + lectures: + - id: "DiidEp6DqCo" + title: "Einleitung, Installation, Scripte ausführen und PyCharm" + description: + type: youtube + video_id: "DiidEp6DqCo" + duration: 1245 + - id: "dyJdLalc7TA" + title: "Für Nostalgiegründe: Einleitung und Installation - die alte Version" + description: + type: youtube + video_id: "dyJdLalc7TA" + duration: 269 + - id: "mNcexeCI-G4" + title: "Zahlen" + description: + type: youtube + video_id: "mNcexeCI-G4" + duration: 509 + - id: "BiVQJ4dTD9o" + title: "Strings" + description: + type: youtube + video_id: "BiVQJ4dTD9o" + duration: 523 + - id: "3ykwB-M2-mg" + title: "Listen" + description: + type: youtube + video_id: "3ykwB-M2-mg" + duration: 487 + - id: "3eV-iDePwG4" + title: "Strings als Listen" + description: + type: youtube + video_id: "3eV-iDePwG4" + duration: 761 + - id: "blFbmXYl_iA" + title: "Das erste echte Script" + description: + type: youtube + video_id: "blFbmXYl_iA" + duration: 201 + - id: "MDxgzWCV3oM" + title: "Die if-Abfrage" + description: + type: youtube + video_id: "MDxgzWCV3oM" + duration: 672 + - id: "5FNVcHUjYCM" + title: "Die while-Schleife" + description: + type: youtube + video_id: "5FNVcHUjYCM" + duration: 313 + - id: "jZxa1IKAgOo" + title: "Die for-Schleife" + description: + type: youtube + video_id: "jZxa1IKAgOo" + duration: 569 + - id: "cKpPvhnxfCY" + title: "die range-Funktion" + description: + type: youtube + video_id: "cKpPvhnxfCY" + duration: 451 + - id: "PhipXSUFXOg" + title: "Break & Continue" + description: + type: youtube + video_id: "PhipXSUFXOg" + duration: 266 + - id: "mgA-Ytr32Ys" + title: "Funktionen" + description: + type: youtube + video_id: "mgA-Ytr32Ys" + duration: 366 + - id: "qLRY2zGXovc" + title: "Rückgabewerte und Rekursion" + description: + type: youtube + video_id: "qLRY2zGXovc" + duration: 469 + - id: "ct2olB0GyLQ" + title: "Default Werte für Funktionsargumente" + description: + type: youtube + video_id: "ct2olB0GyLQ" + duration: 657 + - id: "AagRwg6WZE0" + title: "Module" + description: + type: youtube + video_id: "AagRwg6WZE0" + duration: 382 + - id: "bNk14P3vsRk" + title: "Main" + description: + type: youtube + video_id: "bNk14P3vsRk" + duration: 351 + - id: "xTwGWLijyX8" + title: "User Input" + description: + type: youtube + video_id: "xTwGWLijyX8" + duration: 512 + - id: "EMETm7hRonM" + title: "Dateien lesen" + description: + type: youtube + video_id: "EMETm7hRonM" + duration: 576 + - id: "2A3ZDOUsrOg" + title: "Dateien schreiben" + description: + type: youtube + video_id: "2A3ZDOUsrOg" + duration: 479 + - id: "zGGGwzexDfM" + title: "Gültigkeitsbereich von Variablen" + description: + type: youtube + video_id: "zGGGwzexDfM" + duration: 773 + - id: section2 + title: "Objektorientierung" + description: + lectures: + - id: "ce5Ks2xAXo4" + title: "Klassen" + description: + type: youtube + video_id: "ce5Ks2xAXo4" + duration: 684 + - id: "fKjwwXoyUOw" + title: "Konstruktoren" + description: + type: youtube + video_id: "fKjwwXoyUOw" + duration: 296 + - id: "sKSsAhiaqQ8" + title: "Instanz- und Klassenvariablen" + description: + type: youtube + video_id: "sKSsAhiaqQ8" + duration: 418 + - id: "EdSCvzXwzw4" + title: "Übung - Tic Tac Toe" + description: + type: youtube + video_id: "EdSCvzXwzw4" + duration: 2101 + - id: "1FMCzUPaHzQ" + title: "Vererbung" + description: + type: youtube + video_id: "1FMCzUPaHzQ" + duration: 522 + - id: "3AgG7eTLJGM" + title: "Überschreibung von Attributen und Methoden" + description: + type: youtube + video_id: "3AgG7eTLJGM" + duration: 468 + - id: "1w40nctG2Qg" + title: "Mehrfachvererbung" + description: + type: youtube + video_id: "1w40nctG2Qg" + duration: 592 + - id: section3 + title: "Extras 1" + description: + lectures: + - id: "9A3GtZxB4ug" + title: "Exceptions" + description: + type: youtube + video_id: "9A3GtZxB4ug" + duration: 741 + - id: "GPXEVsOxZVw" + title: "Übung - Temperaturen umrechnen" + description: + type: youtube + video_id: "GPXEVsOxZVw" + duration: 801 + - id: "KLQvQLU5bvI" + title: "Übung - Ein Textadventure" + description: + type: youtube + video_id: "KLQvQLU5bvI" + duration: 3102 + - id: section4 + title: "Multithreading" + description: + lectures: + - id: "_ynNrBP2lWA" + title: "Multithreading" + description: + type: youtube + video_id: "_ynNrBP2lWA" + duration: 666 + - id: "fS6jcEKNiSg" + title: "Locks" + description: + type: youtube + video_id: "fS6jcEKNiSg" + duration: 590 + - id: "lqjWl13-Huw" + title: "Kommunikation zwischen Threads" + description: + type: youtube + video_id: "lqjWl13-Huw" + duration: 528 + - id: "BjalncvFfYs" + title: "Multiprocessing vs Multithreading" + description: + type: youtube + video_id: "BjalncvFfYs" + duration: 489 + - id: "Tu0KbXWr5uA" + title: "Multiprocessing" + description: + type: youtube + video_id: "Tu0KbXWr5uA" + duration: 1062 + - id: "4sEsHa6S58M" + title: "Multiprocessing vs Multithreading Performance Benchmark" + description: + type: youtube + video_id: "4sEsHa6S58M" + duration: 617 + - id: section5 + title: "Funktionales Python" + description: + lectures: + - id: "nlQlajr5Dt8" + title: "partielle Funktionen" + description: + type: youtube + video_id: "nlQlajr5Dt8" + duration: 282 + - id: "_5e0CBcXTZo" + title: "Lambda und Map" + description: + type: youtube + video_id: "_5e0CBcXTZo" + duration: 446 + - id: "5qQ5EKeO9bo" + title: "Filtern einer Liste" + description: + type: youtube + video_id: "5qQ5EKeO9bo" + duration: 232 + - id: section6 + title: "Fortgeschrittene Tipps und Tricks" + description: + lectures: + - id: "F1ODsSWi9nk" + title: "Logging" + description: + type: youtube + video_id: "F1ODsSWi9nk" + duration: 1052 + - id: "jUcQGAvtSCc" + title: "Vokabeltrainer" + description: + type: youtube + video_id: "jUcQGAvtSCc" + duration: 1191 + - id: "kwmrJDSxBXw" + title: "Turtle Grafiken" + description: + type: youtube + video_id: "kwmrJDSxBXw" + duration: 422 + - id: "KUSeRnQT7TE" + title: "PyCharm" + description: + type: youtube + video_id: "KUSeRnQT7TE" + duration: 1135 + - id: "GGkXzHawnCc" + title: "Abstrakte Klassen" + description: + type: youtube + video_id: "GGkXzHawnCc" + duration: 518 + - id: "58lV5lLnuCI" + title: "Enums" + description: + type: youtube + video_id: "58lV5lLnuCI" + duration: 203 + - id: "H44_Ztv-9N8" + title: "Operatoren überladen" + description: + type: youtube + video_id: "H44_Ztv-9N8" + duration: 359 + - id: "QHtYAMkmS1Y" + title: "Regex" + description: + type: youtube + video_id: "QHtYAMkmS1Y" + duration: 784 + - id: "nWOoky0PTVY" + title: "Py2Exe: Python-Programme als Ausführbare Datei" + description: + type: youtube + video_id: "nWOoky0PTVY" + duration: 273 + - id: "m1QG2YuO3gc" + title: "Generatoren und Yield" + description: + type: youtube + video_id: "m1QG2YuO3gc" + duration: 886 + - id: "C7bVzLauLEg" + title: "Argument Unpacking, Tupel und Dictionaries" + description: + type: youtube + video_id: "C7bVzLauLEg" + duration: 623 + - id: "T7oF-ywGxk4" + title: "Dekoratoren" + description: + type: youtube + video_id: "T7oF-ywGxk4" + duration: 371 + - id: "2jHuDKB_veg" + title: "Staticmethod und Classmethod" + description: + type: youtube + video_id: "2jHuDKB_veg" + duration: 824 + - id: "RkYaszX2q_8" + title: "else an komischen Orten" + description: + type: youtube + video_id: "RkYaszX2q_8" + duration: 394 + - id: "db3r3k0B5Es" + title: "Versteckte Features" + description: + type: youtube + video_id: "db3r3k0B5Es" + duration: 596 + - id: "ytOytMdqD7Y" + title: "Funktionsklassen" + description: + type: youtube + video_id: "ytOytMdqD7Y" + duration: 193 + - id: "vy0AuHleY_k" + title: "Gleichheitsoperatoren überladen" + description: + type: youtube + video_id: "vy0AuHleY_k" + duration: 482 + - id: "xSaabBunOto" + title: "Konversions-Magic-Methods" + description: + type: youtube + video_id: "xSaabBunOto" + duration: 476 + - id: "nKwVn0k1krQ" + title: "Sockets" + description: + type: youtube + video_id: "nKwVn0k1krQ" + duration: 1409 + - id: "c5uj8M3fOa4" + title: "Zeit und Datum" + description: + type: youtube + video_id: "c5uj8M3fOa4" + duration: 535 + - id: "drord9gbr3Y" + title: "Json" + description: + type: youtube + video_id: "drord9gbr3Y" + duration: 561 + - id: "Fl6lBCZecdU" + title: "Json und Online APIs" + description: + type: youtube + video_id: "Fl6lBCZecdU" + duration: 295 + - id: "AaRlQ8KuFak" + title: "Den Webbrowser ansprechen" + description: + type: youtube + video_id: "AaRlQ8KuFak" + duration: 224 + - id: "FVfhKgSfsfc" + title: "Hashing" + description: + type: youtube + video_id: "FVfhKgSfsfc" + duration: 563 + - id: "cPC0DCpFKJY" + title: "HMAC" + description: + type: youtube + video_id: "cPC0DCpFKJY" + duration: 305 + - id: "wo6A5IiPEQI" + title: "Kommandozeilenargumente einfach auslesen" + description: + type: youtube + video_id: "wo6A5IiPEQI" + duration: 397 + - id: "wFj58Li_JhI" + title: "Python Programme als Ausführbare Dateien mit PyInstaller" + description: + type: youtube + video_id: "wFj58Li_JhI" + duration: 351 + - id: "vngpiMFHICM" + title: "Requirements eines Python Projektes automatisch erstellen" + description: + type: youtube + video_id: "vngpiMFHICM" + duration: 263 + - id: "KYu4bts4dPI" + title: "Multithreading Queues" + description: + type: youtube + video_id: "KYu4bts4dPI" + duration: 1036 + - id: "c6k-UWkT_Og" + title: "Typen angeben" + description: + type: youtube + video_id: "c6k-UWkT_Og" + duration: 515 + - id: "AXfNKyuutCs" + title: "Dataclasses" + description: + type: youtube + video_id: "AXfNKyuutCs" + duration: 937 + - id: "PmEM4IODkZk" + title: "Subprocess - auf die Commandline zugreifen" + description: + type: youtube + video_id: "PmEM4IODkZk" + duration: 454 + - id: section7 + title: "AsyncIO" + description: + lectures: + - id: "HzpdMDYEstA" + title: "Einführung" + description: + type: youtube + video_id: "HzpdMDYEstA" + duration: 649 + - id: "f_oyk1GpOJg" + title: "Queues und Tasks" + description: + type: youtube + video_id: "f_oyk1GpOJg" + duration: 1011 + - id: "LYTiaSXso_4" + title: "Events" + description: + type: youtube + video_id: "LYTiaSXso_4" + duration: 331 + - id: section8 + title: "Noch mehr fortgeschrittene Themen" + description: + lectures: + - id: "OwUVlPvXwrI" + title: "assert" + description: + type: youtube + video_id: "OwUVlPvXwrI" + duration: 437 + - id: "-v_wzrAXVm0" + title: "Der Walrus Operator / Assignment Expressions" + description: + type: youtube + video_id: "-v_wzrAXVm0" + duration: 563 + - id: "xzju0BCRoEI" + title: "Format Strings" + description: + type: youtube + video_id: "xzju0BCRoEI" + duration: 294 + - id: "rSFFVI5_LB4" + title: "Update Operator für Dictionaries, PEG Parser und Type Hinting für Listen" + description: + type: youtube + video_id: "rSFFVI5_LB4" + duration: 573 + - id: "WI3oSdDR1Vs" + title: "Debugging in Python mit PyCharm" + description: + type: youtube + video_id: "WI3oSdDR1Vs" + duration: 721 + - id: "ytKrvEwCvnU" + title: "Bessere Fehlermeldungen, Union Types, Bessere Kontextmanager" + description: + type: youtube + video_id: "ytKrvEwCvnU" + duration: 603 + - id: "so1kKz74R3Q" + title: "Pattern Matching" + description: + type: youtube + video_id: "so1kKz74R3Q" + duration: 1546 + - id: "spQquhX4sxM" + title: "PyPerformance: Performance messen von Python" + description: + type: youtube + video_id: "spQquhX4sxM" + duration: 821 + - id: "Yj2hqZY5gfA" + title: "ExceptionGroups, Except* und Fehlermeldungen" + description: + type: youtube + video_id: "Yj2hqZY5gfA" + duration: 1332 diff --git a/academy_data/courses/python_data_science.yml b/academy_data/courses/python_data_science.yml new file mode 100644 index 00000000..1cc5647f --- /dev/null +++ b/academy_data/courses/python_data_science.yml @@ -0,0 +1,282 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7o46LI06XkxAqcg4Ucm7pwn +title: "Data Science in Python" +description: "Data Science, also wie genau gehe ich eigentlich mit meinen Daten um, ist in vielen Fällen einfach harte Programmierung. Und weil die beliebtesten Bibliotheken für die Sprache Python verfügbar sind, meist in Python. In diesem Kurs geht's um diese beliebtesten Bibliotheken!" +category: +language: de +image: https://static.bootstrap.academy/thumbnails/python.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665507403 +sections: + - id: section + title: "Einleitung" + description: + lectures: + - id: "EW0rpuPoRNA" + title: "Einleitung" + description: + type: youtube + video_id: "EW0rpuPoRNA" + duration: 686 + - id: section2 + title: "Numpy" + description: + lectures: + - id: "XamW67vUJ-Q" + title: "Arrays erstellen" + description: + type: youtube + video_id: "XamW67vUJ-Q" + duration: 800 + - id: "0tNt4Lu7EZg" + title: "Numpy Arrays vs Python Lists" + description: + type: youtube + video_id: "0tNt4Lu7EZg" + duration: 927 + - id: "mQ_P06Z7e5Y" + title: "Datentypen" + description: + type: youtube + video_id: "mQ_P06Z7e5Y" + duration: 1081 + - id: "RWWjSm5F8uM" + title: "Shape erklärt" + description: + type: youtube + video_id: "RWWjSm5F8uM" + duration: 693 + - id: "bWl4I-kYpio" + title: "Shapes in komplexen Dtypes" + description: + type: youtube + video_id: "bWl4I-kYpio" + duration: 906 + - id: "OTrslIWEf54" + title: "benannte DTypes" + description: + type: youtube + video_id: "OTrslIWEf54" + duration: 979 + - id: "kxpGn6DQVB4" + title: "Slicen und Indexierung" + description: + type: youtube + video_id: "kxpGn6DQVB4" + duration: 848 + - id: "cccNKHvzofw" + title: "Operationen mit Vektoren und Matrizen" + description: + type: youtube + video_id: "cccNKHvzofw" + duration: 1183 + - id: "ZQj8qY6e5uw" + title: "Ravel und Flatten" + description: + type: youtube + video_id: "ZQj8qY6e5uw" + duration: 583 + - id: "bjfmlHghW34" + title: "Reshape" + description: + type: youtube + video_id: "bjfmlHghW34" + duration: 436 + - id: "UMYbeltcyA8" + title: "Stacks, Tiles, Konkatenation und Padding" + description: + type: youtube + video_id: "UMYbeltcyA8" + duration: 639 + - id: "btA5mOXcQYs" + title: "Zufall in Numpy" + description: + type: youtube + video_id: "btA5mOXcQYs" + duration: 333 + - id: "l6Z2Fhxp6ZE" + title: "Dateien laden und speichern" + description: + type: youtube + video_id: "l6Z2Fhxp6ZE" + duration: 656 + - id: "pv3KvUMRZKs" + title: "Mehr Möglichkeiten Arrays zu erstellen" + description: + type: youtube + video_id: "pv3KvUMRZKs" + duration: 490 + - id: "7gWWxAJv_fA" + title: "Fancy Operationen" + description: + type: youtube + video_id: "7gWWxAJv_fA" + duration: 959 + - id: section3 + title: "Pandas" + description: + lectures: + - id: "Uu1Skwz98B4" + title: "DataFrames" + description: + type: youtube + video_id: "Uu1Skwz98B4" + duration: 557 + - id: "tSSMQdNtz38" + title: "Series" + description: + type: youtube + video_id: "tSSMQdNtz38" + duration: 907 + - id: "yRSV-wLWhSw" + title: "Multiindexierte und normale DataFrames erstellen" + description: + type: youtube + video_id: "yRSV-wLWhSw" + duration: 1341 + - id: "u0kBG9rMHjI" + title: "Operationen und Indexierung von DataFrames" + description: + type: youtube + video_id: "u0kBG9rMHjI" + duration: 966 + - id: "SAdh1JnOBYQ" + title: "Mehr wichtige Operationen auf DataFrames" + description: + type: youtube + video_id: "SAdh1JnOBYQ" + duration: 1027 + - id: "lttSd1sBzq0" + title: "Einfache Statistik" + description: + type: youtube + video_id: "lttSd1sBzq0" + duration: 639 + - id: "4rjNHNrr6_U" + title: "Reindex vs Zuweisen von Columns" + description: + type: youtube + video_id: "4rjNHNrr6_U" + duration: 544 + - id: "RuQxtM99IK4" + title: "Fortgeschrittene Indexierung" + description: + type: youtube + video_id: "RuQxtM99IK4" + duration: 976 + - id: "wNnVHNZfyqA" + title: "Iterieren über Dataframes" + description: + type: youtube + video_id: "wNnVHNZfyqA" + duration: 816 + - id: "mQVq-pzd5Tg" + title: "Diskretisierung und Histogramme erstellen bei Floats" + description: + type: youtube + video_id: "mQVq-pzd5Tg" + duration: 616 + - id: "HaLpJgaGBTE" + title: "Mehr zu Kategorien" + description: + type: youtube + video_id: "HaLpJgaGBTE" + duration: 1122 + - id: "2JsAlrBDmUE" + title: "Konkatenieren von DataFrames" + description: + type: youtube + video_id: "2JsAlrBDmUE" + duration: 837 + - id: "4iua5KvH8YA" + title: "Merge bei DataFrames" + description: + type: youtube + video_id: "4iua5KvH8YA" + duration: 1078 + - id: "118j186E5JI" + title: "Gruppieren" + description: + type: youtube + video_id: "118j186E5JI" + duration: 869 + - id: "o7iiox_xsko" + title: "Pivottables erstellen" + description: + type: youtube + video_id: "o7iiox_xsko" + duration: 438 + - id: "Hz4t7K9NaCw" + title: "Stacking und Unstacking" + description: + type: youtube + video_id: "Hz4t7K9NaCw" + duration: 653 + - id: "rfmiu5NKFjI" + title: "DateTime" + description: + type: youtube + video_id: "rfmiu5NKFjI" + duration: 828 + - id: "fyi83xMSLjw" + title: "Datum und Uhrzeit als Index" + description: + type: youtube + video_id: "fyi83xMSLjw" + duration: 934 + - id: "NyJdW0Pyj2E" + title: "TimeDeltas" + description: + type: youtube + video_id: "NyJdW0Pyj2E" + duration: 437 + - id: "_VZQIIz5ofQ" + title: "CSV Dateien lesen und schreiben" + description: + type: youtube + video_id: "_VZQIIz5ofQ" + duration: 841 + - id: "nzWBDfqe4ng" + title: "SQLalchemy nutzen, um in Datenbanken zu schreiben" + description: + type: youtube + video_id: "nzWBDfqe4ng" + duration: 619 + - id: "Mb-fuYgEaFM" + title: "SQLalchemy: aus Datenbanken lesen" + description: + type: youtube + video_id: "Mb-fuYgEaFM" + duration: 303 + - id: "iaYBUkl2u3U" + title: "Performance von loc, iloc, iat und at" + description: + type: youtube + video_id: "iaYBUkl2u3U" + duration: 538 + - id: "_a87bkOZ3Jg" + title: "SQLAlchemy nutzen für Datum und Uhrzeit" + description: + type: youtube + video_id: "_a87bkOZ3Jg" + duration: 357 + - id: "op42i9oheSI" + title: "SQLalchemy: Datum in Unix Timestamp konvertieren" + description: + type: youtube + video_id: "op42i9oheSI" + duration: 475 + - id: section4 + title: "Bonus" + description: + lectures: + - id: "JX0cHWUBkUQ" + title: "Nutzt keine CSV-Dateien, sondern Feathers!" + description: + type: youtube + video_id: "JX0cHWUBkUQ" + duration: 777 diff --git a/academy_data/courses/python_flask.yml b/academy_data/courses/python_flask.yml new file mode 100644 index 00000000..b619935e --- /dev/null +++ b/academy_data/courses/python_flask.yml @@ -0,0 +1,254 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7otfP2zTa8AIiNIWVg0BRqs +title: "APIs programmieren mit Python Flask" +description: "Ihr wollt eine API in Python entwickeln. Flask könnte euch gefallen!" +category: +language: de +image: https://static.bootstrap.academy/thumbnails/python.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665507927 +sections: + - id: section + title: "APIs programmieren mit Python Flask" + description: + lectures: + - id: "EGYpNQ3GL1Y" + title: "Flask vs. Django" + description: + type: youtube + video_id: "EGYpNQ3GL1Y" + duration: 336 + - id: "I0KSJKHuHe4" + title: "Installation" + description: + type: youtube + video_id: "I0KSJKHuHe4" + duration: 374 + - id: "EMcTreG8N3g" + title: "Routing" + description: + type: youtube + video_id: "EMcTreG8N3g" + duration: 217 + - id: "x0iLkYsoWTU" + title: "Variable Routen" + description: + type: youtube + video_id: "x0iLkYsoWTU" + duration: 461 + - id: "kKixgYl_eIM" + title: "URLs generieren" + description: + type: youtube + video_id: "kKixgYl_eIM" + duration: 217 + - id: "BOKYL5vfQX4" + title: "HTTP GET und POST" + description: + type: youtube + video_id: "BOKYL5vfQX4" + duration: 585 + - id: "bF6JCnRtE2Q" + title: "Templates" + description: + type: youtube + video_id: "bF6JCnRtE2Q" + duration: 196 + - id: "Grr7g_dDveE" + title: "Templates mit Parametern und Code" + description: + type: youtube + video_id: "Grr7g_dDveE" + duration: 491 + - id: "sc54UH2rOgs" + title: "Dateiuploads" + description: + type: youtube + video_id: "sc54UH2rOgs" + duration: 821 + - id: "w5CgRaBVZ7c" + title: "Cookies" + description: + type: youtube + video_id: "w5CgRaBVZ7c" + duration: 351 + - id: "GgS8-mn9zoM" + title: "Sessions" + description: + type: youtube + video_id: "GgS8-mn9zoM" + duration: 737 + - id: "ZgwHvNCn3QQ" + title: "Kurze Einführung in Datenbanken mit python" + description: + type: youtube + video_id: "ZgwHvNCn3QQ" + duration: 462 + - id: "K6LuzmG1Anw" + title: "SSL" + description: + type: youtube + video_id: "K6LuzmG1Anw" + duration: 424 + - id: "8UJTSQEcKgA" + title: "Threaded Apps" + description: + type: youtube + video_id: "8UJTSQEcKgA" + duration: 165 + - id: "r-y72UeF-4U" + title: "Fehlermeldungen" + description: + type: youtube + video_id: "r-y72UeF-4U" + duration: 283 + - id: "ZebnoIOdZLI" + title: "Logging" + description: + type: youtube + video_id: "ZebnoIOdZLI" + duration: 283 + - id: "AKD5RZQl5Y4" + title: "Json empfangen" + description: + type: youtube + video_id: "AKD5RZQl5Y4" + duration: 706 + - id: "uD-7KvlxLmY" + title: "Catch All URLs" + description: + type: youtube + video_id: "uD-7KvlxLmY" + duration: 161 + - id: "hqhc2Wxq3W4" + title: "HTTP Authentifikation" + description: + type: youtube + video_id: "hqhc2Wxq3W4" + duration: 719 + - id: "sIODSMgqHIE" + title: "Unittests" + description: + type: youtube + video_id: "sIODSMgqHIE" + duration: 640 + - id: section2 + title: "RESTplus" + description: + lectures: + - id: "0-R7_Q9GtzE" + title: "Projekteinleitung" + description: + type: youtube + video_id: "0-R7_Q9GtzE" + duration: 475 + - id: "GmHEZ8ipZiE" + title: "App Konfiguration für die Nutzung von Swagger" + description: + type: youtube + video_id: "GmHEZ8ipZiE" + duration: 513 + - id: "kTpkzGDVclw" + title: "Blueprints" + description: + type: youtube + video_id: "kTpkzGDVclw" + duration: 304 + - id: "O4Kze2oUauw" + title: "API-Definitionen mit restplus" + description: + type: youtube + video_id: "O4Kze2oUauw" + duration: 511 + - id: "uV5s7t0OsP4" + title: "Namespaces" + description: + type: youtube + video_id: "uV5s7t0OsP4" + duration: 442 + - id: "C8KFZNL90m8" + title: "Klassen für Routen" + description: + type: youtube + video_id: "C8KFZNL90m8" + duration: 473 + - id: "YvXHpBYH4yE" + title: "API Models" + description: + type: youtube + video_id: "YvXHpBYH4yE" + duration: 871 + - id: "jV5_eA8eKHU" + title: "Flasks Argument-Parser" + description: + type: youtube + video_id: "jV5_eA8eKHU" + duration: 431 + - id: "2ZDfHRu2IeA" + title: "Die Domain Logik" + description: + type: youtube + video_id: "2ZDfHRu2IeA" + duration: 312 + - id: "Fkt2TQ1MdSA" + title: "Die Data Transfer Objects" + description: + type: youtube + video_id: "Fkt2TQ1MdSA" + duration: 311 + - id: "aH647Ex5lgA" + title: "SQLAlchemy" + description: + type: youtube + video_id: "aH647Ex5lgA" + duration: 437 + - id: "jw-KOnrtMEE" + title: "Die API-Endpoints" + description: + type: youtube + video_id: "jw-KOnrtMEE" + duration: 248 + - id: "CduKJ75SMl0" + title: "kurze Fehlerbehebung" + description: + type: youtube + video_id: "CduKJ75SMl0" + duration: 480 + - id: "NUDZKqBpQTY" + title: "einzelne Items" + description: + type: youtube + video_id: "NUDZKqBpQTY" + duration: 344 + - id: "R6iFm-OUpcE" + title: "die automatische Swagger UI Integration" + description: + type: youtube + video_id: "R6iFm-OUpcE" + duration: 421 + - id: "a5-83uboWzs" + title: "JSON Web Tokens" + description: + type: youtube + video_id: "a5-83uboWzs" + duration: 876 + - id: section3 + title: "Bonus" + description: + lectures: + - id: "_bwgJFVY2zY" + title: "JSON Web Tokens - JWT Extended" + description: + type: youtube + video_id: "_bwgJFVY2zY" + duration: 1378 + - id: "yB3048KZswc" + title: "Deployment" + description: + type: youtube + video_id: "yB3048KZswc" + duration: 350 diff --git a/academy_data/courses/python_hacking.yml b/academy_data/courses/python_hacking.yml new file mode 100644 index 00000000..9f58def6 --- /dev/null +++ b/academy_data/courses/python_hacking.yml @@ -0,0 +1,98 @@ +# https://www.dropbox.com/t/2QXeTTH1ZwdkNU07 +title: "Python zum Pentesting" +description: "In Python gibt es unfassbar viele Bibliotheken - und einige davon sind definitiv zum Pentesting gedacht!" +category: +language: de +image: https://static.bootstrap.academy/thumbnails/python.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 500 +learning_goals: [] +requirements: [] +last_update: 1665584088 +sections: + - id: section + title: "Verschiedene Nützliche Scripts" + description: + lectures: + - id: "hacking_mit_python_ein_passwort_cracker_für_zip_archive" + title: "Ein Passwort Cracker für Zip-Archive" + description: + type: mp4 + duration: 994 + - id: "hacking_mit_python_ein_dictionary_passwort_cracker_für_zip_archive" + title: "Ein Dictionary Passwort Cracker für Zip-Archive" + description: + type: mp4 + duration: 514 + - id: "hacking_mit_python_rainbowtables_generieren" + title: "Rainbowtables generieren" + description: + type: mp4 + duration: 693 + - id: "hacking_mit_python_hashes_cracken_mit_rainbowtables" + title: "Hashes cracken mit Rainbowtables" + description: + type: mp4 + duration: 431 + - id: "hacking_mit_python_ddos" + title: "DDoS" + description: + type: mp4 + duration: 637 + - id: "hacking_mit_python_ein_keylogger_mit_pygame" + title: "Ein Keylogger mit PyGame" + description: + type: mp4 + duration: 446 + - id: "hacking_mit_python_eine_backdoor_mit_python" + title: "Eine Backdoor mit Python" + description: + type: mp4 + duration: 966 + - id: "hacking_mit_python_bildmetadaten_auslesen_mit_python" + title: "Bildmetadaten auslesen" + description: + type: mp4 + duration: 267 + - id: "hacking_mit_python_steganographie_text_in_bildern_verstecken_funktioniert_auch_mit_mp3s" + title: "Steganographie - Text in Bildern verstecken" + description: + type: mp4 + duration: 391 + - id: "hacking_mit_python_was_tun_ransomwares_aka_kryptographie_in_python" + title: "Was tun Ransomwares aka Kryptographie in Python" + description: + type: mp4 + duration: 829 + - id: "hacking_mit_python_den_antivirenschutz_austricksen" + title: "Den Antivirenschutz austricksen" + description: + type: mp4 + duration: 1778 + - id: "hacking_mit_python_ein_portscanner" + title: "Ein Portscanner" + description: + type: mp4 + duration: 558 + - id: "python_hacking_nmap_mit_python" + title: "Nmap" + description: + type: mp4 + duration: 584 + - id: "python_hacking_html_formulare_bruteforcen_mit_disclaimer" + title: "HTML-Formulare bruteforcen" + description: + type: mp4 + duration: 1562 + - id: "python_hacking_ft._wireshark_pyshark_ein_interface_für_tshark" + title: "Wireshark: PyShark ein Interface für TShark" + description: + type: mp4 + duration: 798 + - id: "python_krypto_one_time_pad" + title: "One Time Pad" + description: + type: mp4 + duration: 992 diff --git a/academy_data/courses/python_lets_code.yml b/academy_data/courses/python_lets_code.yml new file mode 100644 index 00000000..40202770 --- /dev/null +++ b/academy_data/courses/python_lets_code.yml @@ -0,0 +1,234 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7p09TLbRQmqzbH81DHjBO8E +title: "Python Let's Code" +description: "Es gibt so viele Bibliotheken in Python, in diesem Kurs gibt es ein paar Praxisbeispiele, was man damit machen kann!" +category: +language: de +image: https://static.bootstrap.academy/thumbnails/python.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506553 +sections: + - id: section + title: "Python Let's Code" + description: + lectures: + - id: "wI9yE7ZIbMg" + title: "Wasserzeichen und Komprimieren von Bildern" + description: + type: youtube + video_id: "wI9yE7ZIbMg" + duration: 1015 + - id: "vXrBTD8adW0" + title: "Eine Web UI für Stable Diffusion [Dall E Ersatz]" + description: + type: youtube + video_id: "vXrBTD8adW0" + duration: 928 + - id: "J5CEZ1lZo_o" + title: "Stable Diffusion: Besser als Dall E 2 in Python" + description: + type: youtube + video_id: "J5CEZ1lZo_o" + duration: 1083 + - id: "NvH6StJ918s" + title: "Mit Python Personen auf Bildern identifizieren" + description: + type: youtube + video_id: "NvH6StJ918s" + duration: 1408 + - id: "aFYxOS96q2A" + title: "BEAT THE TRÖTE" + description: + type: youtube + video_id: "aFYxOS96q2A" + duration: 920 + - id: "zwiKIzvGAhM" + title: "Gesichtserkennung mit Python und OpenCV in 14 Zeilen" + description: + type: youtube + video_id: "zwiKIzvGAhM" + duration: 695 + - id: "fflEcVtGSlE" + title: "PyScript - Python im Browser als JavaScript-Ersatz" + description: + type: youtube + video_id: "fflEcVtGSlE" + duration: 1098 + - id: "ZOWLCEJzQPQ" + title: "Ein Zufallsgenerator mit Lavalampe und Python" + description: + type: youtube + video_id: "ZOWLCEJzQPQ" + duration: 1470 + - id: "soVqW_yoKIU" + title: "Graphen zeichnen | Python" + description: + type: youtube + video_id: "soVqW_yoKIU" + duration: 618 + - id: "RRuU0W6_kso" + title: "Python Lets Code - Graphen" + description: + type: youtube + video_id: "RRuU0W6_kso" + duration: 954 + - id: "Gc92z58-Qm4" + title: "Snake in Python - in unter 150 Zeilen Code [PyGame]" + description: + type: youtube + video_id: "Gc92z58-Qm4" + duration: 3709 + - id: "XkvcUlvGqvs" + title: "SECURE FTP - SFTP mit pysftp" + description: + type: youtube + video_id: "XkvcUlvGqvs" + duration: 1148 + - id: "1HxjDXykSmc" + title: "FTP steuern und verwalten mit FTPlib" + description: + type: youtube + video_id: "1HxjDXykSmc" + duration: 1324 + - id: "sj03Q-JYZqA" + title: "2FA One Time Passwords mit PyOTP" + description: + type: youtube + video_id: "sj03Q-JYZqA" + duration: 853 + - id: "VVKFuZf9jNw" + title: "Passwörter sicher speichern" + description: + type: youtube + video_id: "VVKFuZf9jNw" + duration: 1140 + - id: "dipFOn4kZHY" + title: 'Text "Clean" machen' + description: + type: youtube + video_id: "dipFOn4kZHY" + duration: 1531 + - id: "cnrhMjroWrI" + title: "Größe eines Verzeichnisses berechnen" + description: + type: youtube + video_id: "cnrhMjroWrI" + duration: 717 + - id: "0q9CLHGV1Fo" + title: "Schrift in Bildern erkennen und in Text umwandeln mit PyTesseract" + description: + type: youtube + video_id: "0q9CLHGV1Fo" + duration: 737 + - id: "-XXj-uLdGmQ" + title: "Webcam nutzen und Kanten erkennen" + description: + type: youtube + video_id: "-XXj-uLdGmQ" + duration: 682 + - id: "lWDWJaV_rZ4" + title: "Subdomains einer Website enumerieren" + description: + type: youtube + video_id: "lWDWJaV_rZ4" + duration: 583 + - id: "m9U2WrmtfR4" + title: "CSGO Cheats, Code Injection & mehr: So wird Python Code in ausführbare Dateien migriert" + description: + type: youtube + video_id: "m9U2WrmtfR4" + duration: 627 + - id: "NcDlSAObptE" + title: "Ein Python VideoPlayer mit PyGame und Moviepy" + description: + type: youtube + video_id: "NcDlSAObptE" + duration: 323 + - id: "iLg9KSFxzi8" + title: "Das TOR-Netzwerk mit Python nutzen (via TorPy)" + description: + type: youtube + video_id: "iLg9KSFxzi8" + duration: 1198 + - id: "bFlyT4cDXew" + title: "Alle Bilder einer Website runterladen" + description: + type: youtube + video_id: "bFlyT4cDXew" + duration: 628 + - id: "9YBaUXzvBOo" + title: "QR Codes erstellen und einlesen" + description: + type: youtube + video_id: "9YBaUXzvBOo" + duration: 568 + - id: "JG1CC89mF00" + title: "Ein Prozessmonitor mit Python" + description: + type: youtube + video_id: "JG1CC89mF00" + duration: 1157 + - id: "6Sf_qHehLgU" + title: "Ein einfacher Screenrecorder mit opencv und pyautogui" + description: + type: youtube + video_id: "6Sf_qHehLgU" + duration: 766 + - id: "TZJQoi1h2FI" + title: "Text-To-Speech in Python in 4 Zeilen" + description: + type: youtube + video_id: "TZJQoi1h2FI" + duration: 230 + - id: "OZo2HxoIOtw" + title: "PDF Dateien zusammenfügen, trennen und Text auslesen" + description: + type: youtube + video_id: "OZo2HxoIOtw" + duration: 1028 + - id: "uZ9WWzkH17I" + title: "Mit RSA Text verschlüsseln [PyCryptodome]" + description: + type: youtube + video_id: "uZ9WWzkH17I" + duration: 1308 + - id: "P4F2Zt25j2I" + title: "Dateien verschlüsseln [PyCryptodome]" + description: + type: youtube + video_id: "P4F2Zt25j2I" + duration: 1816 + - id: "QthP_kxOy9Y" + title: "Dateien über das Netzwerk verschicken mit Sockets" + description: + type: youtube + video_id: "QthP_kxOy9Y" + duration: 1164 + - id: "csPfQnCc9P0" + title: "Sichere Passwörter erstellen" + description: + type: youtube + video_id: "csPfQnCc9P0" + duration: 583 + - id: "QBmhMpNAG0I" + title: "Mein neues System - Systeminfo auslesen" + description: + type: youtube + video_id: "QBmhMpNAG0I" + duration: 1295 + - id: "SfPWCKTHzE4" + title: "Tetris in Python in unter 250 Zeilen Code [PyGame]" + description: + type: youtube + video_id: "SfPWCKTHzE4" + duration: 5625 + - id: "MP8lMbgv1Ls" + title: "DNS Performancetest" + description: + type: youtube + video_id: "MP8lMbgv1Ls" + duration: 873 diff --git a/academy_data/courses/python_pillow.yml b/academy_data/courses/python_pillow.yml new file mode 100644 index 00000000..129aa5dd --- /dev/null +++ b/academy_data/courses/python_pillow.yml @@ -0,0 +1,66 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7p6tJ5S5Yvbw3reoZcHdyfR +title: "Pillow - Bildbearbeitung mit Python" +description: "Ihr wollt Bilder bearbeiten, am besten vollautomatisch und in Python? Kein Problem!" +category: +language: de +image: https://static.bootstrap.academy/thumbnails/python.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506587 +sections: + - id: section + title: "Pillow" + description: + lectures: + - id: "d5YQf8gs2_o" + title: "Installation und Einleitung" + description: + type: youtube + video_id: "d5YQf8gs2_o" + duration: 252 + - id: "fXoI_tZJDeI" + title: "Konvertieren von Bildern" + description: + type: youtube + video_id: "fXoI_tZJDeI" + duration: 344 + - id: "XgevO_Tw64M" + title: "Thumbnails" + description: + type: youtube + video_id: "XgevO_Tw64M" + duration: 296 + - id: "-DNX4GjP0fw" + title: "einzelne Pixel lesen" + description: + type: youtube + video_id: "-DNX4GjP0fw" + duration: 403 + - id: "HIgy3fr9BoA" + title: "Zuschneiden, Drehen und Verbessern" + description: + type: youtube + video_id: "HIgy3fr9BoA" + duration: 450 + - id: "NntGgQUrUuE" + title: "Filter und ImageOps" + description: + type: youtube + video_id: "NntGgQUrUuE" + duration: 239 + - id: "_fjCo5KdzeE" + title: "Farbauswahl, Masken und Pixel setzen" + description: + type: youtube + video_id: "_fjCo5KdzeE" + duration: 435 + - id: "wI9yE7ZIbMg" + title: "Wasserzeichen und Komprimieren von Bildern" + description: + type: youtube + video_id: "wI9yE7ZIbMg" + duration: 1015 diff --git a/academy_data/courses/python_pyqt.yml b/academy_data/courses/python_pyqt.yml new file mode 100644 index 00000000..888c59e6 --- /dev/null +++ b/academy_data/courses/python_pyqt.yml @@ -0,0 +1,90 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7ruNQIfS8NRpjzZIRq0A8QP +title: "Python GUI Programmierung mit PyQT" +description: "Ihr wollt graphische Oberflächen erstellen, um eure Kommandozeilentools etwas griffiger zu machen? Auch das geht mit Python." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/python.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506596 +sections: + - id: section + title: "Python GUI Programmierung mit PyQT" + description: + lectures: + - id: "FiaPzdWKhJU" + title: "Einleitung" + description: + type: youtube + video_id: "FiaPzdWKhJU" + duration: 693 + - id: "Z66AtVqdLUc" + title: "Der QT-Designer" + description: + type: youtube + video_id: "Z66AtVqdLUc" + duration: 463 + - id: "B9Zkn4GEDCE" + title: "Buttons, Tooltips und Quit" + description: + type: youtube + video_id: "B9Zkn4GEDCE" + duration: 729 + - id: "zIbQhLc_boI" + title: "Signale und Events" + description: + type: youtube + video_id: "zIbQhLc_boI" + duration: 983 + - id: "pa4XlYyIa2o" + title: "StatusBar, MenuBar und ToolBar" + description: + type: youtube + video_id: "pa4XlYyIa2o" + duration: 686 + - id: "YvaGU9tKerY" + title: "Layouts" + description: + type: youtube + video_id: "YvaGU9tKerY" + duration: 935 + - id: "6qriyonapEE" + title: "CheckBox, RadioButton, ToggleButton" + description: + type: youtube + video_id: "6qriyonapEE" + duration: 837 + - id: "qdW_XlnOCxM" + title: "Input-Felder aller Art" + description: + type: youtube + video_id: "qdW_XlnOCxM" + duration: 1131 + - id: "3uJpHA4l9zg" + title: "DateTimeEdit, ProgressBar und der Kalendar" + description: + type: youtube + video_id: "3uJpHA4l9zg" + duration: 708 + - id: "VvHePllETng" + title: "Dialoge" + description: + type: youtube + video_id: "VvHePllETng" + duration: 909 + - id: "ykUhAp8yTFE" + title: "Tabs und die ScrollArea" + description: + type: youtube + video_id: "ykUhAp8yTFE" + duration: 643 + - id: "DaIfM0jkbIk" + title: "Drag n' Drop" + description: + type: youtube + video_id: "DaIfM0jkbIk" + duration: 369 diff --git a/academy_data/courses/python_pytorch.yml b/academy_data/courses/python_pytorch.yml new file mode 100644 index 00000000..c33ae868 --- /dev/null +++ b/academy_data/courses/python_pytorch.yml @@ -0,0 +1,260 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7rx55Mai21reZtd_8m-qe27 +title: "PyTorch Tutorial - Neuronale Netze in Python" +description: "Neuronale Netze programmieren in Python. Der Traum für KI. Wenn du es bis hier geschafft hast, hast du 2 Bibliotheken zur Auswahl: PyTorch und Tensorflow. Hier geht's um PyTorch. An der Stelle kurze Warnung, dass PyTorch ein echt großes Update bekommen hat und vieles hier mittlerweile etwas anders geht." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/pytorch.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665508278 +sections: + - id: section + title: "Das erste neuronale Netz" + description: + lectures: + - id: "pylvlMuRKY0" + title: "Tensorflow und Keras vs PyTorch" + description: + type: youtube + video_id: "pylvlMuRKY0" + duration: 691 + - id: "h6KaLGUv9Uw" + title: "Installation von PyTorch" + description: + type: youtube + video_id: "h6KaLGUv9Uw" + duration: 660 + - id: "U4aM8oTEVAc" + title: "Tensoren" + description: + type: youtube + video_id: "U4aM8oTEVAc" + duration: 637 + - id: "bqVYRzwvCkU" + title: "Die Grafikkarte nutzen" + description: + type: youtube + video_id: "bqVYRzwvCkU" + duration: 169 + - id: "GBzojftwfGQ" + title: "Das erste eigene Neuronale Netz" + description: + type: youtube + video_id: "GBzojftwfGQ" + duration: 775 + - id: "u6V69py5Aps" + title: "Das Netz füttern" + description: + type: youtube + video_id: "u6V69py5Aps" + duration: 440 + - id: "F4V2617urQs" + title: "Das Netz lernen lassen" + description: + type: youtube + video_id: "F4V2617urQs" + duration: 797 + - id: "nU5Ww2-Zntk" + title: "Die Grafikkarte nutzen fürs ganze Netz" + description: + type: youtube + video_id: "nU5Ww2-Zntk" + duration: 208 + - id: "I4v2sES3AK0" + title: "Speichern und Laden des Netzes" + description: + type: youtube + video_id: "I4v2sES3AK0" + duration: 408 + - id: section2 + title: "Handschrifterkennung mit MNIST" + description: + lectures: + - id: "8gZR4Q3262k" + title: "Handschrifterkennung mit dem MNIST Datensatz" + description: + type: youtube + video_id: "8gZR4Q3262k" + duration: 893 + - id: "u0hC8gmpUDw" + title: "Training" + description: + type: youtube + video_id: "u0hC8gmpUDw" + duration: 601 + - id: "wVcuMADUmdY" + title: "Das Netz" + description: + type: youtube + video_id: "wVcuMADUmdY" + duration: 1071 + - id: "pS6Qe-A1MWg" + title: "Evaluieren" + description: + type: youtube + video_id: "pS6Qe-A1MWg" + duration: 799 + - id: section3 + title: "Katze oder Hund?" + description: + lectures: + - id: "32lHVbT09h8" + title: "Bilderkennung" + description: + type: youtube + video_id: "32lHVbT09h8" + duration: 819 + - id: "cNwMpWt6IHk" + title: "Daten einlesen" + description: + type: youtube + video_id: "cNwMpWt6IHk" + duration: 640 + - id: "Zj5QkjmYmBI" + title: "Randomisierung" + description: + type: youtube + video_id: "Zj5QkjmYmBI" + duration: 345 + - id: "dDO7ihzkoC4" + title: "Das Training" + description: + type: youtube + video_id: "dDO7ihzkoC4" + duration: 554 + - id: "RkcRqphggLY" + title: "Das Netz" + description: + type: youtube + video_id: "RkcRqphggLY" + duration: 829 + - id: "ulCylfDJRKo" + title: "Evaluation" + description: + type: youtube + video_id: "ulCylfDJRKo" + duration: 613 + - id: section4 + title: "Namensherkunft" + description: + lectures: + - id: "kabjuJWLvus" + title: "Character-RNNs" + description: + type: youtube + video_id: "kabjuJWLvus" + duration: 899 + - id: "26esNjWkEHA" + title: "One-Hot-Encoding" + description: + type: youtube + video_id: "26esNjWkEHA" + duration: 586 + - id: "PjlFR-PdwXk" + title: "Das RNN-Netz" + description: + type: youtube + video_id: "PjlFR-PdwXk" + duration: 668 + - id: "P08d-1RnczM" + title: "Training" + description: + type: youtube + video_id: "P08d-1RnczM" + duration: 791 + - id: "rJUZfEJZas8" + title: "Training und Plotting" + description: + type: youtube + video_id: "rJUZfEJZas8" + duration: 669 + - id: section5 + title: "Menschliche Passwörter generieren" + description: + lectures: + - id: "5O5X5-rNqrA" + title: "Wordlists" + description: + type: youtube + video_id: "5O5X5-rNqrA" + duration: 378 + - id: "cF9fVxHGL54" + title: "Das Netz" + description: + type: youtube + video_id: "cF9fVxHGL54" + duration: 662 + - id: "5qqsfvGqdgU" + title: "Training" + description: + type: youtube + video_id: "5qqsfvGqdgU" + duration: 455 + - id: "-BS63kJIvsY" + title: "Training #2" + description: + type: youtube + video_id: "-BS63kJIvsY" + duration: 804 + - id: "Xe6dMzEyc9A" + title: "Passwörter generieren / Sampling" + description: + type: youtube + video_id: "Xe6dMzEyc9A" + duration: 482 + - id: section6 + title: "Balance halten mit Cartpole" + description: + lectures: + - id: "YfSPmFrs9Vg" + title: "Reinforcement Learning" + description: + type: youtube + video_id: "YfSPmFrs9Vg" + duration: 514 + - id: "CB2WRO_G6OI" + title: "Memory" + description: + type: youtube + video_id: "CB2WRO_G6OI" + duration: 526 + - id: "R9Iy_ViGfCs" + title: "Das Netz" + description: + type: youtube + video_id: "R9Iy_ViGfCs" + duration: 468 + - id: "loTwHTGTBu4" + title: "Datenverarbeitung" + description: + type: youtube + video_id: "loTwHTGTBu4" + duration: 930 + - id: "bDNWSe-DMXI" + title: "Training Vorbereitung" + description: + type: youtube + video_id: "bDNWSe-DMXI" + duration: 880 + - id: "JLCGBEEf2BM" + title: "Training #2" + description: + type: youtube + video_id: "JLCGBEEf2BM" + duration: 1130 + - id: "Jc6jevYQqQQ" + title: "Spielen und Training initialisieren" + description: + type: youtube + video_id: "Jc6jevYQqQQ" + duration: 624 + - id: "Nk0X4TYd1oU" + title: "Anzeigen" + description: + type: youtube + video_id: "Nk0X4TYd1oU" + duration: 517 diff --git a/academy_data/courses/python_selenium.yml b/academy_data/courses/python_selenium.yml new file mode 100644 index 00000000..a2dfbfa5 --- /dev/null +++ b/academy_data/courses/python_selenium.yml @@ -0,0 +1,90 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7ruEf-FwVD3Z5owHgdXNKlb +title: "Python Selenium - Den Browser automatisch bedienen" +description: "Ihr wollt direkt eure Ende-zu-Ende Tests der Website in Python programmieren? Oder einfach nur ein paar lästige Aufgaben fernsteuern? Dann braucht ihr vermutlich Selenium." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/python.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665508136 +sections: + - id: section + title: "Den Browser automatisch bedienen" + description: + lectures: + - id: "u1T2v2Ucuuc" + title: "Den Browser automatisch bedienen lassen" + description: + type: youtube + video_id: "u1T2v2Ucuuc" + duration: 499 + - id: "X_oTF5aSGcA" + title: "Automatisch Googlen" + description: + type: youtube + video_id: "X_oTF5aSGcA" + duration: 547 + - id: "bfk6mmYkOWI" + title: "Unittests mit Selenium" + description: + type: youtube + video_id: "bfk6mmYkOWI" + duration: 633 + - id: "Ak4-l5XkQ3k" + title: "Elemente finden #1" + description: + type: youtube + video_id: "Ak4-l5XkQ3k" + duration: 814 + - id: "2iX3fQiqUdA" + title: "Keys" + description: + type: youtube + video_id: "2iX3fQiqUdA" + duration: 218 + - id: "wJsUvQAjUFs" + title: "Die History" + description: + type: youtube + video_id: "wJsUvQAjUFs" + duration: 131 + - id: "nK6CMrNTWqY" + title: "Cookies" + description: + type: youtube + video_id: "nK6CMrNTWqY" + duration: 400 + - id: "ScByEODsLiw" + title: "Ein Mini XPath Tutorial" + description: + type: youtube + video_id: "ScByEODsLiw" + duration: 709 + - id: "A1XWkGMeso4" + title: "Performance Tests und Explizites warten" + description: + type: youtube + video_id: "A1XWkGMeso4" + duration: 459 + - id: "kPBbIo2iKic" + title: "Implizites warten und eigene Wartebedingungen" + description: + type: youtube + video_id: "kPBbIo2iKic" + duration: 475 + - id: "BsWrl_AT_jQ" + title: "ActionChains" + description: + type: youtube + video_id: "BsWrl_AT_jQ" + duration: 530 + - id: "0hz8u3iCxQk" + title: "ChromeOptions" + description: + type: youtube + video_id: "0hz8u3iCxQk" + duration: 394 diff --git a/academy_data/courses/python_tensorflow.yml b/academy_data/courses/python_tensorflow.yml new file mode 100644 index 00000000..52dfb6b3 --- /dev/null +++ b/academy_data/courses/python_tensorflow.yml @@ -0,0 +1,238 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7oj8ijyHSTOoW9bHLlXQ7hp +title: "TensorFlow 2: Neuronale Netze in Python erstellen" +description: "Neuronale Netze programmieren in Python. Der Traum für KI. Wenn du es bis hier geschafft hast, hast du 2 Bibliotheken zur Auswahl: PyTorch und Tensorflow. Hier geht's um Tensorflow - die neue Version allerdings, denn die ist um einiges leichter und angenehmer geworden." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/tensorflow.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 3000 +learning_goals: [] +requirements: [] +last_update: 1665507656 +sections: + - id: section + title: "TensorFlow 2: Neuronale Netze in Python erstellen" + description: + lectures: + - id: "eEgXn-D8LuU" + title: "Installation auch für die Grafikkarte" + description: + type: youtube + video_id: "eEgXn-D8LuU" + duration: 1259 + - id: "u3WJniYFqvI" + title: "Tensoren" + description: + type: youtube + video_id: "u3WJniYFqvI" + duration: 934 + - id: "IwCc8Yl918Q" + title: "Grundlagen für ein neuronales Netz" + description: + type: youtube + video_id: "IwCc8Yl918Q" + duration: 631 + - id: "mpuVLGVNKnk" + title: "Das neuronale Netz erstellen" + description: + type: youtube + video_id: "mpuVLGVNKnk" + duration: 869 + - id: "Em3r6E0rNiM" + title: "Daten vorbereiten" + description: + type: youtube + video_id: "Em3r6E0rNiM" + duration: 1052 + - id: "L7fuzKv8RvQ" + title: "Metriken" + description: + type: youtube + video_id: "L7fuzKv8RvQ" + duration: 551 + - id: "guEeDOAFn-M" + title: "Das Training" + description: + type: youtube + video_id: "guEeDOAFn-M" + duration: 1076 + - id: "YogPNAlntSw" + title: "Plotten" + description: + type: youtube + video_id: "YogPNAlntSw" + duration: 446 + - id: section2 + title: "Alternativen für MNIST" + description: + lectures: + - id: "xdz8a7lANag" + title: "MNist in kurzem Tensorflow Code" + description: + type: youtube + video_id: "xdz8a7lANag" + duration: 1431 + - id: "n_-WqWLujkM" + title: "Convolutional Neural Networks" + description: + type: youtube + video_id: "n_-WqWLujkM" + duration: 826 + - id: section3 + title: "Übung" + description: + lectures: + - id: "_LLBFqVwayo" + title: "Fashion MNist" + description: + type: youtube + video_id: "_LLBFqVwayo" + duration: 1271 + - id: section4 + title: "Google Colab" + description: + lectures: + - id: "5ZTFKNo5GSg" + title: "Google Colab" + description: + type: youtube + video_id: "5ZTFKNo5GSg" + duration: 381 + - id: section5 + title: "Lego Steine erkennen" + description: + lectures: + - id: "9kxjuTzGq-M" + title: "Datensatz" + description: + type: youtube + video_id: "9kxjuTzGq-M" + duration: 860 + - id: "VfrKWzfNH10" + title: "Datensatz aufteilen" + description: + type: youtube + video_id: "VfrKWzfNH10" + duration: 1068 + - id: "-PFS_9M70FQ" + title: "Daten laden" + description: + type: youtube + video_id: "-PFS_9M70FQ" + duration: 1017 + - id: "3b7QlsFAJRo" + title: "Das neuronale Netz" + description: + type: youtube + video_id: "3b7QlsFAJRo" + duration: 1192 + - id: "dlSkYC2WzUw" + title: "Speichern, Laden und Callbacks" + description: + type: youtube + video_id: "dlSkYC2WzUw" + duration: 787 + - id: "DGmHcut6b6g" + title: "Graphen plotten und interpretieren" + description: + type: youtube + video_id: "DGmHcut6b6g" + duration: 477 + - id: section6 + title: "Objekt-Segmentierung" + description: + lectures: + - id: "lcug3JKUNvE" + title: "Daten laden" + description: + type: youtube + video_id: "lcug3JKUNvE" + duration: 1719 + - id: "LbFDXkpmnz0" + title: "Das neuronale Netz und drucken von neuronalen Net" + description: + type: youtube + video_id: "LbFDXkpmnz0" + duration: 1617 + - id: "3qWplvoZWY0" + title: "Training" + description: + type: youtube + video_id: "3qWplvoZWY0" + duration: 1072 + - id: section7 + title: "GAN - Bildgenerierung" + description: + lectures: + - id: "6geyb6iqjZE" + title: "Daten" + description: + type: youtube + video_id: "6geyb6iqjZE" + duration: 549 + - id: "Jg8Hu0Tu0go" + title: "Bilder generieren mit dem Generator" + description: + type: youtube + video_id: "Jg8Hu0Tu0go" + duration: 1458 + - id: "K1ZitZQgyGI" + title: "Der Discriminator" + description: + type: youtube + video_id: "K1ZitZQgyGI" + duration: 554 + - id: "bPR6Xnr4Jyk" + title: "Die Fehler" + description: + type: youtube + video_id: "bPR6Xnr4Jyk" + duration: 467 + - id: "fZFHf2SaNVc" + title: "Die Trainingsschleife" + description: + type: youtube + video_id: "fZFHf2SaNVc" + duration: 562 + - id: "0O83ez27IHA" + title: "Das Training" + description: + type: youtube + video_id: "0O83ez27IHA" + duration: 1069 + - id: section8 + title: "Textverarbeitung mit dem IMDB Datensatz" + description: + lectures: + - id: "Fc1zqv9Ojmg" + title: "Daten" + description: + type: youtube + video_id: "Fc1zqv9Ojmg" + duration: 1502 + - id: "hlN_UUEV7Pc" + title: "Daten 2" + description: + type: youtube + video_id: "hlN_UUEV7Pc" + duration: 953 + - id: "CYmGAte9t8k" + title: "Das Modell und das Training" + description: + type: youtube + video_id: "CYmGAte9t8k" + duration: 667 + - id: "QY7nIIDD75I" + title: "Vorhersagen erstellen" + description: + type: youtube + video_id: "QY7nIIDD75I" + duration: 502 + - id: "CQLTg1h2yBo" + title: "Rekurrente Netze" + description: + type: youtube + video_id: "CQLTg1h2yBo" + duration: 1036 diff --git a/academy_data/courses/react_js.yml b/academy_data/courses/react_js.yml new file mode 100644 index 00000000..f287bb27 --- /dev/null +++ b/academy_data/courses/react_js.yml @@ -0,0 +1,142 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7oi_Q4whC28Yp12l1I-hauk +title: "React JS" +description: "React, das Frontend Framework von Facebook, ist ein bisschen kleiner und flexibler, aber dennoch genauso mächtig wie Angular!" +category: +language: de +image: https://static.bootstrap.academy/thumbnails/javascript.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1666715550 +sections: + - id: section + title: "React JS" + description: + lectures: + - id: "HCJCFV-OGnY" + title: "React vs. Angular" + description: + type: youtube + video_id: "HCJCFV-OGnY" + duration: 495 + - id: "cSRop5CJQws" + title: "Installation und Setup der Umgebung" + description: + type: youtube + video_id: "cSRop5CJQws" + duration: 665 + - id: "WMf5UEZLXyM" + title: "JSX und Rendern von Objekten" + description: + type: youtube + video_id: "WMf5UEZLXyM" + duration: 954 + - id: "NRpuaZrilCU" + title: "Eine Uhr - Selbst aktualisierende Komponenten" + description: + type: youtube + video_id: "NRpuaZrilCU" + duration: 809 + - id: "dk0KWGOOvdQ" + title: "Mehrere Elemente und Events" + description: + type: youtube + video_id: "dk0KWGOOvdQ" + duration: 944 + - id: "1KlCH6rPpgI" + title: "Euro in Dollar umrechnen - Forms und Live Änderungen" + description: + type: youtube + video_id: "1KlCH6rPpgI" + duration: 1026 + - id: "FfAiMfxxxA8" + title: "Ordnerstrukturen" + description: + type: youtube + video_id: "FfAiMfxxxA8" + duration: 705 + - id: "pRROp0bwxOE" + title: "Routing" + description: + type: youtube + video_id: "pRROp0bwxOE" + duration: 760 + - id: "-Y73N2uqQiM" + title: "Parameter in URLs" + description: + type: youtube + video_id: "-Y73N2uqQiM" + duration: 370 + - id: "K9P-ZclspJg" + title: "Sass / Scss verwenden" + description: + type: youtube + video_id: "K9P-ZclspJg" + duration: 262 + - id: "cwrS3omZbR4" + title: "Redirects" + description: + type: youtube + video_id: "cwrS3omZbR4" + duration: 316 + - id: "PcGQ6nzTXgY" + title: "Deployment" + description: + type: youtube + video_id: "PcGQ6nzTXgY" + duration: 533 + - id: "ZDOo8iCjOMs" + title: "Logik beim Erstellen einer Anwendung mit TypeScript" + description: + type: youtube + video_id: "ZDOo8iCjOMs" + duration: 2707 + - id: "mG7yXW7jluc" + title: "Umbau und erste Tests mit Jest" + description: + type: youtube + video_id: "mG7yXW7jluc" + duration: 492 + - id: "G2KljzRBfNM" + title: "Testen mit Jest" + description: + type: youtube + video_id: "G2KljzRBfNM" + duration: 843 + - id: section2 + title: "Redux" + description: + lectures: + - id: "IglaWZAWVgc" + title: "Was ist React Redux" + description: + type: youtube + video_id: "IglaWZAWVgc" + duration: 550 + - id: "jfBmMztAlxQ" + title: "Die Beispiel App" + description: + type: youtube + video_id: "jfBmMztAlxQ" + duration: 1014 + - id: "SKSxwCX8oGE" + title: "Ein neues Feature hinzufügen" + description: + type: youtube + video_id: "SKSxwCX8oGE" + duration: 795 + - id: "DkkSEbgsjmQ" + title: "Reducer für das Feature" + description: + type: youtube + video_id: "DkkSEbgsjmQ" + duration: 891 + - id: "Nci56RDMlF8" + title: "Asynchronität ermöglichen via Thunks" + description: + type: youtube + video_id: "Nci56RDMlF8" + duration: 895 diff --git a/academy_data/courses/sass_scss.yml b/academy_data/courses/sass_scss.yml new file mode 100644 index 00000000..2e9b4009 --- /dev/null +++ b/academy_data/courses/sass_scss.yml @@ -0,0 +1,180 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7oopYYGy5hX-Y6b07_3DPp5 +title: "SASS und SCSS - CSS auf Steroiden" +description: "Hattet ihr jemals das Gefühl in CSS fehlt was? Variablen, Funktionen, Parameter, eben richtige Programmierung? Willkommen bei SCSS." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/CSS.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665508245 +sections: + - id: section + title: "SASS und SCSS - CSS auf Steroiden" + description: + lectures: + - id: "Vyp3Nh0QvSk" + title: "Einleitung" + description: + type: youtube + video_id: "Vyp3Nh0QvSk" + duration: 406 + - id: "9ZD6NmO2PTk" + title: "Installation unter MacOS, Linux und Windows" + description: + type: youtube + video_id: "9ZD6NmO2PTk" + duration: 524 + - id: "wpjisrRQGoc" + title: "Die Entwicklungsumgebung" + description: + type: youtube + video_id: "wpjisrRQGoc" + duration: 553 + - id: "dmQ9ft1R4oQ" + title: "Variablen" + description: + type: youtube + video_id: "dmQ9ft1R4oQ" + duration: 403 + - id: "5FZo3ieRhno" + title: "Nesting" + description: + type: youtube + video_id: "5FZo3ieRhno" + duration: 488 + - id: "JfS6GoPcpsI" + title: "Partials und Imports" + description: + type: youtube + video_id: "JfS6GoPcpsI" + duration: 653 + - id: "Dsqea2p7qmQ" + title: "Mixins" + description: + type: youtube + video_id: "Dsqea2p7qmQ" + duration: 278 + - id: "2nCPYNVf3fE" + title: "Mixins mit Parametern" + description: + type: youtube + video_id: "2nCPYNVf3fE" + duration: 529 + - id: "Aicbc6d3xgw" + title: "Datentypen" + description: + type: youtube + video_id: "Aicbc6d3xgw" + duration: 431 + - id: "ezOR6yEwubA" + title: "Mathematische Operationen in Style Sheets" + description: + type: youtube + video_id: "ezOR6yEwubA" + duration: 569 + - id: "Ya7J_4au13I" + title: "Interpolation mit #{}" + description: + type: youtube + video_id: "Ya7J_4au13I" + duration: 547 + - id: "acOPoGADus0" + title: "!default" + description: + type: youtube + video_id: "acOPoGADus0" + duration: 172 + - id: "BJBkWvDxYjo" + title: "@media" + description: + type: youtube + video_id: "BJBkWvDxYjo" + duration: 374 + - id: "BbAZQpGTgp0" + title: "if-Anweisungen" + description: + type: youtube + video_id: "BbAZQpGTgp0" + duration: 514 + - id: "7VG8RAkZGIs" + title: "for-Schleifen" + description: + type: youtube + video_id: "7VG8RAkZGIs" + duration: 302 + - id: "9TaxiKMGRKU" + title: "each-Schleifen" + description: + type: youtube + video_id: "9TaxiKMGRKU" + duration: 451 + - id: "sXDGzsNXO3c" + title: "Extends" + description: + type: youtube + video_id: "sXDGzsNXO3c" + duration: 343 + - id: "Fr_4YFkOI_E" + title: "Debug Nachrichten" + description: + type: youtube + video_id: "Fr_4YFkOI_E" + duration: 289 + - id: "5781OsElTo0" + title: "& - der hier Marker" + description: + type: youtube + video_id: "5781OsElTo0" + duration: 176 + - id: "1gPU2Gcn5J0" + title: "Leichte Farbfunktionen" + description: + type: youtube + video_id: "1gPU2Gcn5J0" + duration: 619 + - id: "TvW6sqtOI1k" + title: "Hersteller Präfixe Mixin" + description: + type: youtube + video_id: "TvW6sqtOI1k" + duration: 312 + - id: "FSufbI1YV2Y" + title: "Stanzeffekt Mixin" + description: + type: youtube + video_id: "FSufbI1YV2Y" + duration: 245 + - id: "me3QJZELp3k" + title: "Responsive Breakpoints" + description: + type: youtube + video_id: "me3QJZELp3k" + duration: 294 + - id: "qv1lVbEeRZ0" + title: "Ein- und Ausblenden" + description: + type: youtube + video_id: "qv1lVbEeRZ0" + duration: 455 + - id: "PHXXEIQz5F0" + title: "Mit Listen arbeiten" + description: + type: youtube + video_id: "PHXXEIQz5F0" + duration: 585 + - id: "ybVFCBUVtwM" + title: "Mit Maps arbeiten" + description: + type: youtube + video_id: "ybVFCBUVtwM" + duration: 515 + - id: "8RE7YEFJlfY" + title: "nützliche SASS Funktionen" + description: + type: youtube + video_id: "8RE7YEFJlfY" + duration: 834 diff --git a/academy_data/courses/schwachstellen_web_anwendungen.yml b/academy_data/courses/schwachstellen_web_anwendungen.yml new file mode 100644 index 00000000..70036c8f --- /dev/null +++ b/academy_data/courses/schwachstellen_web_anwendungen.yml @@ -0,0 +1,429 @@ +# https://www.dropbox.com/t/e1CSdYLRYWviD86b +title: "Schwachstellen von Web Anwendungen" +description: "Websites sind mittlerweile überall und sind damit das Ding, was am meisten angegriffen wird. Hier erfahrt ihr alles über die wichtigsten Angriffe und die Möglichkeiten sich zu verteidigen." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/pentesting.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 1000 +learning_goals: [] +requirements: [] +last_update: 1665584088 +sections: + - id: grundlagen + title: "Grundlagen" + description: + lectures: + - id: "01_web_anwendungen_hacken_tutorial_1_schwachstellen_angriffe_und_verteidigung" + title: "Schwachstellen, Angriffe und Verteidigung" + description: + type: mp4 + duration: 575 + - id: "01_web_anwendungen_hacken_tutorial_2_grundlagen_architektur_von_web_anwendungen" + title: "Architektur von Web Anwendungen" + description: + type: mp4 + duration: 335 + - id: "01_web_anwendungen_hacken_tutorial_3_grundlagen_url_kodierung" + title: "URL Kodierung" + description: + type: mp4 + duration: 759 + - id: "01_web_anwendungen_hacken_tutorial_4_grundlagen_parameter_außerhalb_von_urls" + title: "Parameter außerhalb von URLs" + description: + type: mp4 + duration: 840 + - id: "01_web_anwendungen_hacken_tutorial_5_grundlagen_das_große_problem_nutzereingaben" + title: "Das große Problem - Nutzereingaben" + description: + type: mp4 + duration: 336 + - id: "01_web_anwendungen_hacken_tutorial_6_grundlagen_blacklisting_vs._whitelisting" + title: "Blacklisting vs. Whitelisting" + description: + type: mp4 + duration: 352 + - id: xss + title: "XSS" + description: + lectures: + - id: "02_web_anwendungen_hacken_tutorial_xss_1_demo" + title: "Demo" + description: + type: mp4 + duration: 418 + - id: "02_web_anwendungen_hacken_tutorial_xss_2_gefahren_von_xss" + title: "Gefahren von XSS" + description: + type: mp4 + duration: 473 + - id: "02_web_anwendungen_hacken_tutorial_xss_3_reflected_xss" + title: "Reflected XSS" + description: + type: mp4 + duration: 281 + - id: "02_web_anwendungen_hacken_tutorial_xss_4_cookies_stehlen" + title: "Cookies stehlen" + description: + type: mp4 + duration: 389 + - id: "02_web_anwendungen_hacken_tutorial_xss_5_stored_xss" + title: "Stored XSS" + description: + type: mp4 + duration: 268 + - id: "02_web_anwendungen_hacken_tutorial_xss_6_dom_based_xss" + title: "DOM-based XSS" + description: + type: mp4 + duration: 294 + - id: "02_web_anwendungen_hacken_tutorial_xss_7_exotischere_xss_payloads" + title: "Exotischere XSS-Payloads" + description: + type: mp4 + duration: 357 + - id: "02_web_anwendungen_hacken_tutorial_xss_8_filtern_ausweichen_1" + title: "Filtern ausweichen #1" + description: + type: mp4 + duration: 295 + - id: "02_web_anwendungen_hacken_tutorial_xss_9_filtern_ausweichen_2" + title: "Filtern ausweichen #2" + description: + type: mp4 + duration: 372 + - id: "02_web_anwendungen_hacken_tutorial_xss_10_filtern_ausweichen_3" + title: "Filtern ausweichen #3" + description: + type: mp4 + duration: 364 + - id: "02_web_anwendungen_hacken_tutorial_xss_11_filtern_ausweichen_4" + title: "Filtern ausweichen #4" + description: + type: mp4 + duration: 322 + - id: "02_web_anwendungen_hacken_tutorial_xss_12_filtern_ausweichen_5" + title: "Filtern ausweichen #5" + description: + type: mp4 + duration: 474 + - id: "02_web_anwendungen_hacken_tutorial_xss_13_filtern_ausweichen_6" + title: "Filtern ausweichen #6" + description: + type: mp4 + duration: 511 + - id: "02_web_anwendungen_hacken_tutorial_xss_14_filtern_ausweichen_7_liste_in_beschreibung!" + title: "Filtern ausweichen #7" + description: + type: mp4 + duration: 568 + - id: "02_web_anwendungen_hacken_tutorial_xss_15_xss_verhindern_tricks_links_in_beschreibung" + title: "XSS Verhindern Tricks" + description: + type: mp4 + duration: 516 + - id: "02_schwachstellen_von_web_anwendungen_bonus_cookies_stehlen_in_der_praxis" + title: "Bonus: Cookies Stehlen in der Praxis" + description: + type: mp4 + duration: 979 + - id: sql_injections + title: "SQL Injections" + description: + lectures: + - id: "03_web_anwendungen_hacken_tutorial_sql_injections_1_demo" + title: "Demo" + description: + type: mp4 + duration: 544 + - id: "03_web_anwendungen_hacken_tutorial_sql_injections_2_code_reviews" + title: "Code Reviews" + description: + type: mp4 + duration: 323 + - id: "03_web_anwendungen_hacken_tutorial_sql_injections_3_wo_es_auftreten_kann" + title: "Wo es auftreten kann" + description: + type: mp4 + duration: 455 + - id: "03_web_anwendungen_hacken_tutorial_sql_injections_4_gefahren_von_sql_injections" + title: "Gefahren von SQL Injections" + description: + type: mp4 + duration: 531 + - id: "03_web_anwendungen_hacken_tutorial_sql_injections_5_sqlmap_einführung" + title: "SQLMap - Einführung" + description: + type: mp4 + duration: 531 + - id: "03_web_anwendungen_hacken_tutorial_sql_injections_6_sqlmap_grundlegende_nutzung_sqli_get_bereit_stellen" + title: "SQLMap - Grundlegende Nutzung" + description: + type: mp4 + duration: 815 + - id: "03_web_anwendungen_hacken_tutorial_sql_injections_7_sqlmap_exploiten_von_sql_injections" + title: "SQLMap - Exploiten von SQL Injections" + description: + type: mp4 + duration: 614 + - id: "03_web_anwendungen_hacken_tutorial_sql_injections_8_sqlmap_ausführen_von_beliebigen_sql_statements" + title: "SQLMap - Ausführen von beliebigen SQL-Statements" + description: + type: mp4 + duration: 292 + - id: "03_web_anwendungen_hacken_tutorial_sql_injections_9_sqlmap_eigene_injection_points" + title: "SQLMap - Eigene Injection-Points" + description: + type: mp4 + duration: 325 + - id: "03_web_anwendungen_hacken_tutorial_sql_injections_10_sqlmap_post_daten_index.php_bereit_stellen" + title: "SQLMap - POST-Daten" + description: + type: mp4 + duration: 339 + - id: "03_web_anwendungen_hacken_tutorial_sql_injections_11_sqlmap_optimierungen_und_stealth" + title: "SQLMap - Optimierungen und Stealth" + description: + type: mp4 + duration: 259 + - id: "03_web_anwendungen_hacken_tutorial_sql_injections_11_sqlmap_proxies_und_tor_nutzen" + title: "SQLMap - Proxies und TOR nutzen" + description: + type: mp4 + duration: 471 + - id: "03_web_anwendungen_hacken_tutorial_sql_injections_12_sqlmap_forms_automatisch_testen" + title: "SQLMap - Forms automatisch testen" + description: + type: mp4 + duration: 310 + - id: "03_web_anwendungen_hacken_tutorial_sql_injections_13_sqlmap_das_zielsystem_ownen" + title: "SQLMap - Das Zielsystem ownen" + description: + type: mp4 + duration: 460 + - id: "03_web_anwendungen_hacken_tutorial_sql_injections_14_sqlinjections_verhindern" + title: "SQLInjections verhindern" + description: + type: mp4 + duration: 239 + - id: "03_web_anwendungen_hacken_tutorial_sql_injections_15_sqlinjections_verhindern_ii" + title: "SQLInjections verhindern II" + description: + type: mp4 + duration: 381 + - id: xxe + title: "XXE" + description: + lectures: + - id: "04_web_anwendungen_hacken_tutorial_xxe_1_xml_external_entities" + title: "XML External Entities" + description: + type: mp4 + duration: 350 + - id: "04_web_anwendungen_hacken_tutorial_xxe_2_entities_definieren" + title: "Entities definieren" + description: + type: mp4 + duration: 273 + - id: "04_web_anwendungen_hacken_tutorial_xxe_3_der_billion_laughs_angriff" + title: "Der Billion Laughs Angriff" + description: + type: mp4 + duration: 338 + - id: "04_web_anwendungen_hacken_tutorial_xxe_4_geheime_daten_ausspähen" + title: "Geheime Daten ausspähen" + description: + type: mp4 + duration: 234 + - id: "04_web_anwendungen_hacken_tutorial_xxe_5_remote_code_execution" + title: "Remote Code Execution" + description: + type: mp4 + duration: 256 + - id: datei_schwachstellen + title: "Datei-Schwachstellen" + description: + lectures: + - id: "05_web_anwendungen_hacken_tutorial_datei_schwachstellen_2_local_file_inclusion" + title: "Local File Inclusion" + description: + type: mp4 + duration: 289 + - id: "05_web_anwendungen_hacken_tutorial_datei_schwachstellen_3_null_bytes" + title: "NULL Bytes" + description: + type: mp4 + duration: 172 + - id: "05_web_anwendungen_hacken_tutorial_datei_schwachstellen_4_filter_bypassing" + title: "Filter Bypassing" + description: + type: mp4 + duration: 328 + - id: "05_web_anwendungen_hacken_tutorial_datei_schwachstellen_5_log_injection" + title: "Log Injection" + description: + type: mp4 + duration: 358 + - id: "05_web_anwendungen_hacken_tutorial_datei_schwachstellen_remote_file_inclusion" + title: "Remote File Inclusion" + description: + type: mp4 + duration: 287 + - id: directory_enumeration + title: "Directory Enumeration" + description: + lectures: + - id: "06_web_anwendungen_hacken_tutorial_directory_enumeration_dirsearch" + title: "dirsearch" + description: + type: mp4 + duration: 561 + - id: ddos + title: "DDOS" + description: + lectures: + - id: "07_web_anwendungen_hacken_tutorial_ddos_1_klassen_von_ddos_angriffen" + title: "Klassen von DDoS-Angriffen" + description: + type: mp4 + duration: 553 + - id: "07_web_anwendungen_hacken_tutorial_ddos_2_ziele" + title: "Ziele" + description: + type: mp4 + duration: 596 + - id: "07_web_anwendungen_hacken_tutorial_ddos_3_tools_bzw_warum_keine_tools" + title: "Tools bzw warum keine Tools" + description: + type: mp4 + duration: 302 + - id: "07_web_anwendungen_hacken_tutorial_ddos_4_einfache_angriffe" + title: "einfache Angriffe" + description: + type: mp4 + duration: 537 + - id: "07_web_anwendungen_hacken_tutorial_ddos_5_generelles_vorgehen_und_angriffe_die_wir_schon_kennen" + title: "generelles Vorgehen und Angriffe, die wir schon kennen" + description: + type: mp4 + duration: 371 + - id: "07_web_anwendungen_hacken_tutorial_ddos_6_pre_authentification_angriffe" + title: "Pre-Authentification-Angriffe" + description: + type: mp4 + duration: 725 + - id: "07_web_anwendungen_hacken_tutorial_ddos_7_authentification_und_post_auth._angriffe" + title: "Authentification und Post-Auth.-Angriffe" + description: + type: mp4 + duration: 645 + - id: csrf + title: "CSRF" + description: + lectures: + - id: "08_web_anwendungen_hacken_tutorial_csrf_1_cross_site_request_forgery" + title: "Cross Site Request Forgery" + description: + type: mp4 + duration: 252 + - id: "08_web_anwendungen_hacken_tutorial_csrf_1_post_parameter" + title: "POST-Parameter" + description: + type: mp4 + duration: 181 + - id: "08_web_anwendungen_hacken_tutorial_csrf_3_csrf_unterbinden" + title: "CSRF unterbinden" + description: + type: mp4 + duration: 522 + - id: passwortsicherheit + title: "Passwortsicherheit" + description: + lectures: + - id: "09_web_anwendungen_hacken_tutorial_passwortsicherheit_1" + title: "Passwortsicherheit #1" + description: + type: mp4 + duration: 618 + - id: "09_web_anwendungen_hacken_tutorial_passwortsicherheit_2" + title: "Passwortsicherheit #2" + description: + type: mp4 + duration: 511 + - id: "09_web_anwendungen_hacken_tutorial_passwortsicherheit_3_speichern_von_passwörtern" + title: "Speichern von Passwörtern" + description: + type: mp4 + duration: 714 + - id: "09_web_anwendungen_hacken_tutorial_remember_me_tokens" + title: "Remember Me Tokens" + description: + type: mp4 + duration: 517 + - id: zap + title: "Zed Attack Proxy ZAP" + description: + lectures: + - id: "10_zed_attack_proxy_zap_tutorial_1_einleitung_und_installation" + title: "Einleitung und Installation" + description: + type: mp4 + duration: 476 + - id: "10_zed_attack_proxy_zap_tutorial_2_ein_einfacher_angriff" + title: "ein einfacher Angriff" + description: + type: mp4 + duration: 575 + - id: "10_zed_attack_proxy_zap_tutorial_3_warnungen" + title: "Warnungen" + description: + type: mp4 + duration: 678 + - id: "10_zed_attack_proxy_zap_tutorial_4_aktive_scans" + title: "Aktive Scans" + description: + type: mp4 + duration: 590 + - id: "10_zed_attack_proxy_zap_tutorial_5_eigene_policies" + title: "eigene Policies" + description: + type: mp4 + duration: 379 + - id: "10_zed_attack_proxy_zap_tutorial_6_forced_browsing" + title: "Forced Browsing" + description: + type: mp4 + duration: 304 + - id: "10_zed_attack_proxy_zap_tutorial_7_fuzzing" + title: "Fuzzing" + description: + type: mp4 + duration: 656 + - id: "10_zed_attack_proxy_zap_tutorial_8_über_den_browser_angreifen" + title: "Über den Browser angreifen" + description: + type: mp4 + duration: 449 + - id: "10_zed_attack_proxy_zap_tutorial_9_der_marketplace" + title: "Der Marketplace" + description: + type: mp4 + duration: 184 + - id: "10_zed_attack_proxy_zap_tutorial_10_scripts_eine_kurze_einführung" + title: "Scripts eine kurze Einführung" + description: + type: mp4 + duration: 673 + - id: "10_zed_attack_proxy_zap_tutorial_11_kontexte_authentifikation_und_mehr" + title: "Kontexte - Authentifikation und mehr" + description: + type: mp4 + duration: 837 + - id: "10_zed_attack_proxy_zap_tutorial_12_diff_und_abschließende_worte" + title: "Diff und abschließende Worte" + description: + type: mp4 + duration: 259 diff --git a/academy_data/courses/serveradministration.yml b/academy_data/courses/serveradministration.yml new file mode 100644 index 00000000..b7916692 --- /dev/null +++ b/academy_data/courses/serveradministration.yml @@ -0,0 +1,114 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7orIal3z8bq8HlHxnN-CtXr +title: "Serveradministration Grundlagen" +description: "Ihr braucht einen eigenen Server, ihr wollt eine Nextcloud, eine Website oder einen Matrix-Server über den ihr die volle Kontrolle habt? Das und noch so viel mehr lernt ihr hier." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/bash.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665508394 +sections: + - id: section + title: "Serveradministration Grundlagen" + description: + lectures: + - id: "rkO6flF0VXs" + title: "Einen Server bei Hetzner mieten und sich via SSH verbinden" + description: + type: youtube + video_id: "rkO6flF0VXs" + duration: 1028 + - id: "exvPRLSWFSM" + title: "Eine Domain registrieren und einrichten" + description: + type: youtube + video_id: "exvPRLSWFSM" + duration: 640 + - id: "Irau2-w8ABE" + title: "Wichtige erste Schritte auf einem Server" + description: + type: youtube + video_id: "Irau2-w8ABE" + duration: 973 + - id: "lP61L0XgoVs" + title: "Mit Docker einen Nginx Reverse Proxy erstellen" + description: + type: youtube + video_id: "lP61L0XgoVs" + duration: 1032 + - id: "2G0ewKSozs0" + title: "Synapse Matrix Server installieren inklusive Federation" + description: + type: youtube + video_id: "2G0ewKSozs0" + duration: 1152 + - id: "UBAoqQ-15No" + title: "Proxmox auf einem Hetzner Server installieren" + description: + type: youtube + video_id: "UBAoqQ-15No" + duration: 1089 + - id: "uKGkw7KE0ng" + title: "OpnSense auf Proxmox installieren: Nur 1 IP [Hetzner Server]" + description: + type: youtube + video_id: "uKGkw7KE0ng" + duration: 3306 + - id: "GhaGO83VIz0" + title: "OpnSense auf Proxmox: IPv6 Setup [Hetzner Server]" + description: + type: youtube + video_id: "GhaGO83VIz0" + duration: 1799 + - id: "CguJd_I7jEI" + title: "Über SSH Port Forwarding - auch aus einer laufenden Session heraus" + description: + type: youtube + video_id: "CguJd_I7jEI" + duration: 771 + - id: "Mr80hEkYYqY" + title: "Remote Wireshark: SSHDump und Verbindungen auf dem Server beobachten" + description: + type: youtube + video_id: "Mr80hEkYYqY" + duration: 339 + - id: "xlI2EA9Q7Kc" + title: "TCPDump: Netzwerkverbindungen auf dem Server beobachten" + description: + type: youtube + video_id: "xlI2EA9Q7Kc" + duration: 551 + - id: "tVX2z85wGmg" + title: "OpnSense: VMs anlegen in Proxmox" + description: + type: youtube + video_id: "tVX2z85wGmg" + duration: 2836 + - id: "5D4U0kVxbJ4" + title: "Proxmox: Zertifikat via ACME.sh beantragen" + description: + type: youtube + video_id: "5D4U0kVxbJ4" + duration: 796 + - id: "O2CHWr_AQT0" + title: "OpnSense: TLS Zertifikat via ACME.sh" + description: + type: youtube + video_id: "O2CHWr_AQT0" + duration: 1214 + - id: "lGA3ifzAnRk" + title: "OpnSense: VPN zum Server" + description: + type: youtube + video_id: "lGA3ifzAnRk" + duration: 2026 + - id: "F9uMNMl-GAw" + title: "OpnSense: User Certificates für den VPN einrichten" + description: + type: youtube + video_id: "F9uMNMl-GAw" + duration: 813 diff --git a/academy_data/courses/signalverarbeitung.yml b/academy_data/courses/signalverarbeitung.yml new file mode 100644 index 00000000..a58014bb --- /dev/null +++ b/academy_data/courses/signalverarbeitung.yml @@ -0,0 +1,166 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7qvLZlbEiRwHoP0mbmAHNId +title: "Signalverarbeitung mit Python" +description: "Mit Python Biosignale auslesen - Stimme, Bilder aber auch EEG Werte? Ja aber natürlich geht das. Habt ihr was anderes erwartet?" +category: +language: de +image: https://static.bootstrap.academy/thumbnails/signalverarbeitung.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665506609 +sections: + - id: section + title: "Signalverarbeitung" + description: + lectures: + - id: "MI-_ioRdTuk" + title: "Sensoren und Signale" + description: + type: youtube + video_id: "MI-_ioRdTuk" + duration: 323 + - id: "S-dp5N7j62Q" + title: "Signale" + description: + type: youtube + video_id: "S-dp5N7j62Q" + duration: 584 + - id: "gi3J6YyWUN4" + title: "Determinismus und Stochastische Signale" + description: + type: youtube + video_id: "gi3J6YyWUN4" + duration: 228 + - id: "v5pYu2uTuPI" + title: "Quantisierung und Sampling" + description: + type: youtube + video_id: "v5pYu2uTuPI" + duration: 684 + - id: "mpw0WlHFVng" + title: "Beispiele in Audacity" + description: + type: youtube + video_id: "mpw0WlHFVng" + duration: 480 + - id: "FrcUzKukQy4" + title: "Beispiele für Bilder in Gimp" + description: + type: youtube + video_id: "FrcUzKukQy4" + duration: 406 + - id: "mnfGfrmuWUQ" + title: "Aliasing und das Shannonsche Abtasttheorem" + description: + type: youtube + video_id: "mnfGfrmuWUQ" + duration: 607 + - id: "xVIlUS8EUNE" + title: "Up- und Downsampling" + description: + type: youtube + video_id: "xVIlUS8EUNE" + duration: 651 + - id: "fYgO_KB9iO8" + title: "Tiefpassfilter" + description: + type: youtube + video_id: "fYgO_KB9iO8" + duration: 437 + - id: "tkMHyrEjY1M" + title: "Überlagerung und Filter veranschaulicht" + description: + type: youtube + video_id: "tkMHyrEjY1M" + duration: 429 + - id: "lo1RI2SKaOo" + title: "Der Frequenzbereich" + description: + type: youtube + video_id: "lo1RI2SKaOo" + duration: 217 + - id: "7RJdm_g0Nhc" + title: "Frequenzen in Audacity unter die Lupe genommen" + description: + type: youtube + video_id: "7RJdm_g0Nhc" + duration: 468 + - id: "kL8Mgebn80Y" + title: "Fourier Transformation" + description: + type: youtube + video_id: "kL8Mgebn80Y" + duration: 540 + - id: "6Famal0NdFg" + title: "Die Diskrete Fourier Transformation" + description: + type: youtube + video_id: "6Famal0NdFg" + duration: 359 + - id: "OcBVZsRODck" + title: "Windows und Hamming Window" + description: + type: youtube + video_id: "OcBVZsRODck" + duration: 436 + - id: "MoIRG27jD54" + title: "Mel und Mel Filterbanks" + description: + type: youtube + video_id: "MoIRG27jD54" + duration: 336 + - id: section2 + title: "Audio Verarbeitung in Python" + description: + lectures: + - id: "60G9rAmVM0A" + title: "Aufnahme" + description: + type: youtube + video_id: "60G9rAmVM0A" + duration: 428 + - id: "890tPu-nodQ" + title: "Einlesen und Abspielen" + description: + type: youtube + video_id: "890tPu-nodQ" + duration: 554 + - id: "njZNqH5C8Zk" + title: "Fenster auf dem Signal" + description: + type: youtube + video_id: "njZNqH5C8Zk" + duration: 1212 + - id: "m7tAnE4Kmoo" + title: "Fourier Transformation" + description: + type: youtube + video_id: "m7tAnE4Kmoo" + duration: 543 + - id: "NAs60THEgO0" + title: "Librosa" + description: + type: youtube + video_id: "NAs60THEgO0" + duration: 1013 + - id: "27Jl-pA2aDM" + title: "Filter" + description: + type: youtube + video_id: "27Jl-pA2aDM" + duration: 312 + - id: "khp73YQt0L0" + title: "Elektroenzephalografie" + description: + type: youtube + video_id: "khp73YQt0L0" + duration: 319 + - id: "LcSMGBrvFE8" + title: "Frequenzbänder im EEG und abschließende Worte" + description: + type: youtube + video_id: "LcSMGBrvFE8" + duration: 545 diff --git a/academy_data/courses/softskills.yml b/academy_data/courses/softskills.yml new file mode 100644 index 00000000..054099d0 --- /dev/null +++ b/academy_data/courses/softskills.yml @@ -0,0 +1,134 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7rC5g_bZNxZF6lOjSfNBKkE +title: "Softskills für Informatiker" +description: "Informatiker sitzen im Keller und reden nicht mit anderen? Da hast du wohl einigen Vorurteilen aufgesessen. Informatik und vor allem Softwareentwicklung ist mittlerweile fast schon ein sozialer Beruf! Furchtbar? Nein, das kann man lernen!" +category: +language: de +image: https://static.bootstrap.academy/thumbnails/softskills.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" + - name: "Tom Klein" + url: "https://www.tomklein.de/" +price: 5000 +learning_goals: [] +requirements: [] +last_update: 1666399091 +sections: + - id: section + title: "Softskills für Informatiker" + description: + lectures: + - id: "4vuFbfqv9P4" + title: "Einleitung" + description: + type: youtube + video_id: "4vuFbfqv9P4" + duration: 244 + - id: "B-DsxJjdHBU" + title: "Kalibration" + description: + type: youtube + video_id: "B-DsxJjdHBU" + duration: 625 + - id: "C5KyArMdmb0" + title: "Spiegeln" + description: + type: youtube + video_id: "C5KyArMdmb0" + duration: 417 + - id: "tqvRSRvlZKE" + title: "Feedback geben" + description: + type: youtube + video_id: "tqvRSRvlZKE" + duration: 781 + - id: "lxm9-NgpTtU" + title: "Framing" + description: + type: youtube + video_id: "lxm9-NgpTtU" + duration: 1183 + - id: "voP9-VO0Eto" + title: "Fragetechniken" + description: + type: youtube + video_id: "voP9-VO0Eto" + duration: 1091 + - id: "bAA_2euVt28" + title: "Zuhören" + description: + type: youtube + video_id: "bAA_2euVt28" + duration: 1275 + - id: "aAfwhMLO56s" + title: "Visualisieren" + description: + type: youtube + video_id: "aAfwhMLO56s" + duration: 798 + - id: "UXgSjo0NxyY" + title: "Konfliktmanagement: Definition" + description: + type: youtube + video_id: "UXgSjo0NxyY" + duration: 991 + - id: "qesypUWwBVk" + title: "Konfliktmanagement: Grundannahmen" + description: + type: youtube + video_id: "qesypUWwBVk" + duration: 1445 + - id: "smLgKIALcjo" + title: "Gruppendynamik" + description: + type: youtube + video_id: "smLgKIALcjo" + duration: 1099 + - id: "uikaPfxrTuc" + title: "Moderation" + description: + type: youtube + video_id: "uikaPfxrTuc" + duration: 496 + - id: "pJ9rL1DxFK0" + title: "Selbstreflexion" + description: + type: youtube + video_id: "pJ9rL1DxFK0" + duration: 1049 + - id: "lFAEw3Ti1gM" + title: "Kommunikationskontext erklärt" + description: + type: youtube + video_id: "lFAEw3Ti1gM" + duration: 1035 + - id: "MnMiIt1Nr68" + title: "Kontaktfähigkeit" + description: + type: youtube + video_id: "MnMiIt1Nr68" + duration: 785 + - id: "KK829x4FEr4" + title: "Verhandlungsfähigkeit" + description: + type: youtube + video_id: "KK829x4FEr4" + duration: 834 + - id: "IH_BtcH-Bvk" + title: "Product Entry Board" + description: + type: youtube + video_id: "IH_BtcH-Bvk" + duration: 1133 + - id: "yccek0Vout8" + title: "Retrospektive" + description: + type: youtube + video_id: "yccek0Vout8" + duration: 848 + - id: "S0VxFmj5FgA" + title: "Sprint Planning" + description: + type: youtube + video_id: "S0VxFmj5FgA" + duration: 855 diff --git a/academy_data/courses/softwareengineering.yml b/academy_data/courses/softwareengineering.yml new file mode 100644 index 00000000..d019e854 --- /dev/null +++ b/academy_data/courses/softwareengineering.yml @@ -0,0 +1,412 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7qNMn6zimfu4JPUklG-4Uu4 +title: "Softwareengineering - Grundlagen" +description: "Softwareentwickeln ist - so leid es mir tut, das sagen zu müssen - etwas völlig anderes als Programmieren. Es geht darum, den Code aus zig Modulen und zig Klassen in ein großes und ganzes zu gießen - und sich überhaupt mal darum Gedanken zu machen, was man eigentlich braucht. Software ist mittlerweile so hochkomplex, da muss das definitiv sein!" +category: +language: de +image: https://static.bootstrap.academy/thumbnails/softwareengineering.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665507210 +sections: + - id: section + title: "Modelle" + description: + lectures: + - id: "r4u_6OPHiMo" + title: "Einleitung" + description: + type: youtube + video_id: "r4u_6OPHiMo" + duration: 747 + - id: "TgXV_Lw-dBo" + title: "Das Wasserfallmodell" + description: + type: youtube + video_id: "TgXV_Lw-dBo" + duration: 400 + - id: "GZjdl_zf4LA" + title: "Scrum" + description: + type: youtube + video_id: "GZjdl_zf4LA" + duration: 941 + - id: "Q4a519zKeyg" + title: "Projektfindung" + description: + type: youtube + video_id: "Q4a519zKeyg" + duration: 272 + - id: "v3zzvFv1gME" + title: "Die Planungsphase" + description: + type: youtube + video_id: "v3zzvFv1gME" + duration: 459 + - id: "m5deYfB4Zn8" + title: "Requirements: Kategorien" + description: + type: youtube + video_id: "m5deYfB4Zn8" + duration: 380 + - id: "kTeEIdSd7-o" + title: "Der Entwurf" + description: + type: youtube + video_id: "kTeEIdSd7-o" + duration: 300 + - id: section2 + title: "Architekturen" + description: + lectures: + - id: "f2A-YfXjl_w" + title: "Die Architektur" + description: + type: youtube + video_id: "f2A-YfXjl_w" + duration: 281 + - id: "oP7bKkTQCYM" + title: "Separation of Concerns" + description: + type: youtube + video_id: "oP7bKkTQCYM" + duration: 293 + - id: "V70soZ4obBE" + title: "Single Responsibility und Information Hiding" + description: + type: youtube + video_id: "V70soZ4obBE" + duration: 283 + - id: "a8mTNpp9osg" + title: "Least Knowledge, YAGNI und DRY" + description: + type: youtube + video_id: "a8mTNpp9osg" + duration: 243 + - id: "2g_TRpBfROo" + title: "Die 3-Schichtenarchitektur" + description: + type: youtube + video_id: "2g_TRpBfROo" + duration: 452 + - id: "0vkZGWX73yc" + title: "Die 4-Schichtenarchitektur" + description: + type: youtube + video_id: "0vkZGWX73yc" + duration: 482 + - id: "r5CwZw6Vutc" + title: "Die 6-Schichtenarchitektur" + description: + type: youtube + video_id: "r5CwZw6Vutc" + duration: 279 + - id: "9OtDAgRnGYQ" + title: "Die Client-Server Architektur" + description: + type: youtube + video_id: "9OtDAgRnGYQ" + duration: 285 + - id: "_7FSgpV8FKI" + title: "SOA und REST" + description: + type: youtube + video_id: "_7FSgpV8FKI" + duration: 331 + - id: "gi8jcIIpVIw" + title: "Peer-2-Peer Architekturen" + description: + type: youtube + video_id: "gi8jcIIpVIw" + duration: 336 + - id: "qzNdyvzKtMg" + title: "Pipelines" + description: + type: youtube + video_id: "qzNdyvzKtMg" + duration: 315 + - id: "yAVBMEmx05k" + title: "Event-Driven Architecture" + description: + type: youtube + video_id: "yAVBMEmx05k" + duration: 179 + - id: "c_o_uJ-itz0" + title: "Frameworks und Plugins" + description: + type: youtube + video_id: "c_o_uJ-itz0" + duration: 200 + - id: "xK-nj3J1zXA" + title: "Model View Controller MVC" + description: + type: youtube + video_id: "xK-nj3J1zXA" + duration: 320 + - id: section3 + title: "Entwurfsmuster" + description: + lectures: + - id: "zVFtyuLFiXg" + title: "Entwurf und Muster" + description: + type: youtube + video_id: "zVFtyuLFiXg" + duration: 328 + - id: "bRHi1JOVGpI" + title: "Die Factory Method" + description: + type: youtube + video_id: "bRHi1JOVGpI" + duration: 258 + - id: "J5_nYHaJEsc" + title: "Das Prototype Pattern" + description: + type: youtube + video_id: "J5_nYHaJEsc" + duration: 213 + - id: "2JCIsj5hVBc" + title: "Das Abstract Factory Pattern" + description: + type: youtube + video_id: "2JCIsj5hVBc" + duration: 306 + - id: "dcdf3E9XO_Y" + title: "Das Builder Pattern" + description: + type: youtube + video_id: "dcdf3E9XO_Y" + duration: 239 + - id: "GUcWjYHmYhY" + title: "Dependency Injection" + description: + type: youtube + video_id: "GUcWjYHmYhY" + duration: 351 + - id: "gVaZvrLn48I" + title: "Object Pools" + description: + type: youtube + video_id: "gVaZvrLn48I" + duration: 236 + - id: "tBqj1ubwKts" + title: "Das Singleton" + description: + type: youtube + video_id: "tBqj1ubwKts" + duration: 208 + - id: "VKbbVmBpfpQ" + title: "Das Adapterpattern" + description: + type: youtube + video_id: "VKbbVmBpfpQ" + duration: 196 + - id: "q_2ShvmotFc" + title: "Der Decorator" + description: + type: youtube + video_id: "q_2ShvmotFc" + duration: 328 + - id: "TcEMjUmhRjI" + title: "Die Fassade" + description: + type: youtube + video_id: "TcEMjUmhRjI" + duration: 197 + - id: "mo8PRf0BPLE" + title: "Die Brücke/ Das Bridge Pattern" + description: + type: youtube + video_id: "mo8PRf0BPLE" + duration: 346 + - id: "N6nlWISC5is" + title: "Das Flyweight / Fliegengewicht Pattern" + description: + type: youtube + video_id: "N6nlWISC5is" + duration: 379 + - id: "Gpp4VK2K0tg" + title: "Das Proxy Pattern" + description: + type: youtube + video_id: "Gpp4VK2K0tg" + duration: 311 + - id: "TndId6Y3TGk" + title: "Das Observer Pattern aka Publish Subscribe" + description: + type: youtube + video_id: "TndId6Y3TGk" + duration: 340 + - id: "AC_sgvn48S0" + title: "Das Visitor Pattern" + description: + type: youtube + video_id: "AC_sgvn48S0" + duration: 400 + - id: "q_GSakzwr1A" + title: "Das Mediator Pattern" + description: + type: youtube + video_id: "q_GSakzwr1A" + duration: 201 + - id: "sgyg1fINd_c" + title: "Das Strategy Pattern" + description: + type: youtube + video_id: "sgyg1fINd_c" + duration: 250 + - id: "xaQfItxeFs4" + title: "Chain of Responsibility" + description: + type: youtube + video_id: "xaQfItxeFs4" + duration: 259 + - id: "XXFqKN-Uemc" + title: "Das Command Pattern" + description: + type: youtube + video_id: "XXFqKN-Uemc" + duration: 145 + - id: "Oh-AXdBgos8" + title: "Das Memento Pattern" + description: + type: youtube + video_id: "Oh-AXdBgos8" + duration: 159 + - id: "hZ9wPD32Y4w" + title: "Das Template Pattern" + description: + type: youtube + video_id: "hZ9wPD32Y4w" + duration: 220 + - id: "XdJuzSJhiag" + title: "Das Null Object" + description: + type: youtube + video_id: "XdJuzSJhiag" + duration: 164 + - id: "O5TVlmJGCjQ" + title: "Iteratoren" + description: + type: youtube + video_id: "O5TVlmJGCjQ" + duration: 258 + - id: "DhHgkF-1wF8" + title: "Interpreter" + description: + type: youtube + video_id: "DhHgkF-1wF8" + duration: 286 + - id: "fNNWjjMqLyc" + title: "Die GRASP - Patterns" + description: + type: youtube + video_id: "fNNWjjMqLyc" + duration: 611 + - id: "lc9LdxPKwxo" + title: "Das Transaction Script" + description: + type: youtube + video_id: "lc9LdxPKwxo" + duration: 314 + - id: "W-l5jh0LXW4" + title: "Das Table Module" + description: + type: youtube + video_id: "W-l5jh0LXW4" + duration: 228 + - id: "HaYhtv5BaeU" + title: "Das Domain Module" + description: + type: youtube + video_id: "HaYhtv5BaeU" + duration: 203 + - id: "arf_2v02Fk0" + title: "Das Record Set" + description: + type: youtube + video_id: "arf_2v02Fk0" + duration: 296 + - id: "5bf-QpLMon0" + title: "Table Data Gateway" + description: + type: youtube + video_id: "5bf-QpLMon0" + duration: 192 + - id: "geVT4x-OMYI" + title: "Active Records" + description: + type: youtube + video_id: "geVT4x-OMYI" + duration: 330 + - id: "DaL3ygRX-Xo" + title: "Row Data Gateway" + description: + type: youtube + video_id: "DaL3ygRX-Xo" + duration: 327 + - id: "7k7Ygm4ARV8" + title: "Single Table Inheritance" + description: + type: youtube + video_id: "7k7Ygm4ARV8" + duration: 297 + - id: "LDEf9r9oixs" + title: "Class Table Inheritance" + description: + type: youtube + video_id: "LDEf9r9oixs" + duration: 342 + - id: "cbR8GGwi2-Y" + title: "Concrete Table Inheritance" + description: + type: youtube + video_id: "cbR8GGwi2-Y" + duration: 415 + - id: "ODEVZQJbEl0" + title: "Die Implementierungsphase: UML in Code umwandeln" + description: + type: youtube + video_id: "ODEVZQJbEl0" + duration: 441 + - id: section4 + title: "Testen" + description: + lectures: + - id: "d4gZ89r1_YU" + title: "Testen" + description: + type: youtube + video_id: "d4gZ89r1_YU" + duration: 646 + - id: "TwQ31FmPBMA" + title: "Test-Abdeckungen" + description: + type: youtube + video_id: "TwQ31FmPBMA" + duration: 323 + - id: "e9VHgl95qsc" + title: "Kontrollflussgraphen" + description: + type: youtube + video_id: "e9VHgl95qsc" + duration: 324 + - id: section5 + title: "Bonus" + description: + lectures: + - id: "kg3tpBy4YlQ" + title: "Microservice Architekturen" + description: + type: youtube + video_id: "kg3tpBy4YlQ" + duration: 549 + - id: "4u4x4Zg5Zpg" + title: "Aufgaben besser verwalten: Top KANBAN-Boards im Vergleich" + description: + type: youtube + video_id: "4u4x4Zg5Zpg" + duration: 2068 diff --git a/academy_data/courses/spark_pyspark.yml b/academy_data/courses/spark_pyspark.yml new file mode 100644 index 00000000..2abf7c04 --- /dev/null +++ b/academy_data/courses/spark_pyspark.yml @@ -0,0 +1,108 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7pkk8-Yxa7mjAqi_E9DE_Z9 +title: "Spark und PySpark" +description: "Data Science im ganz großen Stil? Da wirst du vermutlich mehr als einen Server brauchen.. und das muss man erstmal implementieren." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/python.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 3000 +learning_goals: [] +requirements: [] +last_update: 1665508416 +sections: + - id: section + title: "Spark und PySpark" + description: + lectures: + - id: "GbQKhMmfsKE" + title: "Einleitung und Motivation" + description: + type: youtube + video_id: "GbQKhMmfsKE" + duration: 844 + - id: "JVuaK8ivKiM" + title: "Installation" + description: + type: youtube + video_id: "JVuaK8ivKiM" + duration: 379 + - id: "oKrS5sd-V3E" + title: "Beispieldaten" + description: + type: youtube + video_id: "oKrS5sd-V3E" + duration: 619 + - id: "nOxrBzUUEcw" + title: "DataFrame: Grundlagen" + description: + type: youtube + video_id: "nOxrBzUUEcw" + duration: 418 + - id: "eXtO-CsAQMY" + title: "eigene Schemas" + description: + type: youtube + video_id: "eXtO-CsAQMY" + duration: 428 + - id: "81t6mcAl9OQ" + title: "Mit Dataframes arbeiten" + description: + type: youtube + video_id: "81t6mcAl9OQ" + duration: 785 + - id: "iBvOxJeww8k" + title: "SQL" + description: + type: youtube + video_id: "iBvOxJeww8k" + duration: 272 + - id: "3_WVsntFqI0" + title: "Daten selektieren" + description: + type: youtube + video_id: "3_WVsntFqI0" + duration: 634 + - id: "8aj0o74ibCQ" + title: "Groupby" + description: + type: youtube + video_id: "8aj0o74ibCQ" + duration: 910 + - id: "IER3vADVs74" + title: "Missing Data" + description: + type: youtube + video_id: "IER3vADVs74" + duration: 672 + - id: "4sKsKFUJAcc" + title: "Datum" + description: + type: youtube + video_id: "4sKsKFUJAcc" + duration: 516 + - id: "4DPVrmE9N1I" + title: "Lineare Regression" + description: + type: youtube + video_id: "4DPVrmE9N1I" + duration: 1259 + - id: "0tpCiSxGcOM" + title: "Kaufverhalten analysieren mit K Means" + description: + type: youtube + video_id: "0tpCiSxGcOM" + duration: 819 + - id: "Wnmq1GFhHXg" + title: "Spark im Cluster nutzen" + description: + type: youtube + video_id: "Wnmq1GFhHXg" + duration: 515 + - id: "gziO9FV3yqI" + title: "Praxisprojekt: Ähnliche Lieder auf Spotify" + description: + type: youtube + video_id: "gziO9FV3yqI" + duration: 1712 diff --git a/academy_data/courses/sql_und_datenbanken.yml b/academy_data/courses/sql_und_datenbanken.yml new file mode 100644 index 00000000..55c62502 --- /dev/null +++ b/academy_data/courses/sql_und_datenbanken.yml @@ -0,0 +1,132 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7qYPusTRflv3tkzhYoT-KiB +title: "Datenbanken und die Structured Query Language SQL" +description: "Datenbanken braucht es einfach immer. Daten speichern, Daten holen, wir können ja nicht alles für immer zwischenspeichern. Und Datenbanken werden mit SQL angesprochen." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/sql.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665507383 +sections: + - id: section + title: "Grundlagen" + description: + lectures: + - id: "1HLgKobzNZk" + title: "Einführung in SQL und Datenbanken" + description: + type: youtube + video_id: "1HLgKobzNZk" + duration: 355 + - id: "WEV5sjgH34Q" + title: "MySQL Installation" + description: + type: youtube + video_id: "WEV5sjgH34Q" + duration: 550 + - id: "kiy8F5uw7vU" + title: "Object Relational Mapping" + description: + type: youtube + video_id: "kiy8F5uw7vU" + duration: 432 + - id: section2 + title: "SQL Grundlagen" + description: + lectures: + - id: "RQPznV3LZW8" + title: "Einführung in SQL und Datenbanken" + description: + type: youtube + video_id: "RQPznV3LZW8" + duration: 500 + - id: "Y_cBipGdf-k" + title: "Distinct und Where" + description: + type: youtube + video_id: "Y_cBipGdf-k" + duration: 674 + - id: "rbQ67RynV_g" + title: "AND und OR, Order By" + description: + type: youtube + video_id: "rbQ67RynV_g" + duration: 456 + - id: "n-TVepjRR5Y" + title: "Einfügen, Verändern und Löschen" + description: + type: youtube + video_id: "n-TVepjRR5Y" + duration: 543 + - id: "G8bQATIsb44" + title: "Null und Like" + description: + type: youtube + video_id: "G8bQATIsb44" + duration: 573 + - id: "eo1Yg00gOVQ" + title: "geschachtelte Suchanfragen mit IN" + description: + type: youtube + video_id: "eo1Yg00gOVQ" + duration: 361 + - id: "NjTg1of8qK8" + title: "Tabellen erstellen und Datentypen" + description: + type: youtube + video_id: "NjTg1of8qK8" + duration: 844 + - id: section3 + title: "Arbeiten mit mehreren Tabellen" + description: + lectures: + - id: "1ZDao9-nfro" + title: "Assoziationen zwischen Tabellen" + description: + type: youtube + video_id: "1ZDao9-nfro" + duration: 507 + - id: "4jYsByLUScY" + title: "Primary und Foreign Keys, Not Null" + description: + type: youtube + video_id: "4jYsByLUScY" + duration: 617 + - id: "a6oAfRTTZmQ" + title: "Tabelle ändern, Autoincrement" + description: + type: youtube + video_id: "a6oAfRTTZmQ" + duration: 375 + - id: "vzjSvjB_UaM" + title: "Joins" + description: + type: youtube + video_id: "vzjSvjB_UaM" + duration: 588 + - id: section4 + title: "Tipps und Tricks" + description: + lectures: + - id: "OY65bU_uNGI" + title: "SQL-built-in Funktionen" + description: + type: youtube + video_id: "OY65bU_uNGI" + duration: 725 + - id: "X4M7XS8lwPE" + title: "SQLite als leichter Einstieg ins Thema Datenbanken" + description: + type: youtube + video_id: "X4M7XS8lwPE" + duration: 596 + - id: "1CRCH_8I_xY" + title: "Relationale DBMS im Vergleich" + description: + type: youtube + video_id: "1CRCH_8I_xY" + duration: 772 diff --git a/academy_data/courses/threejs.yml b/academy_data/courses/threejs.yml new file mode 100644 index 00000000..be4f97f8 --- /dev/null +++ b/academy_data/courses/threejs.yml @@ -0,0 +1,150 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7rrmmZEVGA4GfLLNLlGipWo +title: "Three.js - 3D Animationen im Browser" +description: "Wunderschöne 3D Animationen im Browser, vielleicht sogar 3D Spiele? Das geht! Eine Möglichkeit ist ThreeJS." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/threejs.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665508437 +sections: + - id: section + title: "Three.js - 3D Animationen im Browser" + description: + lectures: + - id: "EYkoGizZnss" + title: "3D entwickeln für den Browser" + description: + type: youtube + video_id: "EYkoGizZnss" + duration: 548 + - id: "FqK1tOillbE" + title: "Setup" + description: + type: youtube + video_id: "FqK1tOillbE" + duration: 1137 + - id: "fHklmbY_cyc" + title: "Die erste Szene" + description: + type: youtube + video_id: "fHklmbY_cyc" + duration: 724 + - id: "W4oLhi9HHlI" + title: "Objekte in der Szene" + description: + type: youtube + video_id: "W4oLhi9HHlI" + duration: 840 + - id: "b6sft8PEs5o" + title: "Der Boden" + description: + type: youtube + video_id: "b6sft8PEs5o" + duration: 637 + - id: "f6YXv363b6M" + title: "Die Renderschleife" + description: + type: youtube + video_id: "f6YXv363b6M" + duration: 483 + - id: "NB0GU2rXhCU" + title: "Unsere erste Animation" + description: + type: youtube + video_id: "NB0GU2rXhCU" + duration: 563 + - id: "JnhN8fXBawI" + title: "Phong Shading" + description: + type: youtube + video_id: "JnhN8fXBawI" + duration: 403 + - id: "J5Iob6v18ZA" + title: "Schatten" + description: + type: youtube + video_id: "J5Iob6v18ZA" + duration: 218 + - id: "QqeiNpkC4fI" + title: "Weitere Lichtquellen und Objekte" + description: + type: youtube + video_id: "QqeiNpkC4fI" + duration: 923 + - id: "EkWL7jn8YsE" + title: "drehbare Kamera" + description: + type: youtube + video_id: "EkWL7jn8YsE" + duration: 338 + - id: "ej6Sfm6oA-k" + title: "Dat.GUI" + description: + type: youtube + video_id: "ej6Sfm6oA-k" + duration: 294 + - id: "Z8TVeEGGZC8" + title: "Tastatur Eingaben" + description: + type: youtube + video_id: "Z8TVeEGGZC8" + duration: 354 + - id: "TbE5pAaoL7g" + title: "Die Clock" + description: + type: youtube + video_id: "TbE5pAaoL7g" + duration: 284 + - id: "FE55Yhv0u6g" + title: "Texturen" + description: + type: youtube + video_id: "FE55Yhv0u6g" + duration: 712 + - id: "kZSHYe7Oa-g" + title: "Hintergrund" + description: + type: youtube + video_id: "kZSHYe7Oa-g" + duration: 809 + - id: "x3GQuTE76uc" + title: "Objekte laden" + description: + type: youtube + video_id: "x3GQuTE76uc" + duration: 775 + - id: "KYWsvIdKygI" + title: "Bewegung" + description: + type: youtube + video_id: "KYWsvIdKygI" + duration: 467 + - id: "w38ttnJ8HDI" + title: "Partikeleffekte" + description: + type: youtube + video_id: "w38ttnJ8HDI" + duration: 493 + - id: "cEuEy1b9VUs" + title: "Animation der Partikel" + description: + type: youtube + video_id: "cEuEy1b9VUs" + duration: 483 + - id: "5llCk-ItC6s" + title: "Mit ES6 arbeiten" + description: + type: youtube + video_id: "5llCk-ItC6s" + duration: 399 + - id: "CB7zKq2whJk" + title: "Physik" + description: + type: youtube + video_id: "CB7zKq2whJk" + duration: 1433 diff --git a/academy_data/courses/typescript.yml b/academy_data/courses/typescript.yml new file mode 100644 index 00000000..5fd0842c --- /dev/null +++ b/academy_data/courses/typescript.yml @@ -0,0 +1,138 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7pwHqtQSBXGBUNkyGGOJQXf +title: "TypeScript: Volle Typisierung für JavaScript" +description: "Was ist das größte Problem von JavaScript? Viele werden hier 'keine Typisierung' schreien. Und deswegen gibt's TypeScript. TypeScript ist mittlerweile so verbreitet, dass die allermeisten großen Webframeworks es genauso wie JavaScript unterstützen." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/typescript.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665508373 +sections: + - id: section + title: "TypeScript Grundlagen" + description: + lectures: + - id: "uo4PWU-R96k" + title: "Die Rettung für JavaScript" + description: + type: youtube + video_id: "uo4PWU-R96k" + duration: 799 + - id: "_4znAuh0peo" + title: "Die IDE" + description: + type: youtube + video_id: "_4znAuh0peo" + duration: 332 + - id: "H4GV9IbjuuU" + title: "Typen" + description: + type: youtube + video_id: "H4GV9IbjuuU" + duration: 815 + - id: "GIPILAlhs78" + title: "Unions" + description: + type: youtube + video_id: "GIPILAlhs78" + duration: 233 + - id: "TitI78lrqPs" + title: "Klassen für JavaScript" + description: + type: youtube + video_id: "TitI78lrqPs" + duration: 481 + - id: "mti14uqp3Ro" + title: "Methoden und Konstruktoren" + description: + type: youtube + video_id: "mti14uqp3Ro" + duration: 643 + - id: "ACLqaZiFUX0" + title: "Vererbung" + description: + type: youtube + video_id: "ACLqaZiFUX0" + duration: 547 + - id: "qRZYRXbvqQs" + title: "Überschreiben von Methoden" + description: + type: youtube + video_id: "qRZYRXbvqQs" + duration: 601 + - id: "ex65d0lVe_s" + title: "Interfaces" + description: + type: youtube + video_id: "ex65d0lVe_s" + duration: 735 + - id: "FsDZBmKdbu0" + title: "static" + description: + type: youtube + video_id: "FsDZBmKdbu0" + duration: 253 + - id: "LFhROzaypAA" + title: "Zugriffsmodifikatoren" + description: + type: youtube + video_id: "LFhROzaypAA" + duration: 580 + - id: "65FKflmpxfA" + title: "Enums" + description: + type: youtube + video_id: "65FKflmpxfA" + duration: 245 + - id: "crYmfViwgGI" + title: "Generics" + description: + type: youtube + video_id: "crYmfViwgGI" + duration: 524 + - id: "BZEfP2pBE7I" + title: "Generische Klassen und Constraints" + description: + type: youtube + video_id: "BZEfP2pBE7I" + duration: 551 + - id: "WOo8SQyBkxQ" + title: "Mehrere Generics" + description: + type: youtube + video_id: "WOo8SQyBkxQ" + duration: 174 + - id: "nOfG4RvoUkI" + title: "Symbols" + description: + type: youtube + video_id: "nOfG4RvoUkI" + duration: 442 + - id: "IiZaeAlTMgQ" + title: "For-of-Schleifen" + description: + type: youtube + video_id: "IiZaeAlTMgQ" + duration: 167 + - id: "JwXejWa_4yo" + title: "Module" + description: + type: youtube + video_id: "JwXejWa_4yo" + duration: 421 + - id: "P_v-i7Az-O0" + title: "Mehr zu Modulen" + description: + type: youtube + video_id: "P_v-i7Az-O0" + duration: 419 + - id: "TjNViF9M22k" + title: "Default Exports" + description: + type: youtube + video_id: "TjNViF9M22k" + duration: 269 diff --git a/academy_data/courses/uml.yml b/academy_data/courses/uml.yml new file mode 100644 index 00000000..26c89322 --- /dev/null +++ b/academy_data/courses/uml.yml @@ -0,0 +1,102 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7oC7U6tm0BOnGg1R9ont0Vo +title: "UML - Unified Modeling Language" +description: "Ihr versucht gerade eure Software zu definieren und malt einfach drauf los? Ja.. schwierig. Denn für sowas gibt's Standards, damit jeder auch dasselbe versteht wie ihr. Und das ist UML." +category: +language: de +image: https://static.bootstrap.academy/thumbnails/uml.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665508356 +sections: + - id: section + title: "Klassendiagramme" + description: + lectures: + - id: "PdlP8gzpRyo" + title: "Einleitung" + description: + type: youtube + video_id: "PdlP8gzpRyo" + duration: 718 + - id: "F5k1u5mzZ3U" + title: "Klassendiagrammen" + description: + type: youtube + video_id: "F5k1u5mzZ3U" + duration: 475 + - id: "fQZOFYuLd-k" + title: "Vererbung" + description: + type: youtube + video_id: "fQZOFYuLd-k" + duration: 601 + - id: "fO7YTqZWZNQ" + title: "Assoziationen" + description: + type: youtube + video_id: "fO7YTqZWZNQ" + duration: 491 + - id: "JvJjOZR6q9s" + title: "Assoziationsklassen" + description: + type: youtube + video_id: "JvJjOZR6q9s" + duration: 234 + - id: "WKKZo1tiOy0" + title: "Aggregationen" + description: + type: youtube + video_id: "WKKZo1tiOy0" + duration: 259 + - id: "uSrBTr7d_g8" + title: "reflexive Assoziationen" + description: + type: youtube + video_id: "uSrBTr7d_g8" + duration: 504 + - id: section2 + title: "OCL - Object Constraint Language" + description: + lectures: + - id: "7sluwA4RSoU" + title: "OCL - Object Constraint Language" + description: + type: youtube + video_id: "7sluwA4RSoU" + duration: 782 + - id: section3 + title: "Aktivitätsdiagramme" + description: + lectures: + - id: "FdH51Ujp-GU" + title: "Aktivitätsdiagramme" + description: + type: youtube + video_id: "FdH51Ujp-GU" + duration: 761 + - id: "XClT7gR6hz0" + title: "Swim Lanes und Nebenläufigkeit" + description: + type: youtube + video_id: "XClT7gR6hz0" + duration: 472 + - id: section4 + title: "Weitere Diagramme" + description: + lectures: + - id: "L_auS6pd_l0" + title: "Sequenzdiagramme" + description: + type: youtube + video_id: "L_auS6pd_l0" + duration: 808 + - id: "dYfr5Opkw38" + title: "Use Case Diagramme" + description: + type: youtube + video_id: "dYfr5Opkw38" + duration: 649 diff --git a/academy_data/courses/unreal_engine.yml b/academy_data/courses/unreal_engine.yml new file mode 100644 index 00000000..3c936901 --- /dev/null +++ b/academy_data/courses/unreal_engine.yml @@ -0,0 +1,474 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7olLCliQ05e6hvEOl6sbBgv +title: "Unreal Engine 4" +description: "Ihr wolltet schon immer mal Spiele entwickeln? Eine der bekanntesten Engines überhaupt - und dazu bis zu einem gewissen Wert noch völlig kostenlos - ist die Unreal Engine 4!" +category: +language: de +image: https://static.bootstrap.academy/thumbnails/unrealengine.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665508182 +sections: + - id: section + title: "Einleitung" + description: + lectures: + - id: "U7Cs3gkelAU" + title: "Spiele programmieren lernen" + description: + type: youtube + video_id: "U7Cs3gkelAU" + duration: 749 + - id: "tF5svOY4PNc" + title: "Das Interface" + description: + type: youtube + video_id: "tF5svOY4PNc" + duration: 650 + - id: "p42u7MAIt-U" + title: "Objekte verschieben, rotieren und skalieren" + description: + type: youtube + video_id: "p42u7MAIt-U" + duration: 698 + - id: "NrDyqJLdI3E" + title: "Der Contentbrowser" + description: + type: youtube + video_id: "NrDyqJLdI3E" + duration: 404 + - id: "EzhKSA3dUM0" + title: "Wände und Türen" + description: + type: youtube + video_id: "EzhKSA3dUM0" + duration: 635 + - id: "co2x9BvBiaE" + title: "ein bisschen Leveldesign" + description: + type: youtube + video_id: "co2x9BvBiaE" + duration: 672 + - id: "HMm6tm8a9ss" + title: "Blueprints" + description: + type: youtube + video_id: "HMm6tm8a9ss" + duration: 551 + - id: "_XTeus4-Sys" + title: "Animationen" + description: + type: youtube + video_id: "_XTeus4-Sys" + duration: 642 + - id: "NOdXRoz7Vqc" + title: "Licht an- und ausschalten" + description: + type: youtube + video_id: "NOdXRoz7Vqc" + duration: 568 + - id: section2 + title: "Blueprints" + description: + lectures: + - id: "DjrkcHDpCJI" + title: "class-Blueprints" + description: + type: youtube + video_id: "DjrkcHDpCJI" + duration: 756 + - id: "4MJ__5kg9js" + title: "Construction Scripts" + description: + type: youtube + video_id: "4MJ__5kg9js" + duration: 606 + - id: "Ufd0uC9UWzs" + title: "grundlegende Typen" + description: + type: youtube + video_id: "Ufd0uC9UWzs" + duration: 668 + - id: "0aFNN-rWUEU" + title: "lokales und Weltkoordinatensystem" + description: + type: youtube + video_id: "0aFNN-rWUEU" + duration: 404 + - id: "tn7Yh7BnGfo" + title: "Benutzereingaben" + description: + type: youtube + video_id: "tn7Yh7BnGfo" + duration: 503 + - id: "TshNQ-OAd3A" + title: "Arrays" + description: + type: youtube + video_id: "TshNQ-OAd3A" + duration: 586 + - id: "D2uClHdDvtA" + title: "For-Schleifen" + description: + type: youtube + video_id: "D2uClHdDvtA" + duration: 615 + - id: "_L4YJVTJ33I" + title: "While-Schleifen" + description: + type: youtube + video_id: "_L4YJVTJ33I" + duration: 677 + - id: "d0wP44wdsVM" + title: "Projektile und Spawnen von Actors" + description: + type: youtube + video_id: "d0wP44wdsVM" + duration: 949 + - id: "8djYpTpRCeU" + title: "Custom Events und Kommunikation zwischen Blueprints" + description: + type: youtube + video_id: "8djYpTpRCeU" + duration: 692 + - id: "KaZ-Mdx3nZA" + title: "Physics Actor" + description: + type: youtube + video_id: "KaZ-Mdx3nZA" + duration: 614 + - id: "xfQs7s9knQY" + title: "Debugging und Breakpoints" + description: + type: youtube + video_id: "xfQs7s9knQY" + duration: 366 + - id: "_LAFT9qMCPg" + title: "Expose On Spawn" + description: + type: youtube + video_id: "_LAFT9qMCPg" + duration: 273 + - id: section3 + title: "Models" + description: + lectures: + - id: "wMak9zJDGgE" + title: "Models importieren" + description: + type: youtube + video_id: "wMak9zJDGgE" + duration: 492 + - id: "zA_1bMP7DN0" + title: "Animationen Basics und Skelette" + description: + type: youtube + video_id: "zA_1bMP7DN0" + duration: 595 + - id: "EtQbFvC_A8g" + title: "Inputs aufsetzen" + description: + type: youtube + video_id: "EtQbFvC_A8g" + duration: 503 + - id: "qRxDEc9BQhk" + title: "Blend Spaces" + description: + type: youtube + video_id: "qRxDEc9BQhk" + duration: 415 + - id: "hq3cNy3E_TA" + title: "Animation Blueprints" + description: + type: youtube + video_id: "hq3cNy3E_TA" + duration: 397 + - id: "9oEwVK7vleI" + title: "Der Animation Graph und Automaten" + description: + type: youtube + video_id: "9oEwVK7vleI" + duration: 1142 + - id: "7cLx6e9I0RM" + title: "Der Event Graph der Animation" + description: + type: youtube + video_id: "7cLx6e9I0RM" + duration: 497 + - id: "wzhmp6FFlWM" + title: "Der Character Blueprint" + description: + type: youtube + video_id: "wzhmp6FFlWM" + duration: 673 + - id: "A7MFmNalNLQ" + title: "Character Input" + description: + type: youtube + video_id: "A7MFmNalNLQ" + duration: 736 + - id: section4 + title: "Wichtige Tricks" + description: + lectures: + - id: "3qL9xUlWEms" + title: "Game Modes und unsere Arbeit in Action" + description: + type: youtube + video_id: "3qL9xUlWEms" + duration: 511 + - id: "r8PZLltUSF4" + title: "Checkpoints und Schaden" + description: + type: youtube + video_id: "r8PZLltUSF4" + duration: 700 + - id: "G5vHGU-IYYc" + title: "ein einfaches HUD" + description: + type: youtube + video_id: "G5vHGU-IYYc" + duration: 958 + - id: "eEYiDaxsE00" + title: "Spielstände speichern" + description: + type: youtube + video_id: "eEYiDaxsE00" + duration: 664 + - id: section5 + title: "Licht, Schatten, Materials und Reflektionen" + description: + lectures: + - id: "WsxMPlkYKac" + title: "Volumetrischer Nebel" + description: + type: youtube + video_id: "WsxMPlkYKac" + duration: 518 + - id: "uDO-mUcPQN8" + title: "Reflektionen und Reflektionskugeln" + description: + type: youtube + video_id: "uDO-mUcPQN8" + duration: 231 + - id: "2S-PzSS4QJs" + title: "Lichtkegel und Blooming" + description: + type: youtube + video_id: "2S-PzSS4QJs" + duration: 229 + - id: "U5osb8OK3FY" + title: "Materials Einleitung" + description: + type: youtube + video_id: "U5osb8OK3FY" + duration: 463 + - id: "j6PT0NhEfgM" + title: "Texturen, Normalen und Blending" + description: + type: youtube + video_id: "j6PT0NhEfgM" + duration: 831 + - id: "1BR_xcPhjOA" + title: "Lava - zeitgebundene Materialien / Panner" + description: + type: youtube + video_id: "1BR_xcPhjOA" + duration: 685 + - id: "Y3LNBO0GLKg" + title: "Parallax Mapping / Texturen mit Höheninformationen" + description: + type: youtube + video_id: "Y3LNBO0GLKg" + duration: 640 + - id: "el1qqePYedA" + title: "Transluzente Materialien (Lavaglas =) )" + description: + type: youtube + video_id: "el1qqePYedA" + duration: 364 + - id: "z8KAle7Q-bA" + title: "Schnee und Materialfunktionen" + description: + type: youtube + video_id: "z8KAle7Q-bA" + duration: 715 + - id: "yPA8k-KIL38" + title: "Schnee als Layered Material" + description: + type: youtube + video_id: "yPA8k-KIL38" + duration: 481 + - id: "EJbtQzR8U-A" + title: "Detail Textures" + description: + type: youtube + video_id: "EJbtQzR8U-A" + duration: 545 + - id: "RbVODlyXxKA" + title: "Distance based Detail Texturing" + description: + type: youtube + video_id: "RbVODlyXxKA" + duration: 693 + - id: "wQjknJ-w8sw" + title: "Strahlende Materials und Materialinstances" + description: + type: youtube + video_id: "wQjknJ-w8sw" + duration: 646 + - id: "wyu0XyuzmQQ" + title: "Fresnel Effekte" + description: + type: youtube + video_id: "wyu0XyuzmQQ" + duration: 339 + - id: "A-phLQUILQw" + title: "Partikelsysteme" + description: + type: youtube + video_id: "A-phLQUILQw" + duration: 799 + - id: "OCFxIcCtpsQ" + title: "Level Of Detail im Partikelsystem" + description: + type: youtube + video_id: "OCFxIcCtpsQ" + duration: 502 + - id: "z5bJHLxnrDE" + title: "Der Curve Editor" + description: + type: youtube + video_id: "z5bJHLxnrDE" + duration: 587 + - id: section6 + title: "Zwischensequenzen mit dem Sequencer" + description: + lectures: + - id: "7REjwKwgzDQ" + title: "Einleitung" + description: + type: youtube + video_id: "7REjwKwgzDQ" + duration: 663 + - id: "euDMa2wDs84" + title: "Shots und Subsequences" + description: + type: youtube + video_id: "euDMa2wDs84" + duration: 537 + - id: "9IRVb1oOS2M" + title: "Subscenes und Animationen" + description: + type: youtube + video_id: "9IRVb1oOS2M" + duration: 912 + - id: "jjE5TiOvhD0" + title: "Cameras" + description: + type: youtube + video_id: "jjE5TiOvhD0" + duration: 908 + - id: "E-BDFuki1xA" + title: "Slow Motion und weitere Tricks" + description: + type: youtube + video_id: "E-BDFuki1xA" + duration: 459 + - id: "_bsvXpOre3M" + title: "Takes" + description: + type: youtube + video_id: "_bsvXpOre3M" + duration: 337 + - id: "QojDo0I0IyM" + title: "Exportieren und Rendern der Sequenz" + description: + type: youtube + video_id: "QojDo0I0IyM" + duration: 434 + - id: "whmnpxlSoFo" + title: "Der Master Sequencer" + description: + type: youtube + video_id: "whmnpxlSoFo" + duration: 167 + - id: "vQ430KHy3mU" + title: "Fades und Ton" + description: + type: youtube + video_id: "vQ430KHy3mU" + duration: 293 + - id: "AaGPfOMdEU4" + title: "Kamerafahrten und Tracking" + description: + type: youtube + video_id: "AaGPfOMdEU4" + duration: 460 + - id: "0Sz3gUuj6zw" + title: "Sequences aus Blueprints auslösen" + description: + type: youtube + video_id: "0Sz3gUuj6zw" + duration: 338 + - id: "H6X31sfRbcc" + title: "Events aus Sequences" + description: + type: youtube + video_id: "H6X31sfRbcc" + duration: 283 + - id: section7 + title: "Paper2D" + description: + lectures: + - id: "-ANulmE9yEU" + title: "Einleitung" + description: + type: youtube + video_id: "-ANulmE9yEU" + duration: 414 + - id: "fuz09-B-Vbc" + title: "Paper2D - Das Prototype Material" + description: + type: youtube + video_id: "fuz09-B-Vbc" + duration: 602 + - id: "uEhYYzZYZSw" + title: "Level Layout" + description: + type: youtube + video_id: "uEhYYzZYZSw" + duration: 606 + - id: "_8lvWOPF7B8" + title: "Sprites, Physik, Collision und Rendering" + description: + type: youtube + video_id: "_8lvWOPF7B8" + duration: 601 + - id: "Rltg-nXHl0k" + title: "Flipbook Animationen" + description: + type: youtube + video_id: "Rltg-nXHl0k" + duration: 438 + - id: "3jGTaq2qWpQ" + title: "Der PlayerBlueprint" + description: + type: youtube + video_id: "3jGTaq2qWpQ" + duration: 760 + - id: "PpKUOxh2C3Y" + title: "Input und Bewegung" + description: + type: youtube + video_id: "PpKUOxh2C3Y" + duration: 590 + - id: "D8Q-JsBqgpU" + title: "Animation umschalten" + description: + type: youtube + video_id: "D8Q-JsBqgpU" + duration: 343 diff --git a/academy_data/courses/windows10.yml b/academy_data/courses/windows10.yml new file mode 100644 index 00000000..01b30fa9 --- /dev/null +++ b/academy_data/courses/windows10.yml @@ -0,0 +1,84 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7rRSgXNzZMV3XlrfklBugNW +title: "Windows lernen - Kommandozeile und mehr" +description: "Wir alle nutzen Windows irgendwann in unserem Leben. Und vermutlich sollten wir es dann schon zu nutzen lernen!" +category: +language: de +image: https://static.bootstrap.academy/thumbnails/windows.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665507370 +sections: + - id: section + title: "Grundlagen" + description: + lectures: + - id: "xnF2ZnYPIOc" + title: "Einleitung" + description: + type: youtube + video_id: "xnF2ZnYPIOc" + duration: 317 + - id: "vWlwHLgdNBU" + title: "ipconfig" + description: + type: youtube + video_id: "vWlwHLgdNBU" + duration: 208 + - id: "s6HmUeYefuE" + title: "Erstellen und Löschen von Verzeichnissen" + description: + type: youtube + video_id: "s6HmUeYefuE" + duration: 232 + - id: "wtvCi6ytnxs" + title: "Dateien löschen, erstellen, anhängen und Pipes" + description: + type: youtube + video_id: "wtvCi6ytnxs" + duration: 519 + - id: "3NEpD_mYcvM" + title: "Dateien verschieben, kopieren, Datenträger und Farbe" + description: + type: youtube + video_id: "3NEpD_mYcvM" + duration: 288 + - id: "01pu4Euw9Ng" + title: "Speichern von Outputs" + description: + type: youtube + video_id: "01pu4Euw9Ng" + duration: 245 + - id: "6app-3MmjVI" + title: "cls und mehrere Commands auf einmal ausführen" + description: + type: youtube + video_id: "6app-3MmjVI" + duration: 160 + - id: "Jd_5Zr6qoO8" + title: "Der Registrierungseditor und Autostart unter Windows" + description: + type: youtube + video_id: "Jd_5Zr6qoO8" + duration: 506 + - id: "vf62tjS6v9E" + title: "Registrierungseditor per Kommandozeile" + description: + type: youtube + video_id: "vf62tjS6v9E" + duration: 321 + - id: "ejy0APEsRuY" + title: "Windows SICHER, ANONYM und SCHNELLER machen" + description: + type: youtube + video_id: "ejy0APEsRuY" + duration: 3287 + - id: "0EgGoKG165o" + title: "Ich habe meine PowerShell gemoddet, damit ich SUDO nutzen kann" + description: + type: youtube + video_id: "0EgGoKG165o" + duration: 896 diff --git a/academy_data/courses/wireshark.yml b/academy_data/courses/wireshark.yml new file mode 100644 index 00000000..8dc65a65 --- /dev/null +++ b/academy_data/courses/wireshark.yml @@ -0,0 +1,84 @@ +# https://www.youtube.com/playlist?list=PLNmsVeXQZj7oIlWv3K9xACZi3fHfYLKtj +title: "Wireshark: Netzwerkanalyse" +description: "Wenn ihr Netzwerktraffic analysieren wollt, also schauen, was da so alles passiert, vielleicht einzelne Verbindungen untersuchen wollt, ob da jetzt jemand Sachen schickt, die nicht sein sollten - dann kommt ihr um Wireshark fast nicht drum herum!" +category: +language: de +image: https://static.bootstrap.academy/thumbnails/wireshark.jpg +authors: + - name: "The Morpheus Tutorials" + url: "https://www.youtube.com/@TheMorpheusTutorials" +price: 0 +learning_goals: [] +requirements: [] +last_update: 1665507854 +sections: + - id: section + title: "Wireshark" + description: + lectures: + - id: "Tc6V4lem9FY" + title: "Einleitung und Installation" + description: + type: youtube + video_id: "Tc6V4lem9FY" + duration: 574 + - id: "tMP6IH4MAk8" + title: "Aufzeichnen" + description: + type: youtube + video_id: "tMP6IH4MAk8" + duration: 632 + - id: "rhokQ-6UC2Q" + title: "Mehr zum Paket" + description: + type: youtube + video_id: "rhokQ-6UC2Q" + duration: 625 + - id: "2L7WP0Bb5pA" + title: "Datenpakete" + description: + type: youtube + video_id: "2L7WP0Bb5pA" + duration: 717 + - id: "rEWSZ8V4H3c" + title: "Speichern und Laden" + description: + type: youtube + video_id: "rEWSZ8V4H3c" + duration: 191 + - id: "pJekOEB3HLs" + title: "Filter" + description: + type: youtube + video_id: "pJekOEB3HLs" + duration: 653 + - id: "5GbvTT69v0U" + title: "Verbindungen einfärben" + description: + type: youtube + video_id: "5GbvTT69v0U" + duration: 231 + - id: "rXb5AFSQpSE" + title: "Statistiken und Graphs" + description: + type: youtube + video_id: "rXb5AFSQpSE" + duration: 477 + - id: "Hs58b7OHgto" + title: "Challenge aus dem Vorstellungsgespräch - Telnet" + description: + type: youtube + video_id: "Hs58b7OHgto" + duration: 499 + - id: "r9rd7U5I4Q4" + title: "Wireshark-Ersatz? Das eine Feature des MS Network Monitors" + description: + type: youtube + video_id: "r9rd7U5I4Q4" + duration: 337 + - id: "Mr80hEkYYqY" + title: "Remote Wireshark: SSHDump und Verbindungen auf dem Server beobachten" + description: + type: youtube + video_id: "Mr80hEkYYqY" + duration: 339 diff --git a/academy_data/src/course.rs b/academy_data/src/course.rs new file mode 100644 index 00000000..89833830 --- /dev/null +++ b/academy_data/src/course.rs @@ -0,0 +1,196 @@ +use std::{collections::HashMap, fs::DirEntry, ops::Deref, path::Path, sync::Arc, time::Duration}; + +use academy_models::{ + course::{ + Course, CourseAuthor, CourseAuthorName, CourseBase, CourseDescription, CourseId, + CourseLecture, CourseLectureId, CourseLectureKind, CourseLectureTitle, CourseMp4Lecture, + CourseSection, CourseSectionId, CourseSectionTitle, CourseTitle, CourseYoutubeLecture, + }, + url::Url, +}; +use anyhow::{Context, anyhow}; +use chrono::DateTime; +use serde::Deserialize; +use tracing::{debug, info}; + +#[derive(Debug, Clone, Default)] +pub struct CourseDataRepository(Arc>); + +impl Deref for CourseDataRepository { + type Target = HashMap; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl CourseDataRepository { + pub fn load(course_dir: &Path) -> anyhow::Result { + info!("Loading courses from {}", course_dir.display()); + let courses = std::fs::read_dir(course_dir) + .with_context(|| anyhow!("Failed to read directory at {}", course_dir.display()))? + .map(|entry| load_course(entry?)) + .flat_map(|result| result.transpose()) + .collect::>()?; + + Ok(Self(Arc::new(courses))) + } +} + +fn load_course(entry: DirEntry) -> anyhow::Result> { + if !entry.file_type()?.is_file() { + debug!( + "Skipping {} because it is not a regular file", + entry.path().display() + ); + return Ok(None); + } + + let file_name = entry.file_name(); + let file_name = file_name.to_str().ok_or_else(|| { + anyhow!( + "Name of file at {} is not valid unicode", + entry.path().display() + ) + })?; + + let Some(id) = file_name.strip_suffix(".yml") else { + debug!( + "Skipping {} because it's not a .yml file", + entry.path().display() + ); + return Ok(None); + }; + + let content = std::fs::read_to_string(entry.path()) + .with_context(|| anyhow!("Failed to read file at {}", entry.path().display()))?; + + let id = CourseId::new(id); + let course = serde_yaml::from_str::(&content) + .with_context(|| anyhow!("Failed to deserialize file at {}", entry.path().display()))?; + + let course = Course { + base: CourseBase { + id: id.clone(), + title: course.title, + description: course.description, + image_url: course.image, + authors: course.authors.into_iter().map(Into::into).collect(), + price: course.price, + last_update: DateTime::from_timestamp(course.last_update, 0) + .ok_or_else(|| anyhow!("Invalid timestamp: {}", course.last_update))?, + }, + sections: course.sections.into_iter().map(Into::into).collect(), + }; + + Ok(Some((id, course))) +} + +#[derive(Debug, Deserialize)] +struct RawCourse { + title: CourseTitle, + description: CourseDescription, + image: Option, + authors: Vec, + price: u64, + last_update: i64, + sections: Vec, +} + +#[derive(Debug, Deserialize)] +struct RawCourseAuthor { + name: CourseAuthorName, + url: Option, +} + +#[derive(Debug, Deserialize)] +struct RawCourseSection { + id: CourseSectionId, + title: CourseSectionTitle, + lectures: Vec, +} + +#[derive(Debug, Deserialize)] +struct RawCourseLecture { + id: CourseLectureId, + title: CourseLectureTitle, + #[serde(flatten)] + kind: RawCourseLectureKind, +} + +#[derive(Debug, Deserialize)] +#[serde(tag = "type", rename_all = "snake_case")] +enum RawCourseLectureKind { + Youtube(RawCourseYoutubeLecture), + Mp4(RawCourseMp4Lecture), +} + +#[derive(Debug, Deserialize)] +struct RawCourseYoutubeLecture { + video_id: String, + duration: u64, +} + +#[derive(Debug, Deserialize)] +struct RawCourseMp4Lecture { + duration: u64, +} + +impl From for CourseAuthor { + fn from(value: RawCourseAuthor) -> Self { + Self { + name: value.name, + url: value.url, + } + } +} + +impl From for CourseSection { + fn from(value: RawCourseSection) -> Self { + Self { + id: value.id, + title: value.title, + lectures: value.lectures.into_iter().map(Into::into).collect(), + } + } +} + +impl From for CourseLecture { + fn from(value: RawCourseLecture) -> Self { + Self { + id: value.id.clone(), + title: value.title, + kind: match value.kind { + RawCourseLectureKind::Youtube(kind) => { + CourseLectureKind::Youtube(CourseYoutubeLecture { + video_id: kind.video_id, + duration: Duration::from_secs(kind.duration), + }) + } + RawCourseLectureKind::Mp4(kind) => CourseLectureKind::Mp4(CourseMp4Lecture { + video_id: value.id.into_inner(), + duration: Duration::from_secs(kind.duration), + }), + }, + } + } +} + +impl FromIterator for CourseDataRepository { + fn from_iter>(iter: T) -> Self { + Self(Arc::new( + iter.into_iter().map(|c| (c.base.id.clone(), c)).collect(), + )) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn load() { + CourseDataRepository::load(concat!(env!("CARGO_MANIFEST_DIR"), "/courses").as_ref()) + .unwrap(); + } +} diff --git a/academy_data/src/lib.rs b/academy_data/src/lib.rs new file mode 100644 index 00000000..e59f6938 --- /dev/null +++ b/academy_data/src/lib.rs @@ -0,0 +1 @@ +pub mod course; diff --git a/academy_demo/src/course.rs b/academy_demo/src/course.rs new file mode 100644 index 00000000..b13ad925 --- /dev/null +++ b/academy_demo/src/course.rs @@ -0,0 +1,42 @@ +use std::sync::LazyLock; + +use academy_models::course::{Course, CourseAuthor, CourseBase}; +use chrono::{TimeZone, Utc}; + +pub static ALL_COURSES: LazyLock> = LazyLock::new(|| vec![&COURSE1, &COURSE2]); + +pub static COURSE_AUTHOR1: LazyLock = LazyLock::new(|| CourseAuthor { + name: "Course Author 1".into(), + url: None, +}); + +pub static COURSE_AUTHOR2: LazyLock = LazyLock::new(|| CourseAuthor { + name: "Course Author 2".into(), + url: None, +}); + +pub static COURSE1: LazyLock = LazyLock::new(|| Course { + base: CourseBase { + id: "c1".into(), + title: "Course 1".into(), + description: "desc1".into(), + image_url: None, + authors: vec![COURSE_AUTHOR1.clone()], + price: 0, + last_update: Utc.with_ymd_and_hms(2025, 7, 10, 16, 0, 0).unwrap(), + }, + sections: vec![], +}); + +pub static COURSE2: LazyLock = LazyLock::new(|| Course { + base: CourseBase { + id: "c2".into(), + title: "Course 2".into(), + description: "desc2".into(), + image_url: None, + authors: vec![COURSE_AUTHOR1.clone(), COURSE_AUTHOR2.clone()], + price: 42, + last_update: Utc.with_ymd_and_hms(2025, 7, 10, 18, 0, 0).unwrap(), + }, + sections: vec![], +}); diff --git a/academy_demo/src/lib.rs b/academy_demo/src/lib.rs index 10091979..7f3d1fb5 100644 --- a/academy_demo/src/lib.rs +++ b/academy_demo/src/lib.rs @@ -7,6 +7,7 @@ use academy_persistence_contracts::{ use anyhow::Context; use uuid::{Uuid, uuid}; +pub mod course; pub mod mfa; pub mod oauth2; pub mod session; diff --git a/academy_email/contracts/src/template.rs b/academy_email/contracts/src/template.rs index 144abb76..ae6382d2 100644 --- a/academy_email/contracts/src/template.rs +++ b/academy_email/contracts/src/template.rs @@ -2,8 +2,8 @@ use std::future::Future; use academy_models::email_address::EmailAddressWithName; use academy_templates_contracts::{ - PurchaseConfirmationTemplate, ResetPasswordTemplate, SubscribeNewsletterTemplate, - VerifyEmailTemplate, + CoursePurchaseConfirmationTemplate, PurchaseConfirmationTemplate, ResetPasswordTemplate, + SubscribeNewsletterTemplate, VerifyEmailTemplate, }; #[cfg_attr(feature = "mock", mockall::automock)] @@ -32,6 +32,12 @@ pub trait TemplateEmailService: Send + Sync + 'static { data: &PurchaseConfirmationTemplate, invoice: Vec, ) -> impl Future> + Send; + + fn send_course_purchase_confirmation_email( + &self, + recipient: EmailAddressWithName, + data: &CoursePurchaseConfirmationTemplate, + ) -> impl Future> + Send; } #[cfg(feature = "mock")] @@ -101,4 +107,20 @@ impl MockTemplateEmailService { .return_once(move |_, _, _| Box::pin(std::future::ready(Ok(result)))); self } + + pub fn with_send_course_purchase_confirmation_email( + mut self, + recipient: EmailAddressWithName, + data: CoursePurchaseConfirmationTemplate, + result: bool, + ) -> Self { + self.expect_send_course_purchase_confirmation_email() + .once() + .with( + mockall::predicate::eq(recipient), + mockall::predicate::eq(data), + ) + .return_once(move |_, _| Box::pin(std::future::ready(Ok(result)))); + self + } } diff --git a/academy_email/impl/src/template.rs b/academy_email/impl/src/template.rs index e1bfe58d..d69efb96 100644 --- a/academy_email/impl/src/template.rs +++ b/academy_email/impl/src/template.rs @@ -6,8 +6,8 @@ use academy_email_contracts::{ }; use academy_models::email_address::EmailAddressWithName; use academy_templates_contracts::{ - PurchaseConfirmationTemplate, ResetPasswordTemplate, SubscribeNewsletterTemplate, Template, - TemplateService, VerifyEmailTemplate, + CoursePurchaseConfirmationTemplate, PurchaseConfirmationTemplate, ResetPasswordTemplate, + SubscribeNewsletterTemplate, Template, TemplateService, VerifyEmailTemplate, }; use academy_utils::trace_instrument; @@ -100,6 +100,21 @@ where ) .await } + + #[trace_instrument(skip(self))] + async fn send_course_purchase_confirmation_email( + &self, + recipient: EmailAddressWithName, + data: &CoursePurchaseConfirmationTemplate, + ) -> anyhow::Result { + self.send_email( + recipient, + data, + "Kaufbestätigung - Bootstrap Academy", + Vec::new(), + ) + .await + } } impl TemplateEmailServiceImpl diff --git a/academy_models/src/course.rs b/academy_models/src/course.rs new file mode 100644 index 00000000..a5f0029f --- /dev/null +++ b/academy_models/src/course.rs @@ -0,0 +1,148 @@ +use std::time::Duration; + +use academy_utils::patch::Patch; +use chrono::{DateTime, Utc}; + +use crate::{SearchTerm, nutype_string, url::Url, user::UserId}; + +#[derive(Debug, Clone, PartialEq, Eq, Patch)] +pub struct CourseUser { + #[no_patch] + pub course_id: CourseId, + #[no_patch] + pub user_id: UserId, + pub purchased: bool, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CourseBase { + pub id: CourseId, + pub title: CourseTitle, + pub description: CourseDescription, + pub image_url: Option, + pub authors: Vec, + pub price: u64, + pub last_update: DateTime, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Course { + pub base: CourseBase, + pub sections: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CourseUserSummary { + pub base: CourseBase, + pub sections: Vec, + pub completed: Option, +} + +nutype_string!(CourseId); +nutype_string!(CourseTitle); +nutype_string!(CourseDescription); + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CourseAuthor { + pub name: CourseAuthorName, + pub url: Option, +} + +nutype_string!(CourseAuthorName); + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CourseSection { + pub id: CourseSectionId, + pub title: CourseSectionTitle, + pub lectures: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CourseSectionUserSummary { + pub title: CourseSectionTitle, + pub lectures: Vec, + pub completed: Option, +} + +nutype_string!(CourseSectionId); +nutype_string!(CourseSectionTitle); + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CourseLecture { + pub id: CourseLectureId, + pub title: CourseLectureTitle, + pub kind: CourseLectureKind, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CourseLectureUserSummary { + pub title: CourseLectureTitle, + pub duration: Duration, + pub completed: Option, +} + +nutype_string!(CourseLectureId); +nutype_string!(CourseLectureTitle); + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum CourseLectureKind { + Youtube(CourseYoutubeLecture), + Mp4(CourseMp4Lecture), +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CourseYoutubeLecture { + pub video_id: String, + pub duration: Duration, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CourseMp4Lecture { + pub video_id: String, + pub duration: Duration, +} + +#[derive(Debug, Clone, PartialEq, Eq, Default)] +pub struct CourseFilter { + /// Search in `title` + pub search_term: Option, + /// Filter by author + pub author: Option, + /// Return only free (`true`) or unfree (`false`) courses + pub free: Option, +} + +impl From for CourseUserSummary { + fn from(value: Course) -> Self { + Self { + base: value.base, + sections: value.sections.into_iter().map(Into::into).collect(), + completed: None, + } + } +} + +impl From for CourseSectionUserSummary { + fn from(value: CourseSection) -> Self { + Self { + title: value.title, + lectures: value.lectures.into_iter().map(Into::into).collect(), + completed: None, + } + } +} + +impl From for CourseLectureUserSummary { + fn from(value: CourseLecture) -> Self { + Self { + title: value.title, + duration: match value.kind { + CourseLectureKind::Youtube(course_youtube_lecture) => { + course_youtube_lecture.duration + } + CourseLectureKind::Mp4(course_mp4_lecture) => course_mp4_lecture.duration, + }, + completed: None, + } + } +} diff --git a/academy_models/src/lib.rs b/academy_models/src/lib.rs index a488e94b..9a63e6bf 100644 --- a/academy_models/src/lib.rs +++ b/academy_models/src/lib.rs @@ -8,6 +8,7 @@ use serde::{Deserialize, Serialize}; pub mod auth; pub mod coin; pub mod contact; +pub mod course; pub mod email_address; pub mod heart; mod macros; diff --git a/academy_persistence/contracts/src/course.rs b/academy_persistence/contracts/src/course.rs new file mode 100644 index 00000000..c9275433 --- /dev/null +++ b/academy_persistence/contracts/src/course.rs @@ -0,0 +1,61 @@ +#[cfg(feature = "mock")] +use academy_models::course::CourseUserPatch; +use academy_models::{ + course::{CourseId, CourseUser, CourseUserPatchRef}, + user::UserId, +}; + +#[cfg_attr(feature = "mock", mockall::automock)] +pub trait CourseRepository: Send + Sync + 'static { + /// Return the given course user. + fn get_course_user( + &self, + txn: &mut Txn, + course_id: &CourseId, + user_id: UserId, + ) -> impl Future> + Send; + + /// Update the given course user. + fn update_course_user<'a>( + &self, + txn: &mut Txn, + course_id: &CourseId, + user_id: UserId, + patch: CourseUserPatchRef<'a>, + ) -> impl Future> + Send; +} + +#[cfg(feature = "mock")] +impl MockCourseRepository { + pub fn with_get_course_user( + mut self, + course_id: CourseId, + user_id: UserId, + result: CourseUser, + ) -> Self { + self.expect_get_course_user() + .once() + .with( + mockall::predicate::always(), + mockall::predicate::eq(course_id), + mockall::predicate::eq(user_id), + ) + .return_once(|_, _, _| Box::pin(std::future::ready(Ok(result)))); + self + } + + pub fn with_update_course_user( + mut self, + course_id: CourseId, + user_id: UserId, + patch: CourseUserPatch, + ) -> Self { + self.expect_update_course_user() + .once() + .withf(move |_, cid, uid, p| { + *cid == course_id && *uid == user_id && *p == patch.as_ref() + }) + .return_once(|_, _, _, _| Box::pin(std::future::ready(Ok(())))); + self + } +} diff --git a/academy_persistence/contracts/src/lib.rs b/academy_persistence/contracts/src/lib.rs index e3de7bcf..5f9873a7 100644 --- a/academy_persistence/contracts/src/lib.rs +++ b/academy_persistence/contracts/src/lib.rs @@ -1,6 +1,7 @@ use std::future::Future; pub mod coin; +pub mod course; pub mod heart; pub mod mfa; pub mod oauth2; diff --git a/academy_persistence/postgres/clorinde/src/queries.rs b/academy_persistence/postgres/clorinde/src/queries.rs index 88bbed2e..4bc73ad6 100644 --- a/academy_persistence/postgres/clorinde/src/queries.rs +++ b/academy_persistence/postgres/clorinde/src/queries.rs @@ -1,6 +1,7 @@ // This file was generated with `clorinde`. Do not modify. pub mod coin; +pub mod course; pub mod heart; pub mod mfa; pub mod oauth2; diff --git a/academy_persistence/postgres/clorinde/src/queries/course.rs b/academy_persistence/postgres/clorinde/src/queries/course.rs new file mode 100644 index 00000000..d475c1fc --- /dev/null +++ b/academy_persistence/postgres/clorinde/src/queries/course.rs @@ -0,0 +1,218 @@ +// This file was generated with `clorinde`. Do not modify. + +#[derive(Debug)] +pub struct GetCourseUserParams { + pub course_id: T1, + pub user_id: uuid::Uuid, +} +#[derive(Debug)] +pub struct UpdateCourseUserParams { + pub course_id: T1, + pub user_id: uuid::Uuid, + pub purchased: Option, +} +#[derive(Debug, Clone, PartialEq)] +pub struct CourseUser { + pub course_id: String, + pub user_id: uuid::Uuid, + pub purchased: bool, +} +pub struct CourseUserBorrowed<'a> { + pub course_id: &'a str, + pub user_id: uuid::Uuid, + pub purchased: bool, +} +impl<'a> From> for CourseUser { + fn from( + CourseUserBorrowed { + course_id, + user_id, + purchased, + }: CourseUserBorrowed<'a>, + ) -> Self { + Self { + course_id: course_id.into(), + user_id, + purchased, + } + } +} +use crate::client::async_::GenericClient; +use futures::{self, StreamExt, TryStreamExt}; +pub struct CourseUserQuery<'c, 'a, 's, C: GenericClient, T, const N: usize> { + client: &'c C, + params: [&'a (dyn postgres_types::ToSql + Sync); N], + query: &'static str, + cached: Option<&'s tokio_postgres::Statement>, + extractor: fn(&tokio_postgres::Row) -> Result, + mapper: fn(CourseUserBorrowed) -> T, +} +impl<'c, 'a, 's, C, T: 'c, const N: usize> CourseUserQuery<'c, 'a, 's, C, T, N> +where + C: GenericClient, +{ + pub fn map( + self, + mapper: fn(CourseUserBorrowed) -> R, + ) -> CourseUserQuery<'c, 'a, 's, C, R, N> { + CourseUserQuery { + client: self.client, + params: self.params, + query: self.query, + cached: self.cached, + extractor: self.extractor, + mapper, + } + } + pub async fn one(self) -> Result { + let row = + crate::client::async_::one(self.client, self.query, &self.params, self.cached).await?; + Ok((self.mapper)((self.extractor)(&row)?)) + } + pub async fn all(self) -> Result, tokio_postgres::Error> { + self.iter().await?.try_collect().await + } + pub async fn opt(self) -> Result, tokio_postgres::Error> { + let opt_row = + crate::client::async_::opt(self.client, self.query, &self.params, self.cached).await?; + Ok(opt_row + .map(|row| { + let extracted = (self.extractor)(&row)?; + Ok((self.mapper)(extracted)) + }) + .transpose()?) + } + pub async fn iter( + self, + ) -> Result< + impl futures::Stream> + use<'c, C, T, N>, + tokio_postgres::Error, + > { + let stream = crate::client::async_::raw( + self.client, + self.query, + crate::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream + .map(move |res| { + res.and_then(|row| { + let extracted = (self.extractor)(&row)?; + Ok((self.mapper)(extracted)) + }) + }) + .into_stream(); + Ok(mapped) + } +} +pub struct GetCourseUserStmt(&'static str, Option); +pub fn get_course_user() -> GetCourseUserStmt { + GetCourseUserStmt( + "select * from course_users where course_id=$1 and user_id=$2", + None, + ) +} +impl GetCourseUserStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } + pub fn bind<'c, 'a, 's, C: GenericClient, T1: crate::StringSql>( + &'s self, + client: &'c C, + course_id: &'a T1, + user_id: &'a uuid::Uuid, + ) -> CourseUserQuery<'c, 'a, 's, C, CourseUser, 2> { + CourseUserQuery { + client, + params: [course_id, user_id], + query: self.0, + cached: self.1.as_ref(), + extractor: + |row: &tokio_postgres::Row| -> Result { + Ok(CourseUserBorrowed { + course_id: row.try_get(0)?, + user_id: row.try_get(1)?, + purchased: row.try_get(2)?, + }) + }, + mapper: |it| CourseUser::from(it), + } + } +} +impl<'c, 'a, 's, C: GenericClient, T1: crate::StringSql> + crate::client::async_::Params< + 'c, + 'a, + 's, + GetCourseUserParams, + CourseUserQuery<'c, 'a, 's, C, CourseUser, 2>, + C, + > for GetCourseUserStmt +{ + fn params( + &'s self, + client: &'c C, + params: &'a GetCourseUserParams, + ) -> CourseUserQuery<'c, 'a, 's, C, CourseUser, 2> { + self.bind(client, ¶ms.course_id, ¶ms.user_id) + } +} +pub struct UpdateCourseUserStmt(&'static str, Option); +pub fn update_course_user() -> UpdateCourseUserStmt { + UpdateCourseUserStmt( + "insert into course_users as cu (course_id, user_id, purchased) values ($1, $2, coalesce($3, false)) on conflict (course_id, user_id) do update set purchased = coalesce($3, cu.purchased)", + None, + ) +} +impl UpdateCourseUserStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } + pub async fn bind<'c, 'a, 's, C: GenericClient, T1: crate::StringSql>( + &'s self, + client: &'c C, + course_id: &'a T1, + user_id: &'a uuid::Uuid, + purchased: &'a Option, + ) -> Result { + client + .execute(self.0, &[course_id, user_id, purchased]) + .await + } +} +impl<'a, C: GenericClient + Send + Sync, T1: crate::StringSql> + crate::client::async_::Params< + 'a, + 'a, + 'a, + UpdateCourseUserParams, + std::pin::Pin< + Box> + Send + 'a>, + >, + C, + > for UpdateCourseUserStmt +{ + fn params( + &'a self, + client: &'a C, + params: &'a UpdateCourseUserParams, + ) -> std::pin::Pin< + Box> + Send + 'a>, + > { + Box::pin(self.bind( + client, + ¶ms.course_id, + ¶ms.user_id, + ¶ms.purchased, + )) + } +} diff --git a/academy_persistence/postgres/migrations/2025-07-09-165140_create_course_users_table/down.sql b/academy_persistence/postgres/migrations/2025-07-09-165140_create_course_users_table/down.sql new file mode 100644 index 00000000..8c7e5b02 --- /dev/null +++ b/academy_persistence/postgres/migrations/2025-07-09-165140_create_course_users_table/down.sql @@ -0,0 +1 @@ +drop table course_users; diff --git a/academy_persistence/postgres/migrations/2025-07-09-165140_create_course_users_table/up.sql b/academy_persistence/postgres/migrations/2025-07-09-165140_create_course_users_table/up.sql new file mode 100644 index 00000000..f26426b5 --- /dev/null +++ b/academy_persistence/postgres/migrations/2025-07-09-165140_create_course_users_table/up.sql @@ -0,0 +1,6 @@ +create table course_users ( + course_id text not null, + user_id uuid not null references users(id) on delete cascade, + purchased boolean not null, + primary key (course_id, user_id) +); diff --git a/academy_persistence/postgres/queries/course.sql b/academy_persistence/postgres/queries/course.sql new file mode 100644 index 00000000..cd8effd1 --- /dev/null +++ b/academy_persistence/postgres/queries/course.sql @@ -0,0 +1,10 @@ +--: CourseUser() + +--! get_course_user : CourseUser +select * from course_users where course_id=:course_id and user_id=:user_id; + +--! update_course_user (purchased?) +insert into course_users as cu (course_id, user_id, purchased) + values (:course_id, :user_id, coalesce(:purchased, false)) + on conflict (course_id, user_id) do update + set purchased = coalesce(:purchased, cu.purchased); diff --git a/academy_persistence/postgres/src/course.rs b/academy_persistence/postgres/src/course.rs new file mode 100644 index 00000000..31b7bbb3 --- /dev/null +++ b/academy_persistence/postgres/src/course.rs @@ -0,0 +1,78 @@ +use academy_di::Build; +use academy_models::{ + course::{CourseId, CourseUser, CourseUserPatchRef}, + user::UserId, +}; +use academy_persistence_contracts::course::CourseRepository; +use academy_utils::trace_instrument; +use clorinde::{ + client::Params, + queries::{ + self, + course::{GetCourseUserParams, UpdateCourseUserParams}, + }, +}; + +use crate::PostgresTransaction; + +#[derive(Debug, Clone, Build)] +pub struct PostgresCourseRepository; + +impl CourseRepository for PostgresCourseRepository { + #[trace_instrument(skip(self, txn))] + async fn get_course_user( + &self, + txn: &mut PostgresTransaction, + course_id: &CourseId, + user_id: UserId, + ) -> anyhow::Result { + queries::course::get_course_user() + .params( + txn.txn(), + &GetCourseUserParams { + course_id: &**course_id, + user_id: *user_id, + }, + ) + .opt() + .await + .map_err(Into::into) + .map(|row| { + row.map(decode_course_user).unwrap_or_else(|| CourseUser { + course_id: course_id.clone(), + user_id, + purchased: false, + }) + }) + } + + #[trace_instrument(skip(self, txn))] + async fn update_course_user<'a>( + &self, + txn: &mut PostgresTransaction, + course_id: &CourseId, + user_id: UserId, + patch: CourseUserPatchRef<'a>, + ) -> anyhow::Result<()> { + queries::course::update_course_user() + .params( + txn.txn(), + &UpdateCourseUserParams { + course_id: &**course_id, + user_id: *user_id, + purchased: patch.purchased.update().copied(), + }, + ) + .await + .map(|_| ()) + .map_err(Into::into) + } +} + +fn decode_course_user(value: queries::course::CourseUser) -> CourseUser { + CourseUser { + course_id: value.course_id.into(), + user_id: value.user_id.into(), + purchased: value.purchased, + } +} diff --git a/academy_persistence/postgres/src/lib.rs b/academy_persistence/postgres/src/lib.rs index 666a4137..a1796e5f 100644 --- a/academy_persistence/postgres/src/lib.rs +++ b/academy_persistence/postgres/src/lib.rs @@ -13,6 +13,7 @@ use ouroboros::self_referencing; use tracing::trace; pub mod coin; +pub mod course; pub mod heart; pub mod mfa; pub mod oauth2; diff --git a/academy_persistence/postgres/tests/repos/course.rs b/academy_persistence/postgres/tests/repos/course.rs new file mode 100644 index 00000000..661d4bb2 --- /dev/null +++ b/academy_persistence/postgres/tests/repos/course.rs @@ -0,0 +1,82 @@ +use academy_demo::user::FOO; +use academy_models::course::{CourseId, CourseUser, CourseUserPatchRef}; +use academy_persistence_contracts::{Database, Transaction, course::CourseRepository}; +use academy_persistence_postgres::course::PostgresCourseRepository; +use academy_utils::patch::PatchValue; + +use crate::common::setup; + +const REPO: PostgresCourseRepository = PostgresCourseRepository; + +#[tokio::test] +async fn course_users() { + let db = setup().await; + + let course_id = CourseId::new("course"); + + let mut txn = db.begin_transaction().await.unwrap(); + let result = REPO + .get_course_user(&mut txn, &course_id, FOO.user.id) + .await + .unwrap(); + assert_eq!( + result, + CourseUser { + course_id: course_id.clone(), + user_id: FOO.user.id, + purchased: false + } + ); + + REPO.update_course_user( + &mut txn, + &course_id, + FOO.user.id, + CourseUserPatchRef { + purchased: PatchValue::Update(&true), + }, + ) + .await + .unwrap(); + txn.commit().await.unwrap(); + + let mut txn = db.begin_transaction().await.unwrap(); + let result = REPO + .get_course_user(&mut txn, &course_id, FOO.user.id) + .await + .unwrap(); + assert_eq!( + result, + CourseUser { + course_id: course_id.clone(), + user_id: FOO.user.id, + purchased: true + } + ); + + REPO.update_course_user( + &mut txn, + &course_id, + FOO.user.id, + CourseUserPatchRef { + purchased: PatchValue::Update(&false), + }, + ) + .await + .unwrap(); + txn.commit().await.unwrap(); + + let mut txn = db.begin_transaction().await.unwrap(); + let result = REPO + .get_course_user(&mut txn, &course_id, FOO.user.id) + .await + .unwrap(); + assert_eq!( + result, + CourseUser { + course_id: course_id.clone(), + user_id: FOO.user.id, + purchased: false + } + ); +} diff --git a/academy_persistence/postgres/tests/repos/mod.rs b/academy_persistence/postgres/tests/repos/mod.rs index 2b94daa3..30ae3ca3 100644 --- a/academy_persistence/postgres/tests/repos/mod.rs +++ b/academy_persistence/postgres/tests/repos/mod.rs @@ -1,6 +1,7 @@ use academy_models::pagination::PaginationSlice; mod coins; +mod course; mod heart; mod mfa; mod oauth2; diff --git a/academy_templates/contracts/src/lib.rs b/academy_templates/contracts/src/lib.rs index b65e42c1..63cd282e 100644 --- a/academy_templates/contracts/src/lib.rs +++ b/academy_templates/contracts/src/lib.rs @@ -57,6 +57,7 @@ templates! { SubscribeNewsletterTemplate(templates::SUBSCRIBE_NEWSLETTER_HTML), PurchaseConfirmationTemplate(templates::PURCHASE_CONFIRMATION_HTML), InvoiceTemplate(templates::INVOICE_HTML), + CoursePurchaseConfirmationTemplate(templates::COURSE_PURCHASE_CONFIRMATION_HTML), } #[derive(Debug, Clone, PartialEq, Eq, Serialize)] @@ -99,6 +100,11 @@ pub struct PurchaseConfirmationTemplate { pub gross_total: Decimal, } +#[derive(Debug, Clone, PartialEq, Eq, Serialize)] +pub struct CoursePurchaseConfirmationTemplate { + pub title: String, +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize)] pub struct InvoiceTemplate { pub title: &'static str, diff --git a/academy_utils_derive/src/lib.rs b/academy_utils_derive/src/lib.rs index 6fb950c8..30de257d 100644 --- a/academy_utils_derive/src/lib.rs +++ b/academy_utils_derive/src/lib.rs @@ -235,7 +235,18 @@ pub fn derive_patch(input: TokenStream) -> TokenStream { #[proc_macro_attribute] pub fn trace_instrument(meta: TokenStream, input: TokenStream) -> TokenStream { - let meta = proc_macro2::TokenStream::from(meta); + let mut meta_iter = proc_macro2::TokenStream::from(meta).into_iter(); + let mut meta = proc_macro2::TokenStream::new(); + let ret = match meta_iter.next() { + Some(proc_macro2::TokenTree::Ident(i)) if i == "no_ret" => false, + Some(t) => { + meta.extend([t]); + true + } + None => true, + }; + meta.extend(meta_iter); + let ItemFn { attrs, vis, @@ -243,8 +254,10 @@ pub fn trace_instrument(meta: TokenStream, input: TokenStream) -> TokenStream { block, } = parse_macro_input!(input as ItemFn); + let ret = ret.then(|| quote! { ret(level = "trace") }); + quote! { - #[::tracing::instrument(ret(level = "trace"), #meta)] + #[::tracing::instrument(#ret, #meta)] #(#attrs)* #vis #sig { ::tracing::trace!("call"); diff --git a/config.dev.toml b/config.dev.toml index f27bc748..2b990dce 100644 --- a/config.dev.toml +++ b/config.dev.toml @@ -35,6 +35,9 @@ base_url_override = "http://127.0.0.1:8103/" client_id = "test-client" client_secret = "test-secret" +[course] +course_dir = "./academy_data/courses" + [render] daemon_url = "http://127.0.0.1:8001/" diff --git a/config.toml b/config.toml index 6e08226e..d27c62f1 100644 --- a/config.toml +++ b/config.toml @@ -85,6 +85,9 @@ auto_refill_time = "00:00" # UTC monthly_price = 1000 yearly_price = 10000 +[course] +# course_dir = "" + [render] # daemon_url = "" diff --git a/flake.nix b/flake.nix index 8ada2717..cbcdde3d 100644 --- a/flake.nix +++ b/flake.nix @@ -85,6 +85,8 @@ default = import ./nix/module.nix self; }; + courses = ./academy_data/courses; + devShells = eachDefaultSystem (system: { default = mkDevShell { inherit system; }; }); diff --git a/nix/module.nix b/nix/module.nix index 3bad7bfb..eb153890 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -259,6 +259,7 @@ in settings = { database.url = lib.mkIf cfg.localDatabase "host=/run/postgresql user=academy"; cache.url = lib.mkIf cfg.localCache "redis+unix://${config.services.redis.servers.academy.unixSocket}"; + course.course_dir = lib.mkDefault self.courses; render.daemon_url = lib.mkIf cfg.renderDaemon.enable "http://127.0.0.1:${toString cfg.renderDaemon.port}/"; finance.invoices_archive = lib.mkDefault "/var/lib/academy/invoices"; finance.credit_notes_archive = lib.mkDefault "/var/lib/academy/credit_notes"; diff --git a/nix/packages.nix b/nix/packages.nix index 96f167dd..c8322f9b 100644 --- a/nix/packages.nix +++ b/nix/packages.nix @@ -10,6 +10,7 @@ makeWrapper, versionCheckHook, }: + let toolchain = fenix.packages.${system}.stable; @@ -112,6 +113,12 @@ let ${attrs.patchPhase or ""} ''; }; + academy_data = _: { + src = lib.fileset.toSource { + root = ../academy_data; + fileset = ../academy_data/src; + }; + }; }; cargoNix = callPackage ../Cargo.nix { @@ -127,6 +134,7 @@ let defaultCrateOverrides = mergeOverrideSets pkgs.defaultCrateOverrides crateOverrides; }; in + builtins.mapAttrs (_: setVersion) { default = cargoNix.workspaceMembers.academy.build; render_daemon = cargoNix.workspaceMembers.academy_render_daemon.build.overrideAttrs { diff --git a/nix/tests/course.py b/nix/tests/course.py new file mode 100644 index 00000000..7fc7ca10 --- /dev/null +++ b/nix/tests/course.py @@ -0,0 +1,52 @@ +import re +import subprocess + +from utils import c, create_verified_account, decode_mail_header, decode_mail_payload, fetch_mail + +login = create_verified_account("a", "a@a", "a") + +# list courses +resp = c.get("/skills/courses") +assert resp.status_code == 200 +courses = resp.json() +assert isinstance(courses, list) +assert all(isinstance(c, dict) for c in courses) +assert all(f in c for c in courses for f in ["id", "title", "description", "authors", "last_update", "sections"]) + +unfree = next(c for c in courses if c["price"] != 0) +free = next(c for c in courses if c["price"] == 0) + +# purchase course + +## not found +resp = c.post("/skills/course_access/does_not_exist") +assert resp.status_code == 404 +assert resp.json() == {"detail": "Course not found"} + +## course is free +resp = c.post(f"/skills/course_access/{free["id"]}") +assert resp.status_code == 403 +assert resp.json() == {"detail": "Course is free"} + +## not enough coins +resp = c.post(f"/skills/course_access/{unfree["id"]}") +assert resp.status_code == 412 +assert resp.json() == {"detail": "Not enough coins"} + +## ok +assert subprocess.getstatusoutput(f"academy admin coin add {login['user']['id']} {unfree["price"] + 7}")[0] == 0 +resp = c.post(f"/skills/course_access/{unfree["id"]}") +assert resp.status_code == 200 +assert resp.json() is True +assert c.get("/shop/coins/me").json()["coins"] == 7 + +mail = fetch_mail() +assert mail["X-Original-To"] == "a@a" +assert decode_mail_header(mail["Subject"]) == "Kaufbestätigung - Bootstrap Academy" +content = decode_mail_payload(mail) +assert f'Danke für den Kauf des Kurses "{unfree["title"]}"!' in content + +## already purchased +resp = c.post(f"/skills/course_access/{unfree["id"]}") +assert resp.status_code == 403 +assert resp.json() == {"detail": "Already purchased course"}