From 86c92034a71d5e9cc9df1581519c5540f79c1631 Mon Sep 17 00:00:00 2001 From: Ari Archer Date: Wed, 18 Dec 2024 02:14:35 +0200 Subject: [PATCH] update @ Wed Dec 18 02:14:35 EET 2024 Signed-off-by: Ari Archer --- blog.json | 31 +++++++++++++++++- content/post_critical.css | 2 +- ...d19a2ef5b0c06102a8526b2157d14ec9e3db24.png | Bin 0 -> 35687 bytes media/media.json | 13 ++++++++ scripts/blog.py | 20 +++++++++-- 5 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 media/0867cea01b7f0dda58de112b78d19a2ef5b0c06102a8526b2157d14ec9e3db24.png diff --git a/blog.json b/blog.json index 2b24bb2..66e9af7 100644 --- a/blog.json +++ b/blog.json @@ -133,8 +133,37 @@ "top-words": 64, "top-tags": 64, "code-style": "coffee", - "note": "This page uses the Nerd Hack Font, which is licensed under the OFL 1.1 License. All internal content, unless specified otherwise, is subject to their respective license terms as well as Ari-web legal policies.", + "note": "This page uses the Nerd Hack Font, which is licensed under the OFL 1.1 License. All internal content, unless specified otherwise, is subject to their respective license terms as well as Ari-web legal policies. Treat the content and the source of the page as source code according to the license.", "posts": { + "rust-bad-ii": { + "title": "rust bad II", + "description": "An analysis of the Rust programming language 3 years later from my las blog post: its major flaws, complexities, and issues that make it not an ideal language for developers. My post goes in-depth into the personal and experiences, driven view of the language's deficiencies, such as its complexity, fragmentation, and toxicity within the community, thus putting its ultimate viability in question.", + "content": "Hi!\n\nA while ago, 2021-11-07 (more than 3 years ago as of writing this), I made a blog post about the Rust programming language, criticising its uselessness. At the time, I gave really easy to beat arguments and made me seem like a clown in a way, which, in retrospect - is funny. To be fair, I didn't dig *that* deep into Rust, but I believe I did have minimal experience with it, and ***a lot*** of idiocy exposure coming from the Rust side; the hype, the libraries, the memes, the community, and the code as well of course.\n\n<@:2f279788d90f6ddae8d49c49674ac899f078bb94243b1b0aabf711e17fc3f482>\n\nSo, over 3 years later, what do I think about the language now as the tides have calmed down a little? That's what I will be discussing today in a calmer tone, trying to avoid being as bold as I was in the original post, which at the time I edited and retracted my bold claims. Furthermore, I have more experience with Rust and the long-term exposure to everything has probably made me more desensitised to it, also, the criticisms of Rust being talked about more has also made me more confident to cover this topic. But I have to say, my opinion and view on Rust, albeit shifted, is still negative.\n\nWell, anyway - Rust.\n\n## Acknowledging the bias\n\nThis post is very biased since I was never a fan of the Rust programming language due to various factors I will discuss today. Viewing this through a fully rational lens, Rust is just a language and there's nothing more to it - just another tool I can use if I want to to develop various programs and tell the computer what I want it to do.\n\nThus, I will be portraying my view on Rust through my biases, opinions, experiences, and feelings towards it. Of course, Rust is probably the last thing that comes to mind when I think about something, but, I just want to share my opinion through a more grown up perspective than I was over 3 years ago (I was like in my early 14s since I am now 17, which is wild!).\n\nFurthermore, I don't have major experience with the Rust programming language. I was interested in it for some time because of the hype but quickly became cold to it. I minimally contributed to a couple of Rust-based projects, but, once again - nothing major. Though, most of my experience with rust comes from messing with rust (like doing a challenge where I did 30 days of pure Rust (doing like 1-3 programs in Rust for 30 days, I did this back in 2022 to \"Prove the rusties wrong\" and to be fair I did prove an annoying guy wrong, I hated all of it), or just seeing what it has from time to time), reading Rust code from open source projects, hearing about Rust as well as observing its state - which means that even though I do have somewhat of a better voice on Rust than I had 3+ years ago, I still have pretty minimal involvement in Rust over like a full-time / fully-hobby Rust developer, so take my words with a grain of salt.\n\n## My concerns about rust in short\n\nMy concerns about rust are nothing extraordinary, at least I don't think that they're truly anything unique, I just want to make my stance clearer in a \"better\" tone. Regardless, in short, the following list describes my concerns in short and why I don't think Rust is \"the language\" like many like to put it, we'll dig all of them individually later :)\n\n1. Its increasing complexity, verbosity, and ever-saturating ecosystem. Consequently creating a language which is hard to use, understand, control, on top of an ecosystem that further mirrors JavaScript's heavy dependence on 3rd party frameworks. Hell, in 2024 we STILL don't have built in `random`!\n2. Over-structuring and strictness of the language, which creates a strong dependency on 3rd party libraries with very high level features, resulting in various inefficiencies and vastly increased compile times. Moreover, its strictness terribly impacts the usability of the language in fields like systems' development, leading to a need of hack-arounds and `unsafe` code blocks.\n3. Arrogance and toxicity in the Rust community. This is a massive issue which I've been a victim of myself many times, even when having genuine interest in the language. Even the Rust moderators stepped down from their roles some time ago due to not being able to enforce community standards, but I don't remember what happened after.\n4. Rust's runtime and compile-time costs are also harshly juxtaposition lightweight languages like C, or even C++. This is not only a technical problem, but also an environmental problem, considering its further adoption in the world and how it has the potential to be quite a wide-spread language, it should strive to be as efficient and (environmentally) friendly as possible to reduce waste in today's dying world.\n5. Severe fragmentation in the Rust ecosystem is also a big issue for open discussion. Albeit, some stuff Rust developers achieve is impressive, there's no denying that, but most general-purposes languages have their focuses or niches despite being able to do other things, such as Python (data science), JavaScript (Web development), C (system's development), C++ (games, higher level performance-critical applications), R (statistics), PHP (server-side scripting), shell scripting (automation), etc. While Rust feels like they're trying to do everything, which oftentimes leads to fragmentation and incompleteness.\n6. Finally, hype around the language is still relevant (although that's not nearly as bad as it was 3 years ago). This hype ushers us to make quick decisions which we later regret or at least could have spent more time on. For instance, the aggressive push of Rust in the Linux kernel was a discourse, it made it in, and in my opinion: that was not a very smart idea. But more about that later. Regardless, despite the hype, its adoption is still relatively low, and even though it is pushed aggressively - maybe it's time to think about its longevity ignoring the hype surrounding it?\n\nThis time I'll focus on these arguments as these are what concern me the most,\n\n## Concern 1: Increasing complexity, verbosity, and ever-saturating ecosystem\n\nFrom watching rust from afar, time to time getting closer to it, I've seen the language get more complex, verbose, and ever more saturated with various libraries, frameworks, and features. I've also had the criticism of its bad syntax and it hasn't changed, of course, that's subjective, I guess. I, personally, am very used to the simple syntax of languages like Python and C, even C++ is more simple and less noisy than Rust! Let me give you a comparison I came across today when I saw a beginner Rust developer try to make a simple application in Rust:\n\nThey tried to make a random number guessing game in Rust where they read the number from the standard input and the user tries to guess a random number generated by the program. Well, even though I don't have the exact example now, it was something like this (made by me) (**note:** I know the PRNG isn't seeded, ignore it. It doesn't make any difference in my point and I already wrote this \ud83d\ude2d):\n\n```rs\nuse std::io;\nuse rand::Rng;\n\nfn main() {\n let n = rand::thread_rng().gen_range(1..=100);\n\n println!(\"Guess the number: \");\n\n let mut input = String::new();\n io::stdin()\n .read_line(&mut input)\n .expect(\"Failed to read the number\");\n\n let g: u32 = match input.trim().parse() {\n Ok(num) => num,\n Err(_) => {\n println!(\"Please enter a valid number.\");\n return;\n }\n };\n\n if g != n {\n println!(\"No! The number was {}.\", n);\n } else {\n println!(\"Correct!\");\n }\n}\n```\n\nAnd you know the best part? This isn't even the whole of it. You need a whole Cargo project and Cargo.toml that looks like this:\n\n```toml\n[package]\nname = \"game\"\nversion = \"0.1.0\"\nedition = \"2021\"\n\n[dependencies]\nrand = \"^0.8.5\"\n```\n\nThen you need to run `cargo build --release` (or `b` instead of `build`) to end up with:\n\n- 19 crates downloaded and built on your system.\n- 6.61s compile time.\n- 441 KB binary. (due to static linking most likely, but even then it depends on libc and libgcc dynamically)\n- 15 MB of Cargo cache.\n- 31 MB build directory.\n- And uhhh a basic game, I guess.\n\nI am not joking:\n\n<@:43fef629105fdc1cd04e6f400abed839d988c23f67223a8d3fe1674fe02e42e1>\n\nThis is funny to me when you see the C example:\n\n```c\n#include \n#include \n\nint main(void) {\n unsigned g;\n const unsigned n = rand() % 100 + 1;\n\n fputs(\"Guess the number: \", stdout);\n scanf(\"%u\", &g);\n\n if (g != n)\n printf(\"No! The number was %u.\\n\", n);\n else\n puts(\"Correct!\");\n\n return 0;\n}\n```\n\nOr even the C++ one:\n\n```cpp\n#include \n#include \n\nint main() {\n unsigned g;\n const unsigned n = std::rand() % 100 + 1;\n\n std::cout << \"Guess the number: \";\n std::cin >> g;\n\n if (g != n)\n std::cout << \"No! The number was \" << n << \".\\n\";\n else\n std::cout << \"correct.\" << '\\n';\n\n return 0;\n}\n```\n\nWhere in both cases you end up with:\n\n- A short, simple program.\n- 0 dependencies. (except stuff like libc_\n- 0.06s (in case of C), and 0.39s (in case of C++) compile times.\n- 14 KB binary. (you are able to strip it down to about 6-7 KB if you try with compiler flags)\n- 0 cache.\n- And a basic game!\n\n<@:a22e9a8beb3154523ba368302bedede134df659950925a9968b49cc265cefb7a>\n\nThis stupid example shows how complex, verbose, and saturated Rust is. The sheer size of the source code is enough to show the complexity and verbosity of the language. Then, there's the need for Cargo to even *begin* building the project, and even if you do, you need to download 19 crates. What kind of madness is this! This is the mere epidemic of [modernism](https://blog.ari.lt/b/modernism/) I talked in the past. The post about modernism is quick and has bold and unprecedented language, but it's essentially what Rust is - something modern, which is clearly a waste in so many ways, the peak of modernism; the hype, the size, the reach for a great goal but flopping it so bad in sacrifice of... Everything?\n\n## Concern 2: Over-structuring and strictness of the language\n\nFurther expanding on the first concern, the over-structuring and strictness of it present significant challenges that hinder its usability. This complexity has led to a strong dependency on third-party libraries (as shown in the first example) that offer high-level features, resulting in inefficiencies and increased compile times (once again proven by the first example). This over-structuring and its strictness has made system's development in rust particularly hard (even though some may argue otherwise), and has forced a culture of dependencies and writing unsafe code, mitigating essentially the main point of Rust - its safety - yet still leaving the major disadvantages that come with the Rust ecosystem.\n\nIts over-structuring also limits people's ability to create unique solutions to problems, well, hinders it. It makes it hard to take different approaches because there is so much to navigate, and where C - a simple language - allows you essentially full control, Rust will force you into an indefinite loop of callbacks and various, sometimes unnecessary, error handling, as well as its policy on ownership and other safety features. Also, as much as Rust focuses on concurrency, its multi-threading is known to be notoriously annoying and painful, not allowing you to easily and maybe even fully effectively take full advantage of multi-threading.\n\nThis safety model is very strict and awfully structured, and as a result of this, it leads to runtime costs you wouldn't see in a simple language like C. And if not runtime costs - it's hack-arounds and dependencies to try to make the ecosystem more usable and less complex. This reminds me of one quote:\n\n<@:783a5e8cb6fcc3626a0ebfb08d2c35defa5e4fbfa48f17ebcb3596bffad01cd3>\n\nEven the same Rust developers have concerns about the language's complexity and usability, as a Rust survey back in 2023 showed. InfoWorld covered this back in February of 2024 at , reviewing the [2023 Annual Rust Survey Results](https://blog.rust-lang.org/2024/02/19/2023-Rust-Annual-Survey-2023-results.html). I would cover the 2024 results, but they're not out yet, but you can still contribute to the 2024 results at !\n\n## Concern 3: Arrogance and toxicity in the Rust community\n\nI have a lot of personal experiences with the Rust community, and it rarely has been positive. I've heard many people had a similar experiences with the Rust community - a toxic, often annoying and arrogant, mess.\n\nIn fact, I have a pretty irritating story I think about from time to time, though, this memory is quite blurry at this point. Basically, back when I was still naive and only heard how \"perfect\" the Rust programming language is and how the experience is so great and amazing, I had genuine interest in this \"godly\" language, it did look interesting. Well, I joined a couple of Rust communities on a couple of platforms, can't remember which at this point since it happened a while ago, and oh my god I remember it being awful. Fighting about random idiocy and pedantics everywhere, impossible to interact with anyone due to how everyone seemed just constantly angry - just overall a horrible first impression, of course hyperbolised, but you get the idea I think, not a good community. Furthermore, one moment sticks out to me from that time. I was learning Rust beginnings, and I had a question about things, and I was essentially screamed at \"READ THE FUCKING MANUAL YOU FUCKING IMBECILE\" and stuff, maybe not the exact words, but still - I was a novice trying to learn and ask the mere people who are there... In a chat where questions are expected? I generally began seeing the Rust community for what it truly is, finally turning my back on it and the language as a whole.\n\nThis story reminds me of how shit the Rust community is, or at least was. But, honestly, none of my recent interactions with any rusties have been nice either. I felt exhausted every time I tried to talk to any of them. It's usually either hyper-left trans puppygirl anarchocommunist who is rewriting every piece of software they see in Rust because they believe that language Aryanism is the solution to everything, or a person who dismisses any criticism thrown as rust as like \"you're just stupid\" or something - this arrogance is something I've ever only observed in Rust communities thus far myself. And I've been in many communities, like various Linux and Linux distribution community, language communities like Python, C, C++, etc., and generally social gatherings of tech nerds, and not a single community do I remember in such a negative light I remember the rust community as. Additionally, people oftentimes dismiss every criticism thrown towards the Rust community as \"you're making it up\" or \"this isn't my experience\", which undermines any open dialogue to be had in my opinion.\n\nOne important thing to note that back in 2021, the whole Rust mod team resigned from their roles () due to \"the Core Team placing themselves unaccountable to anyone but themselves\", which highlights the mess that the Rust structure used to be, and quite possibly still is (although I haven't caught up with any Rust community meta in a long while). This is just sad how Rust community has left such a dirty mark on the whole developer social ecosphere, at least for me, and are like the floating toxic and radioactive shit in the toilet bowl that is full of #RustRewrites and gatekeeping.\n\nSpeaking of rust rewrites, a common occurrence, at least used to be (I don't see as many rewrites nowadays, which is a positive), language Aryanism as I called it above. The C vs Rust discourse feels like \"ViM or Emacs\" discourse back when it was relevant (I don't think anyone really talks about it besides the memes anymore, correct me if I'm wrong). It feels like too many people are too obsessed with the hype of Rust and trying to replace C for like whoever knows what reason. Of course C isn't perfect, far from it, in fact, but Rust community's aggressive push of Rust to replace C by only showing the upsides when disregarding all of its downsides and wastes speaks nothing more to me than language Aryanism.\n\nReminds me of a meme I saw a while ago:\n\n<@:7039b8fd6868afe631aa97acb95222f21a64e1ddee38779142d9f098141bb4c4>\n\nHistorically, they keep trying to replace C, but for what? I know, the tool isn't perfect, but it's *simple*. C is so well-established and simple there's nothing that could truly yet replace it. Regardless, as Linus Torvalds once said -\n\n> To me, Rust was one of those things that made technical sense, but to me personally, even more importantly, we need to not stagnate as a kernel and as developers.\n\nAnd I think it's a nice idea.\n\n## Concern 4: Rust's runtime and compile-time costs\n\nRust is notorious for its terrible compile times, so much so, a whole technical commentary called [mTvare6/hello-world.rs](https://github.com/mTvare6/hello-world.rs) has been made on Rust as a whole, including its large and heavy compile times, large build sizes, dependency hell, and general burdens that come with Rust as well as its costs. Of course, it's a hyperbolised example, but the general idea stays true regardless - its compiler is extremely inefficient and provides huge costs. While caching aids this problem, it's still far from perfect, and the caches tend to get huge as well, wasting more resources.\n\nPer runtime costs, its runtime safety checks can increase the safety of the application, but it comes at a runtime cost to check things, especially for complex applications.\n\nEven a simple example such as\n\n```rs\nuse std::cell::RefCell;\n\nfn main() {\n let data = RefCell::new(5);\n let borrow_mut = data.borrow_mut(); // Mutable borrow\n let borrow = data.borrow(); // Immutable borrow - this will panic at runtime\n}\n```\n\nCreates a lot more cost than in C, which isn't safe, but it crashes regardless, and the crashes you can usually debug using debuggers like `gdb` or writing your own optional runtime abstractions (I've done that in the past for memory debugging). For such things, the best remedy isn't to throw in a bunch of runtime checks, but rather stay aware and implement error checking yourself - which is your job as a developer, though not to say that Rust doesn't make these things easier sometimes with its tooling and error checking insertion, but more often than not it introduces extra costs and noise which quickly adds up.\n\nAnd the Rust compiler itself, even it does so much, doesn't catch such an error for whatever reason:\n\n<@:14a5361b38cd74a9b6d8cd5e2fa63d9ea4a6a813d7780ffb6454a4871ecec996>\n\nAs I mentioned before, this Rust's costs juxtaposition lightweight languages like C or C++, which by default, reducing the overall overhead and making the languages more efficient with less waste.\n\nFurthermore, languages to Rust, while being far from the worst (*cough* JS *cough*), create an environment for having limited ability to create the least wasteful software out there. The tech industry as a whole creates a lot of waste nowadays, and even though one or two projects in the open source space won't make huge of a difference, where I see the problem lie in is the almost mere gaslighting Rust is doing in making companies who use C to switch to Rust, which can accelerate production of waste through electricity wastes in both runtime and compile-time costs, as well as requiring more cooling (which is also wasteful). While on the runtime side the difference may be negligible in release mode, compile time costs are far from it; from personal experience running Gentoo Linux, Rust is ***awful*** in so many ways to compile, so much so that bigger pieces projects written in C seem like a break to my CPU almost.\n\nBut the environmental impact of Rust as a whole is way too early to tell since it's far from well-adopted, although, I believe in the long run this should be considered in the ever-expending that is modern software. Not just the energy required should be considered, but also the storage, the efficiency of the ecosystem, the available optimisations, the costs, and the general impact of the technology.\n\n## Concern 5: Severe fragmentation in the Rust ecosystem\n\nI've noticed that severe fragmentation in the Rust ecosystem often poses challenges for developers and the broader community, because its ambition to span over such wide range of domains leads to a lack of cohesion, unlike in other established languages which have clear niches. Rust's attempt to be a general-purpose language is something I would a pretty impressive attempt to be a fit-all remedy for everything. This lack of cohesion also leads to overwhelming choice and a lack of uniformity, making it hard for developers to navigate and choose appropriate tools and libraries for their projects, resulting in, once again, more waste.\n\nOne of the primary issues stemming from it is the sheer inconsistency in library quality and community support, since, in languages with well-centred purposes it's quite easy to find good libraries for your purpose with great optimisation, as well as great support from experienced people. Where in Rust this often can feel like navigating a maze. Also, Rust's ambitious scope often lead to incomplete implementations of concepts or features that may be crucial for certain applications - or not for others, which is generally a problem with fragmentation.\n\nAdditionally, the challenge of integrating various components within the Rust ecosystem can lead to significant overhead in development processes, which can lead to difficulties, overhead, or other performance issues, as well as increasing the likelihood of bugs.\n\nThis bad fragmentation in the ecosystem is also why I had to download 19 crates to simply generate random numbers, it's not only sad, but it's concerning when with just a little more complexity you have to add more and more dependencies and subdependencies, some of which may even serve a similar purpose. In Rust, more uniformity is a must, or else we will end ourselves in a dependency hell that JavaScript is suffering to this day - and that one is essentially a toy language, in my opinion at least.\n\nHell! Even for basic tasks like random number generation there's over 2000 different libraries to use on crates dot io:\n\n<@:0916be4b05235a7551cffd393b9f92925aaa6695e21c1db6b4ffa0f9a59e76d0>\n\nIt's kind of wild. Of course, diverse approaches are always welcome, but what's the point of all of this? It's time to address the fragmentation, or end up with Rust version of JS' [is-even](https://www.npmjs.com/package/is-even) package, and thousands of others like it.\n\n## Concern 6: Hype around the language\n\nFinally, my last major concern for the language. The hype, which is a theme that kept coming up in this blog post over and over again.\n\nThe current hype around Rust, while diminished compared to three years ago, still influences (mainly new) developers to make hasty decisions regarding adoption. This rush can lead to regrettable choices, particularly when considering the language's integration into critical systems like the Linux kernel, as well as a system that is saturated with people who keep pushing more libraries and stuff and then leave the community because they realise it's not for them, because of the rushed decisions. Aggressive pushes overlook the complexities and potential drawbacks of adopting a relatively new language in established environments.\n\nFurthermore, the promotion of Rust makes me question its longevity: Is it all just hype? Of course, the hype's been around for a bit now, but the adoption stays relatively low, regardless, makes me reconsider is it healthy to push Rust into already such well-established, critical ecosystems like the Linux kernel? The hype not only could lead to technical debt, but it also creates a general scepticism of it, which may accelerate the death of the language or at least stunt its growth and acceptable. Maybe not even *may* - it *does*.\n\nMoreover, the talk about Rust very often emphasizes its specific features, like ownership and borrowing, that promise better safety but at the same time introduce additional complexity, which the same people then sweep under the carpet. This complexity will most likely increase development time and frustration, especially on projects with tight deadlines or when resources are limited. So, was it worth the trade? For many developers, probably not. At least that's my take on it.\n\nThe hyper-optimistic view on rust also creates general negative prejudice, well, attitudes I guess, against Rust developers as a whole like this meme portrays:\n\n<@:86b362afea5c76f61ed65da4762b91fda1a99d302f814b48fbf79a8b1f6bcc94>\n\nI feel the exact same way about it. I'm *tired* of hearing of the \"new and exciting\" and \"how safe it is\" and how \"blazingly fast it is\". I'm tired of the \"rust rewrites\" which take Mona Lisa and produce an A4 piece of paper with the sun drawn at the corner of it (metaphorically). Can we stop being this unrealistic and jump bling into it? And maybe it's time to think about its longevity ignoring the hype surrounding it?\n\n## Conclusion\n\nWell, in conclusion, my experience and opinion of Rust, 3+ years later, is still mainly negative. Although, I think I've made it clearer and less bold this time. While I understand that rust has its merits like memory safety, my concern about its various problems like complexity, over-structuring, fragmentation, longevity, and community toxicity still remain significant years later, and I don't think this is going anywhere any time soon, sadly.\n\nI'm glad been given the chance to express my opinion about the Rust programming language, and for now - until next time!", + "keywords": [ + "disadvantages of rust", + "rust and efficiency", + "compilation costs", + "opinions about rust", + "rust ecosystem", + "rust structure", + "rust security", + "rust and development", + "experience with rust", + "complexity of rust", + "rust hype", + "programming language", + "rust community", + "rust and toxicity", + "rust in 2024", + "learning rust", + "rust c comparison", + "fragmentation in rust", + "rust programming", + "criticism of rust" + ], + "created": 1734472525.14714, + "preview": "0867cea01b7f0dda58de112b78d19a2ef5b0c06102a8526b2157d14ec9e3db24" + }, "install-lineageos-181-xiaomi-redmi-go-tiare": { "title": "How to install LineageOS 18.1 on Xiaomi Redmi GO (Tiare)", "description": "In this blog post, I walk you through a process of installing LineageOS 18.1 with Magisk on Redmi GO (Tiare). I cover various things like recovery, installing, and rooting LineageOS, and later I teach you how to get more swap space for better performance.", diff --git a/content/post_critical.css b/content/post_critical.css index a4af280..197c18a 100644 --- a/content/post_critical.css +++ b/content/post_critical.css @@ -69,7 +69,7 @@ blockquote:before { } .media > img { - max-width: 400px; + max-width: 600px; width: 100%; height: auto; } diff --git a/media/0867cea01b7f0dda58de112b78d19a2ef5b0c06102a8526b2157d14ec9e3db24.png b/media/0867cea01b7f0dda58de112b78d19a2ef5b0c06102a8526b2157d14ec9e3db24.png new file mode 100644 index 0000000000000000000000000000000000000000..fb456de1597723c12184cb999d16787c74e42831 GIT binary patch literal 35687 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 Hack Font, which is licensed under the OFL 1.1 License. All internal content, unless specified otherwise, is subject to their respective license terms as well as Ari-web legal policies.', + "note": 'This page uses the Nerd Hack Font, which is licensed under the OFL 1.1 License. All internal content, unless specified otherwise, is subject to their respective license terms as well as Ari-web legal policies. Treat the content and the source of the page as source code according to the license.', "posts": {}, } @@ -580,6 +580,11 @@ def select_posts(posts: dict[str, dict[str, typing.Any]]) -> tuple[str, ...]: def select_medias(type: typing.Optional[str] = None) -> tuple[str, ...]: + if os.path.exists("media/media.json"): + with open("media/media.json", "r") as fp: + MEDIA_INDEX.clear() + MEDIA_INDEX.update(json.load(fp)) + if type: return tuple( map( @@ -821,8 +826,9 @@ def parse_inline_media_embed( {"type": "linebreak"}, { "type": "emphasis", - "raw": f"{mdx['alt']} | \"{mdx['title']}\" by {mdx['credit']} ({mdx['license']}). Purpose: {mistune.escape(mdx['purpose'])}. Uploaded on {datetime.datetime.utcfromtimestamp(mdx['uploaded']).strftime('%a, %d %b %Y %H:%M:%S GMT')}. ", + "raw": f"{mdx['alt']} | \"{mdx['title']}\" by {mdx['credit']} ({mdx['license']}). Purpose: {mistune.escape(mdx['purpose'])}. Uploaded on {datetime.datetime.utcfromtimestamp(mdx['uploaded']).strftime('%a, %d %b %Y %H:%M:%S GMT')}.", }, + {"type": "text", "raw": " "}, { "type": "link", "children": [{"type": "text", "raw": f"(raw media here)"}], @@ -1766,7 +1772,15 @@ def media(config: dict[str, typing.Any]) -> int: purpose: str = iinput("media purpose") title: str = iinput("media title") - license: str = ", ".join(select_multi(licenses)) + license: str = ", ".join( + select_multi( + [ + "All-rights-reserved", + "Unknown", + ] + + licenses + ) + ) credit: str = iinput("media credit")