diff --git a/.gitignore b/.gitignore index 355b808..e76bf9d 100644 --- a/.gitignore +++ b/.gitignore @@ -47,4 +47,7 @@ next-env.d.ts # project sample files _data/*-sample.yml -_data/*-sample.json \ No newline at end of file +_data/*-sample.json + +# project images (generated during build) +public/project-images/ \ No newline at end of file diff --git a/_data/projects.yml b/_data/projects.yml index 12efa79..b23fd7b 100644 --- a/_data/projects.yml +++ b/_data/projects.yml @@ -14,8 +14,8 @@ language: C++ created_at: "2016-10-02T13:07:18Z" updated_at: "2025-07-06T01:50:41Z" - og_image: >- - https://opengraph.githubassets.com/bab195a2c9f578e288086c0612d70ed78132ec633de95b096bc80e9da734d175/InDieTasten/Connect4 + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: Slanted-Prime-Sudoku status: done @@ -31,8 +31,8 @@ language: C++ created_at: "2016-12-22T11:36:19Z" updated_at: "2025-07-06T01:47:50Z" - og_image: >- - https://opengraph.githubassets.com/cc0ead899e605442efeabc05d0b56f87004ba19526134082c84ef0d4c04e6917/InDieTasten/Slanted-Prime-Sudoku + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: DevTease.MicrosoftLoggingExtensions status: done @@ -50,8 +50,8 @@ language: HTML created_at: "2018-09-10T04:19:02Z" updated_at: "2025-07-06T01:45:54Z" - og_image: >- - https://opengraph.githubassets.com/96ea5396d3579b33372d1050766d222601ec943a9bd335e23cfc7d38e8cb7bea/InDieTasten/DevTease.MicrosoftLoggingExtensions + og_image: /project-placeholder.svg + custom_image_url: null archived: true - name: DevTease.AspNetIntegrationTests status: done @@ -69,8 +69,8 @@ language: HTML created_at: "2018-09-26T10:11:27Z" updated_at: "2025-07-06T01:44:46Z" - og_image: >- - https://opengraph.githubassets.com/7f2c3533f2af804ad1e203fab018cfb52ef73b993417617b8a90fee55f2ad6a7/InDieTasten/DevTease.AspNetIntegrationTests + og_image: /project-placeholder.svg + custom_image_url: null archived: true - name: DevTease.Plugins status: done @@ -85,8 +85,8 @@ language: C# created_at: "2019-02-03T19:59:43Z" updated_at: "2025-07-06T01:49:01Z" - og_image: >- - https://opengraph.githubassets.com/f0780af1b0e6d327103fc236ad7c94879a736e241b7272089ae99828b6701fbb/InDieTasten/DevTease.Plugins + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: Authenticated-Integration-Testing status: done @@ -106,8 +106,8 @@ language: C# created_at: "2019-10-17T16:27:01Z" updated_at: "2025-07-06T01:38:23Z" - og_image: >- - https://opengraph.githubassets.com/3e8e2728e654a431b9a29e21cac7fff48e25bf96f03e7375d2110f731cfd9d59/InDieTasten/Authenticated-Integration-Testing + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: Sars-Cov2-Necessity-Screening status: done @@ -127,8 +127,8 @@ language: TypeScript created_at: "2020-03-21T09:20:23Z" updated_at: "2025-07-06T01:41:22Z" - og_image: >- - https://opengraph.githubassets.com/23c45f047278fc73ec19d295c271317a09f01d410e4ef4b351fb4677cf05f2e0/InDieTasten/Sars-Cov2-Necessity-Screening + og_image: /project-placeholder.svg + custom_image_url: null archived: true - name: TerminalRTX status: done @@ -146,8 +146,8 @@ language: C# created_at: "2020-05-23T23:54:11Z" updated_at: "2025-07-06T00:49:42Z" - og_image: >- - https://opengraph.githubassets.com/c60b39b5be4d1b426ed32941ae53e2b58de1efc57dae6ec359d65ab30cee1b6f/InDieTasten/TerminalRTX + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: DigitalDepot status: done @@ -163,8 +163,8 @@ language: JavaScript created_at: "2021-07-15T17:09:41Z" updated_at: "2025-07-06T01:42:45Z" - og_image: >- - https://opengraph.githubassets.com/c6c7c22ebfaf993da0e197a5f7c1b384b13320aa294028c022c8d2c690e6362b/InDieTasten/DigitalDepot + og_image: /project-placeholder.svg + custom_image_url: null archived: true - name: tictactoe-rs status: done @@ -184,8 +184,8 @@ language: Rust created_at: "2023-03-11T00:38:26Z" updated_at: "2025-07-06T01:41:39Z" - og_image: >- - https://opengraph.githubassets.com/ac747458f72be7a94db597ac12dc4397241c0ac0e1e849ad6bd10b14ccc02781/InDieTasten/tictactoe-rs + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: alternate-screen-buffer-demo status: done @@ -201,8 +201,8 @@ language: Rust created_at: "2024-02-10T01:32:23Z" updated_at: "2025-07-06T01:27:37Z" - og_image: >- - https://opengraph.githubassets.com/48ddb6e5df82777e22b25c8f519e9c51a04c683418668be02d44b8bd9fef9d0b/InDieTasten/alternate-screen-buffer-demo + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: mouse-tracking-demo status: done @@ -221,8 +221,8 @@ language: Rust created_at: "2024-02-14T02:50:22Z" updated_at: "2025-07-06T01:39:40Z" - og_image: >- - https://opengraph.githubassets.com/7d8550a517e2718c57bc524b848eef5284a9239ca91384e4610ae6e639df082e/InDieTasten/mouse-tracking-demo + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: ANSI-mate status: done @@ -244,7 +244,8 @@ language: Lua created_at: "2024-05-05T11:59:56Z" updated_at: "2025-07-06T01:38:32Z" - og_image: https://repository-images.githubusercontent.com/796251486/5ffc646c-85db-450e-9018-8ce2b86de90d + og_image: /project-images/ANSI-mate-5ffc646c-85db-450e-9018-8ce2b86de90d.gif + custom_image_url: https://repository-images.githubusercontent.com/796251486/5ffc646c-85db-450e-9018-8ce2b86de90d archived: false - name: mandel-lua status: done @@ -268,7 +269,8 @@ language: Lua created_at: "2024-08-09T12:22:43Z" updated_at: "2025-08-29T18:31:33Z" - og_image: https://repository-images.githubusercontent.com/840310203/9323cb94-15c0-4e2e-8535-8dde50fe5b88 + og_image: /project-images/mandel-lua-9323cb94-15c0-4e2e-8535-8dde50fe5b88.png + custom_image_url: https://repository-images.githubusercontent.com/840310203/9323cb94-15c0-4e2e-8535-8dde50fe5b88 archived: false - name: superstitious-gh status: done @@ -290,8 +292,8 @@ language: JavaScript created_at: "2025-01-29T10:06:33Z" updated_at: "2025-08-29T22:51:20Z" - og_image: >- - https://opengraph.githubassets.com/da7782f8135396d1751452e56cd616ab713d10da728323093bd2b4da08c8f6f3/InDieTasten/superstitious-gh + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: InDieTasten status: in-progress @@ -303,8 +305,8 @@ language: null created_at: "2020-09-22T20:47:06Z" updated_at: "2025-05-26T15:39:03Z" - og_image: >- - https://opengraph.githubassets.com/10b2a430b30b71c848dd2ea6e1d657f0b11d455b42cf4e6f255e9f3f08646e4a/InDieTasten/InDieTasten + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: pfand status: in-progress @@ -323,8 +325,8 @@ language: Rust created_at: "2024-07-24T16:26:12Z" updated_at: "2025-04-08T18:34:29Z" - og_image: >- - https://opengraph.githubassets.com/7ea257cc486c2c9b21e45af55425bb2eba6dd4e9e49b51d3c75ef9b2dd31c591/InDieTasten/pfand + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: k8s-bug status: in-progress @@ -336,8 +338,8 @@ language: Shell created_at: "2025-03-12T16:45:41Z" updated_at: "2025-03-12T16:45:47Z" - og_image: >- - https://opengraph.githubassets.com/4dce0556bd899219d31af8f88c530f7e237abab159ffdbcb01586b0a9b11dfb6/InDieTasten/k8s-bug + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: OpenHour status: in-progress @@ -349,8 +351,8 @@ language: null created_at: "2025-07-12T02:22:37Z" updated_at: "2025-07-12T02:22:38Z" - og_image: >- - https://opengraph.githubassets.com/ab9a9cb5ca669adcec4d2f326191284fe3f2daaaac978334d280b1923cd4e531/InDieTasten/OpenHour + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: acc-engineering-agent status: in-progress @@ -364,8 +366,8 @@ language: null created_at: "2025-07-13T10:56:45Z" updated_at: "2025-07-13T10:56:45Z" - og_image: >- - https://opengraph.githubassets.com/d67d59e1c346b2f27d2c113cf5fa6cd9ef5d989a7e45738d5b0b7194b7c0fb3c/InDieTasten/acc-engineering-agent + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: "--EXP-old-" status: abandoned @@ -377,8 +379,8 @@ language: C++ created_at: "2014-03-24T17:32:25Z" updated_at: "2023-01-28T21:20:54Z" - og_image: >- - https://opengraph.githubassets.com/c3fd98e44e7d55e8ad9d13b2ca76abd35692c9c5f490da574526cc4288526317/InDieTasten/--EXP-old- + og_image: /project-placeholder.svg + custom_image_url: null archived: true - name: "--libavc-test" status: abandoned @@ -390,8 +392,8 @@ language: C++ created_at: "2014-09-21T16:36:20Z" updated_at: "2023-01-28T21:20:54Z" - og_image: >- - https://opengraph.githubassets.com/c3fd98e44e7d55e8ad9d13b2ca76abd35692c9c5f490da574526cc4288526317/InDieTasten/--libavc-test + og_image: /project-placeholder.svg + custom_image_url: null archived: true - name: "--CodeX" status: abandoned @@ -403,8 +405,8 @@ language: Lua created_at: "2014-11-21T22:50:29Z" updated_at: "2023-01-28T21:20:54Z" - og_image: >- - https://opengraph.githubassets.com/c3fd98e44e7d55e8ad9d13b2ca76abd35692c9c5f490da574526cc4288526317/InDieTasten/--CodeX + og_image: /project-placeholder.svg + custom_image_url: null archived: true - name: "--2k16" status: abandoned @@ -416,8 +418,8 @@ language: HTML created_at: "2015-12-31T23:05:18Z" updated_at: "2023-01-28T21:20:54Z" - og_image: >- - https://opengraph.githubassets.com/c3fd98e44e7d55e8ad9d13b2ca76abd35692c9c5f490da574526cc4288526317/InDieTasten/--2k16 + og_image: /project-placeholder.svg + custom_image_url: null archived: true - name: "--Formal" status: abandoned @@ -429,8 +431,8 @@ language: C++ created_at: "2016-05-05T10:20:27Z" updated_at: "2023-01-28T21:20:54Z" - og_image: >- - https://opengraph.githubassets.com/c3fd98e44e7d55e8ad9d13b2ca76abd35692c9c5f490da574526cc4288526317/InDieTasten/--Formal + og_image: /project-placeholder.svg + custom_image_url: null archived: true - name: REEL status: abandoned @@ -442,7 +444,8 @@ language: Lua created_at: "2016-10-01T13:35:15Z" updated_at: "2023-01-28T20:40:31Z" - og_image: https://opengraph.githubassets.com/073c830c82460c54e6b207c421a99ad8fa9f4931b7d4bf7604410f3ad275d2cf/InDieTasten/REEL + og_image: /project-placeholder.svg + custom_image_url: null archived: true - name: b0tnet status: abandoned @@ -458,7 +461,8 @@ language: TypeScript created_at: "2017-03-15T19:20:41Z" updated_at: "2023-10-11T23:56:41Z" - og_image: https://repository-images.githubusercontent.com/85112149/e96a4f00-fa8a-11e9-8f81-fa2ae4bffe68 + og_image: /project-images/b0tnet-e96a4f00-fa8a-11e9-8f81-fa2ae4bffe68.png + custom_image_url: https://repository-images.githubusercontent.com/85112149/e96a4f00-fa8a-11e9-8f81-fa2ae4bffe68 archived: true - name: Top-Down-Heist status: abandoned @@ -474,8 +478,8 @@ language: C# created_at: "2017-12-17T02:15:37Z" updated_at: "2023-01-28T06:31:07Z" - og_image: >- - https://opengraph.githubassets.com/ce3d50dab3c3bd0de7f1b9c7be0362df12ef7d65e0893df97b33b90bde80809b/InDieTasten/Top-Down-Heist + og_image: /project-placeholder.svg + custom_image_url: null archived: true - name: indie-classes status: abandoned @@ -487,8 +491,8 @@ language: Lua created_at: "2018-01-06T18:37:16Z" updated_at: "2018-01-06T18:38:25Z" - og_image: >- - https://opengraph.githubassets.com/5195963ea8fea5e48834f1b7c6a5f83d6b6ec5f0125e736e410ba32363d2c871/InDieTasten/indie-classes + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: indie-ml status: abandoned @@ -500,8 +504,8 @@ language: Lua created_at: "2018-01-06T18:39:44Z" updated_at: "2023-01-28T15:41:45Z" - og_image: >- - https://opengraph.githubassets.com/8448a3bf506b4cc143b0c7ae2aa3619e6ebc8d403c6299b467c60b33756a7be4/InDieTasten/indie-ml + og_image: /project-placeholder.svg + custom_image_url: null archived: true - name: CSharp.lua status: abandoned @@ -517,8 +521,8 @@ language: C# created_at: "2018-04-21T12:41:43Z" updated_at: "2023-01-28T15:41:45Z" - og_image: >- - https://opengraph.githubassets.com/8448a3bf506b4cc143b0c7ae2aa3619e6ebc8d403c6299b467c60b33756a7be4/InDieTasten/CSharp.lua + og_image: /project-placeholder.svg + custom_image_url: null archived: true - name: CC-CSharp status: abandoned @@ -530,8 +534,8 @@ language: null created_at: "2018-04-21T14:50:29Z" updated_at: "2023-01-28T15:41:45Z" - og_image: >- - https://opengraph.githubassets.com/8448a3bf506b4cc143b0c7ae2aa3619e6ebc8d403c6299b467c60b33756a7be4/InDieTasten/CC-CSharp + og_image: /project-placeholder.svg + custom_image_url: null archived: true - name: RetailPro.Backend status: abandoned @@ -543,8 +547,8 @@ language: C# created_at: "2018-09-27T23:35:57Z" updated_at: "2024-10-13T17:32:36Z" - og_image: >- - https://opengraph.githubassets.com/dec424542de9106a21663fe241c99ac13142eb8251ae987e4867d77cd32a514f/InDieTasten/RetailPro.Backend + og_image: /project-placeholder.svg + custom_image_url: null archived: true - name: BadRazorInjectionExample status: abandoned @@ -556,8 +560,8 @@ language: C# created_at: "2018-09-29T13:28:06Z" updated_at: "2023-06-28T06:34:04Z" - og_image: >- - https://opengraph.githubassets.com/61929546e133c92319867075331df73ad6293d80d17e339d516b2e4105cd2302/InDieTasten/BadRazorInjectionExample + og_image: /project-placeholder.svg + custom_image_url: null archived: true - name: DevTease.VueTs status: abandoned @@ -573,8 +577,8 @@ language: Vue created_at: "2018-10-26T15:51:57Z" updated_at: "2023-06-28T06:25:23Z" - og_image: >- - https://opengraph.githubassets.com/0ce0e4acc4fd354a0a137d335672a4b82d4db94c40fc31f4ff2c9bbc1d325ad1/InDieTasten/DevTease.VueTs + og_image: /project-placeholder.svg + custom_image_url: null archived: true - name: DevTease.DI status: abandoned @@ -586,8 +590,8 @@ language: C# created_at: "2019-01-22T19:18:47Z" updated_at: "2020-12-20T11:25:24Z" - og_image: >- - https://opengraph.githubassets.com/54bff6fe6f739a46969e2961fb25a0d45ed190f44995c41325764ab0a623d3ee/InDieTasten/DevTease.DI + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: breadstone status: abandoned @@ -604,7 +608,8 @@ language: HTML created_at: "2019-07-19T19:14:26Z" updated_at: "2022-08-01T10:11:25Z" - og_image: https://repository-images.githubusercontent.com/197829352/8b0d6880-c46a-11e9-903b-6500e4a61ad2 + og_image: /project-images/breadstone-8b0d6880-c46a-11e9-903b-6500e4a61ad2.png + custom_image_url: https://repository-images.githubusercontent.com/197829352/8b0d6880-c46a-11e9-903b-6500e4a61ad2 archived: false - name: terminal-damage status: abandoned @@ -616,8 +621,8 @@ language: HTML created_at: "2020-03-19T20:32:33Z" updated_at: "2021-11-30T08:06:20Z" - og_image: >- - https://opengraph.githubassets.com/4838fded7665b4bb8fbe3363342e1fafdf39ae5043a9f3582896b295f17662b7/InDieTasten/terminal-damage + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: TextAdventure.NET status: abandoned @@ -633,8 +638,8 @@ language: C# created_at: "2020-08-19T19:48:19Z" updated_at: "2025-07-06T01:28:41Z" - og_image: >- - https://opengraph.githubassets.com/3b5246ea36117acb0c762cc7cdc0c045dbf43e6d114e527a44f72060353392f2/InDieTasten/TextAdventure.NET + og_image: /project-placeholder.svg + custom_image_url: null archived: true - name: SpaceRace status: abandoned @@ -648,8 +653,8 @@ language: C# created_at: "2020-11-03T19:40:16Z" updated_at: "2025-07-06T01:25:33Z" - og_image: >- - https://opengraph.githubassets.com/cb73277f82ff5a8f8bc9b7f6399de4fd55541e9c9aa0c2510361fcb5a72ea8dd/InDieTasten/SpaceRace + og_image: /project-placeholder.svg + custom_image_url: null archived: true - name: VirtualDev status: abandoned @@ -667,8 +672,8 @@ language: C# created_at: "2021-01-24T11:06:26Z" updated_at: "2025-07-06T01:26:04Z" - og_image: >- - https://opengraph.githubassets.com/93c3c92df8bc9dcc1966c578a76306a75f6b7d9df64ee62f90090aa92e363727/InDieTasten/VirtualDev + og_image: /project-placeholder.svg + custom_image_url: null archived: true - name: CliSpectrogram.NET status: abandoned @@ -680,8 +685,8 @@ language: C# created_at: "2021-01-29T18:04:59Z" updated_at: "2024-04-21T00:53:45Z" - og_image: >- - https://opengraph.githubassets.com/16724d3abfd4f9baea468f3e870de7a53ca93c90e5a2cd17ab96fd9d6742c396/InDieTasten/CliSpectrogram.NET + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: DevTease.Rasa status: abandoned @@ -693,8 +698,8 @@ language: Python created_at: "2021-02-09T20:53:57Z" updated_at: "2021-02-09T20:55:13Z" - og_image: >- - https://opengraph.githubassets.com/2fd7ce10cfbfa42752ecbd803911b5ee6e93c9d8beea6311c2796075e3123cac/InDieTasten/DevTease.Rasa + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: WikiWebhookTestRepo status: abandoned @@ -708,8 +713,8 @@ language: null created_at: "2021-07-27T10:37:08Z" updated_at: "2021-07-27T10:37:08Z" - og_image: >- - https://opengraph.githubassets.com/b2ef3529ce0618b45e991908d203c0571e75d9095ec7f469d493a7c6fb43fb33/InDieTasten/WikiWebhookTestRepo + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: CoinTale status: abandoned @@ -721,8 +726,8 @@ language: C# created_at: "2022-01-22T23:02:06Z" updated_at: "2023-01-28T02:25:57Z" - og_image: >- - https://opengraph.githubassets.com/eb8b9778ba864646b9cdee0515512835d5e798b420251852bf0689e2c4a6df8f/InDieTasten/CoinTale + og_image: /project-placeholder.svg + custom_image_url: null archived: true - name: operator-game status: abandoned @@ -738,8 +743,8 @@ language: Rust created_at: "2023-10-09T01:50:19Z" updated_at: "2025-07-06T01:27:03Z" - og_image: >- - https://opengraph.githubassets.com/171265910da829c16988fb40699baadfb48613faa1efa1cb4ec80dacc0364d31/InDieTasten/operator-game + og_image: /project-placeholder.svg + custom_image_url: null archived: true - name: astats-fast status: abandoned @@ -751,8 +756,8 @@ language: null created_at: "2024-05-05T11:54:03Z" updated_at: "2024-05-24T03:28:14Z" - og_image: >- - https://opengraph.githubassets.com/40427b9fa7fd4bd63800262e35132798348ea395deb2d696b60994733df1d2e9/InDieTasten/astats-fast + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: flat-game status: abandoned @@ -764,8 +769,8 @@ language: null created_at: "2024-05-05T11:56:03Z" updated_at: "2024-05-05T11:56:07Z" - og_image: >- - https://opengraph.githubassets.com/038a633786e8da1f68a93c02dc569695a8db7a60d03fe478044c50e412136aa6/InDieTasten/flat-game + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: connect-ice status: abandoned @@ -777,8 +782,8 @@ language: null created_at: "2024-05-05T11:57:10Z" updated_at: "2024-05-05T11:57:14Z" - og_image: >- - https://opengraph.githubassets.com/24fecfa1d262af239bd5686212ed85feac1d121487ecb8dd2c75031ed040741d/InDieTasten/connect-ice + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: Novel-Now status: abandoned @@ -790,8 +795,8 @@ language: null created_at: "2024-05-05T11:58:59Z" updated_at: "2024-05-05T11:59:03Z" - og_image: >- - https://opengraph.githubassets.com/dd7fdd71dcce6f6caf5927ce1b3d5f5fa942baf102f68e4744bde5703e0f244f/InDieTasten/Novel-Now + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: Leergut-Simulator status: abandoned @@ -805,8 +810,8 @@ language: null created_at: "2024-05-05T12:00:24Z" updated_at: "2024-05-05T12:00:27Z" - og_image: >- - https://opengraph.githubassets.com/abfa86bd95787fe3dd0e46ff12aead991f8cdd0558930c766db601e67f2a6da9/InDieTasten/Leergut-Simulator + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: cli-lighthouse-viewer status: abandoned @@ -818,8 +823,8 @@ language: null created_at: "2024-05-05T12:01:00Z" updated_at: "2024-05-05T12:01:04Z" - og_image: >- - https://opengraph.githubassets.com/577b4abadf36d62d560c3f9ff1bee62e5ba86a4e9af9857d6f9d310c9b9f0320/InDieTasten/cli-lighthouse-viewer + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: EduPlex status: abandoned @@ -831,8 +836,8 @@ language: null created_at: "2024-05-05T12:01:25Z" updated_at: "2024-05-05T12:01:29Z" - og_image: >- - https://opengraph.githubassets.com/1dbac8ed912fde031f27ea92cc394675937bff6868d04fba0df671b94aa70c53/InDieTasten/EduPlex + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: Shady-Comms-Inc status: abandoned @@ -844,8 +849,8 @@ language: null created_at: "2024-05-05T19:32:56Z" updated_at: "2024-05-05T19:33:00Z" - og_image: >- - https://opengraph.githubassets.com/5b97838c93719eb0fdb98d87086bad38b163a0382b894c29b3dcb5276afe5cb0/InDieTasten/Shady-Comms-Inc + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: gh-extraordinaire-farm status: abandoned @@ -859,8 +864,8 @@ language: null created_at: "2024-05-24T01:34:56Z" updated_at: "2024-05-24T01:34:56Z" - og_image: >- - https://opengraph.githubassets.com/263debf3ecb6d5a8d1427466190319c54062e54c1f788990a6e297e9d5f3541a/InDieTasten/gh-extraordinaire-farm + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: gh-sine-activity status: abandoned @@ -872,8 +877,8 @@ language: null created_at: "2024-05-24T01:36:29Z" updated_at: "2024-05-24T01:36:29Z" - og_image: >- - https://opengraph.githubassets.com/7a27fd9e92b89417366065e831fb874681f86df4e914ac4e11a868de4d1549ea/InDieTasten/gh-sine-activity + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: gpg-signing-test status: abandoned @@ -885,8 +890,8 @@ language: null created_at: "2024-07-22T12:20:39Z" updated_at: "2024-07-22T13:11:31Z" - og_image: >- - https://opengraph.githubassets.com/25745dd2eeabfa3c3c279f7cc792a3972d13a04cb24ae038cbc8d062fd7533c3/InDieTasten/gpg-signing-test + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: lua-test status: abandoned @@ -898,8 +903,8 @@ language: Lua created_at: "2024-07-22T20:48:06Z" updated_at: "2024-07-22T21:15:22Z" - og_image: >- - https://opengraph.githubassets.com/fe5cbf7bca9d6a2c219e6137fe0a50835ffc9d9cf02c1a1eb146542dd70d9f7a/InDieTasten/lua-test + og_image: /project-placeholder.svg + custom_image_url: null archived: false - name: Anti-GH-Pages-Yank status: abandoned @@ -911,6 +916,6 @@ language: null created_at: "2024-10-20T21:25:42Z" updated_at: "2024-11-08T04:00:20Z" - og_image: >- - https://opengraph.githubassets.com/7257ee479f942d8005045c2948a60a6e0455b2ce88463571d098c4e88d68e04c/InDieTasten/Anti-GH-Pages-Yank + og_image: /project-placeholder.svg + custom_image_url: null archived: false diff --git a/package.json b/package.json index 89c314c..be94bbb 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,8 @@ "private": true, "scripts": { "dev": "next dev --turbopack", - "build": "next build" + "download-project-images": "node scripts/download-project-images.js", + "build": "npm run download-project-images && next build" }, "dependencies": { "@headlessui/react": "2.2.4", diff --git a/public/project-placeholder.svg b/public/project-placeholder.svg new file mode 100644 index 0000000..e287382 --- /dev/null +++ b/public/project-placeholder.svg @@ -0,0 +1,12 @@ + + + + + + + + + Project Preview + \ No newline at end of file diff --git a/scripts/download-project-images.js b/scripts/download-project-images.js new file mode 100644 index 0000000..3309842 --- /dev/null +++ b/scripts/download-project-images.js @@ -0,0 +1,141 @@ +#!/usr/bin/env node + +/** + * Download Project Images Script + * Downloads custom repository images for projects during build time + */ + +const fs = require('fs'); +const path = require('path'); +const yaml = require('js-yaml'); + +const log = (message) => console.log(`[INFO] ${message}`); +const warn = (message) => console.log(`[WARN] ${message}`); +const error = (message) => { + console.error(`[ERROR] ${message}`); + process.exit(1); +}; + +async function downloadProjectImages() { + const projectsFile = path.join(process.cwd(), '_data', 'projects.yml'); + const imagesDir = path.join(process.cwd(), 'public', 'project-images'); + + // Check if projects file exists + if (!fs.existsSync(projectsFile)) { + error('projects.yml not found. Please run fetch-projects.sh first.'); + } + + // Load projects data + log('Loading projects data...'); + const fileContents = fs.readFileSync(projectsFile, 'utf8'); + const projects = yaml.load(fileContents); + + // Create images directory + if (!fs.existsSync(imagesDir)) { + fs.mkdirSync(imagesDir, { recursive: true }); + log('Created project-images directory'); + } + + // Download images for projects with custom_image_url + const projectsWithImages = projects.filter(project => project.custom_image_url); + + if (projectsWithImages.length === 0) { + log('No projects with custom images found'); + return; + } + + log(`Found ${projectsWithImages.length} projects with custom images`); + + for (const project of projectsWithImages) { + try { + const imageUrl = project.custom_image_url; + const imagePath = project.og_image; // This is the local path like "/project-images/filename" + + if (!imagePath || !imagePath.startsWith('/project-images/')) { + warn(`Skipping ${project.name}: Invalid image path`); + continue; + } + + // Extract filename from the path + const filename = path.basename(imagePath); + const fullPath = path.join(imagesDir, filename); + + // Skip if image already exists + if (fs.existsSync(fullPath)) { + log(`Image already exists for ${project.name}, skipping`); + continue; + } + + log(`Downloading image for ${project.name}...`); + + const response = await fetch(imageUrl); + if (!response.ok) { + warn(`Failed to download image for ${project.name}: ${response.status} ${response.statusText}`); + continue; + } + + const arrayBuffer = await response.arrayBuffer(); + const buffer = Buffer.from(arrayBuffer); + + // Determine correct file extension based on content type or magic bytes + let extension = '.jpg'; // default + const contentType = response.headers.get('content-type'); + if (contentType) { + if (contentType.includes('png')) { + extension = '.png'; + } else if (contentType.includes('gif')) { + extension = '.gif'; + } else if (contentType.includes('webp')) { + extension = '.webp'; + } + } else { + // Check magic bytes for GIF + if (buffer.length >= 3 && + buffer[0] === 0x47 && buffer[1] === 0x49 && buffer[2] === 0x46) { + extension = '.gif'; + } else if (buffer.length >= 8 && + buffer[0] === 0x89 && buffer[1] === 0x50 && buffer[2] === 0x4E && buffer[3] === 0x47) { + extension = '.png'; + } + } + + // Update filename with correct extension + const baseFilename = filename.replace(/\.[^.]+$/, ''); // Remove existing extension + const correctedFilename = baseFilename + extension; + const correctedPath = path.join(imagesDir, correctedFilename); + + fs.writeFileSync(correctedPath, buffer); + log(`Downloaded and saved: ${correctedFilename}`); + + // If the filename changed, we need to update the project data + if (correctedFilename !== filename) { + log(`Updated filename for ${project.name}: ${filename} -> ${correctedFilename}`); + project.og_image = `/project-images/${correctedFilename}`; + } + + } catch (err) { + warn(`Error downloading image for ${project.name}: ${err.message}`); + } + } + + // Update the projects file with any corrected filenames + const updatedYaml = yaml.dump(projects, { + indent: 2, + lineWidth: 120, + quotingType: '"', + forceQuotes: false + }); + + fs.writeFileSync(projectsFile, updatedYaml); + log('Project images download completed'); +} + +// Run the script +if (require.main === module) { + downloadProjectImages().catch(error => { + console.error('Failed to download project images:', error); + process.exit(1); + }); +} + +module.exports = { downloadProjectImages }; \ No newline at end of file diff --git a/scripts/fetch-projects.sh b/scripts/fetch-projects.sh index 4be70c5..d82f523 100755 --- a/scripts/fetch-projects.sh +++ b/scripts/fetch-projects.sh @@ -130,10 +130,11 @@ async function fetchAllRepos() { tags.unshift(repo.language); } - // Try to get repository's actual OpenGraph image first + // Try to get repository's custom social preview image let ogImage = null; + let customImageUrl = null; - // Try to extract OpenGraph image from repository HTML page + // Try to extract custom repository image from repository HTML page try { const repoPageResponse = await fetch(repo.html_url, { method: 'GET', @@ -148,16 +149,30 @@ async function fetchAllRepos() { // Extract OpenGraph image from meta tag const ogImageMatch = htmlContent.match(/]*>/i); if (ogImageMatch && ogImageMatch[1]) { - ogImage = ogImageMatch[1]; + const imageUrl = ogImageMatch[1]; + + // Check if this is a custom repository image (not the dynamic OpenGraph one) + if (imageUrl.includes('repository-images.githubusercontent.com')) { + // This is a custom social preview image - store URL for build-time processing + customImageUrl = imageUrl; + + // Extract a unique identifier from the URL to create local filename + const urlParts = imageUrl.split('/'); + const imageId = urlParts[urlParts.length - 1] || 'unknown'; + const localFileName = `${repo.name}-${imageId}`; + ogImage = `/project-images/${localFileName}`; + + console.log(`Custom image found for ${repo.name}: ${imageUrl}`); + } } } } catch (error) { console.log(`Could not fetch repository page for ${repo.full_name}: ${error.message}`); } - // Use the dynamic OpenGraph image as fallback + // Use generic placeholder for projects without custom images if (!ogImage) { - ogImage = `https://opengraph.githubassets.com/1/${repo.full_name}`; + ogImage = '/project-placeholder.svg'; } const project = { @@ -171,6 +186,7 @@ async function fetchAllRepos() { created_at: repo.created_at, updated_at: repo.updated_at, og_image: ogImage, + custom_image_url: customImageUrl, archived: repo.archived }; diff --git a/src/interfaces/project.ts b/src/interfaces/project.ts index f7f0db2..3c7d25c 100644 --- a/src/interfaces/project.ts +++ b/src/interfaces/project.ts @@ -10,5 +10,6 @@ export type Project = { created_at?: string; updated_at?: string; og_image?: string; + custom_image_url?: string; archived?: boolean; }; \ No newline at end of file