diff --git a/data/talks/12-factor.md b/data/talks/12-factor.md index 0295723..b9c1ef9 100644 --- a/data/talks/12-factor.md +++ b/data/talks/12-factor.md @@ -1,4 +1,5 @@ # The 12 Factor App +*2012* This talk recaps the 12 Factor App methodology, which is a set of best practices for building scalable, maintainable, and portable web applications. diff --git a/data/talks/api-driven-development.md b/data/talks/api-driven-development.md index 6e3c7c2..20d357c 100644 --- a/data/talks/api-driven-development.md +++ b/data/talks/api-driven-development.md @@ -1,4 +1,5 @@ # API Driven Development +*2012* diff --git a/data/talks/awareness-of-self.md b/data/talks/awareness-of-self.md index 6162641..0770611 100644 --- a/data/talks/awareness-of-self.md +++ b/data/talks/awareness-of-self.md @@ -1,4 +1,5 @@ # Awareness of Self +*2024* diff --git a/data/talks/developer-burnout.md b/data/talks/developer-burnout.md index 1619809..5da412c 100644 --- a/data/talks/developer-burnout.md +++ b/data/talks/developer-burnout.md @@ -1,4 +1,5 @@ # The Reality of Developer Burnout +*2015* diff --git a/data/talks/documentation-at-scale.md b/data/talks/documentation-at-scale.md index 9d3a765..f31a8f7 100644 --- a/data/talks/documentation-at-scale.md +++ b/data/talks/documentation-at-scale.md @@ -1,4 +1,5 @@ # Documentation at Scale +*2013* diff --git a/data/talks/documentation-is-king.md b/data/talks/documentation-is-king.md index 4cfb649..1f73b21 100644 --- a/data/talks/documentation-is-king.md +++ b/data/talks/documentation-is-king.md @@ -1,4 +1,5 @@ # Documentation is King +*2011* In this talk, we will discuss the importance of documentation in software development. We will cover the following topics: diff --git a/data/talks/flasky-goodness.md b/data/talks/flasky-goodness.md index 7777661..9d9aa24 100644 --- a/data/talks/flasky-goodness.md +++ b/data/talks/flasky-goodness.md @@ -1,4 +1,5 @@ # Flasky Goodness +*2012* diff --git a/data/talks/future-python-deps.md b/data/talks/future-python-deps.md index 56fc697..caf7d3c 100644 --- a/data/talks/future-python-deps.md +++ b/data/talks/future-python-deps.md @@ -1,4 +1,5 @@ # The Future of Python Dependencies Management +*2018* diff --git a/data/talks/growing-open-source-seeds.md b/data/talks/growing-open-source-seeds.md index c402417..605b5c7 100644 --- a/data/talks/growing-open-source-seeds.md +++ b/data/talks/growing-open-source-seeds.md @@ -1,65 +1,50 @@ # Growing Open Source Seeds +*2014* - ## Introduction -- **Growing Open Source Seeds** explores different approaches to open source projects, highlighting the evolution and challenges in the community, particularly focusing on the philosophy and sustainability of open source contributions. - -This talk emerged from Kenneth's experience maintaining some of the most popular Python packages. His insights into open source sustainability predate many current discussions about maintainer burnout and funding, offering practical wisdom from someone who lived these challenges. +This talk explores the diverse approaches to open source projects, examining the evolution and challenges within the community. It focuses particularly on the philosophy and sustainability of open source contributions, offering insights drawn from years of maintaining some of Python's most popular packages. + +These insights into open source sustainability predate many current discussions about maintainer burnout and funding, offering practical wisdom from someone who lived these challenges firsthand. ## Public vs. Open Source -- **Public Source:** - - Code is released with an open source license, but it may not be actively maintained or developed. - - Often abandoned due to lack of interest or burnout. +There's a crucial distinction between **public source** and truly **open source** projects. Public source involves code released with an open source license, but without active maintenance or development. These projects often become abandoned due to lack of interest or maintainer burnout, littering GitHub with good intentions that never found sustainable support. -- **Gittip Example:** - - An extreme open source project with shared ownership and transparency. - - Major decisions are made through community involvement on platforms like GitHub. - - Represents a "shared investment" model where contributors actively participate in the project's development. +The **Gittip** project exemplified an extreme approach to open source, embracing shared ownership and radical transparency. Major decisions were made through community involvement on platforms like GitHub, with every discussion and debate happening in public view. This represented a "shared investment" model where contributors actively participated in the project's development, creating true collective ownership rather than mere collaboration. ## Dictatorship Projects -- **Requests as a Dictatorship Project:** - - A "Benevolent Dictator For Life" (BDFL) manages the project, making all key decisions. - - While community feedback is encouraged, there is no expectation that it will influence decisions. - - Benefits include quick iteration and maintaining a strong vision, but it carries risks like low bus-factor and high burnout potential. - -Kenneth's frank discussion of the BDFL model was controversial but honest. He recognized that while community-driven projects have benefits, sometimes a single vision is necessary to maintain coherence and prevent feature creep. +The **Requests** library operates as what I call a "dictatorship project" - managed by a Benevolent Dictator For Life (BDFL) who makes all key decisions. While community feedback is encouraged and valued, there's no expectation that it will necessarily influence decisions. This model offers benefits like quick iteration and maintaining a strong, coherent vision, though it carries risks including low bus-factor and high potential for maintainer burnout. + +This frank discussion of the BDFL model was controversial but honest. While community-driven projects have clear benefits, sometimes a single vision is necessary to maintain coherence and prevent feature creep. ## Lessons in Open Source -- **Contributors:** - - Interactions with maintainers should be respectful and appreciative of their time and effort. +For **contributors**, interactions with maintainers should always be respectful and appreciative of their time and effort. Remember that most maintainers are volunteers, often working on projects in their limited free time. Your feature request or bug report is one of hundreds they might be dealing with. -- **Maintainers:** - - Must be thankful to contributors, choose words carefully, and educate users, particularly those new to open source. +**Maintainers** must be thankful to contributors, choose words carefully, and take time to educate users, particularly those new to open source. Every interaction shapes the community culture. A harsh response to a first-time contributor might discourage not just that individual, but others watching the exchange. ## Avoiding Burnout -- **Sustainability:** - - Open source is challenging to sustain due to time constraints and the risk of becoming a bottleneck in one’s own projects. - - Emphasizes the importance of purpose, mastery, and autonomy in maintaining motivation. +Open source sustainability remains one of the greatest challenges in software development. Projects become difficult to sustain due to time constraints and the risk of maintainers becoming bottlenecks in their own projects. The key lies in maintaining purpose, mastery, and autonomy - the three pillars of intrinsic motivation. -- **Delegation:** - - Leveraging a team to handle issues and pull requests can help maintainers focus on larger issues, improving sustainability. +**Delegation** becomes essential for long-term sustainability. By leveraging a team to handle issues and pull requests, maintainers can focus on larger architectural decisions and strategic direction, improving both the project's health and their own well-being. ## The Power of Saying No -- **Simplicity Over Functionality:** - - Maintain simplicity by rejecting features or pull requests that add unnecessary complexity. - - Simple code is easier to maintain, while complex code leads to technical debt and higher maintenance burdens. +Perhaps the most important lesson I've learned is the power of maintaining simplicity by rejecting features or pull requests that add unnecessary complexity. Simple code is easier to maintain, understand, and extend. Complex code leads to technical debt and exponentially higher maintenance burdens. + +This philosophy helped Requests maintain its elegant simplicity despite thousands of feature requests, proving that restraint can be more valuable than addition. -The power of saying "no" became a central principle in Kenneth's approach to open source. This philosophy helped Requests maintain its elegant simplicity despite thousands of feature requests, proving that restraint can be more valuable than addition. +Every feature added is a feature that must be maintained forever. Every configuration option doubles the testing surface. Every abstraction adds cognitive overhead. Sometimes the kindest thing you can do for your users is to say no to their requests, preserving the simplicity that drew them to your project in the first place. ## Conclusion -- **Open Source Philosophy:** - - Open source should make the world a better place without adding unnecessary complexity. - - Focus on simplicity, sustainability, and maintaining a clear vision to ensure long-term success in open source projects. +Open source should make the world a better place without adding unnecessary complexity. Success comes from focusing on simplicity, sustainability, and maintaining a clear vision. The goal isn't to accept every contribution or implement every feature request - it's to create something valuable that can be maintained and understood over time. --- -*These principles of ethical open source development evolved into deeper understanding of [programming as spiritual practice](/essays/2025-08-26-programming_as_spiritual_practice), treating code creation as conscious service to human flourishing rather than mere technical achievement.* +*These principles of ethical open source development evolved into deeper understanding of [programming as spiritual practice](/essays/2025-08-26-programming_as_spiritual_practice), treating code creation as conscious service to human flourishing rather than mere technical achievement.* \ No newline at end of file diff --git a/data/talks/heroku-101.md b/data/talks/heroku-101.md index 6ab5e2e..3357703 100644 --- a/data/talks/heroku-101.md +++ b/data/talks/heroku-101.md @@ -1,4 +1,5 @@ # Heroku 101 +*2012* diff --git a/data/talks/python-2-vs-python-3.md b/data/talks/python-2-vs-python-3.md index 677b4a6..7156598 100644 --- a/data/talks/python-2-vs-python-3.md +++ b/data/talks/python-2-vs-python-3.md @@ -1,4 +1,5 @@ # Python 2 vs Python 3: A Sacred Love Story +*2015* diff --git a/data/talks/python-for-humans.md b/data/talks/python-for-humans.md index f8ff42c..68d5569 100644 --- a/data/talks/python-for-humans.md +++ b/data/talks/python-for-humans.md @@ -1,4 +1,5 @@ # Python for Humans +*2012* diff --git a/data/talks/requests-stdlib.md b/data/talks/requests-stdlib.md index f0be52a..87e8dcf 100644 --- a/data/talks/requests-stdlib.md +++ b/data/talks/requests-stdlib.md @@ -1,4 +1,5 @@ # Python, Requests, & The Standard Library +*2013* diff --git a/data/talks/responder.md b/data/talks/responder.md index 137ae97..5d94708 100644 --- a/data/talks/responder.md +++ b/data/talks/responder.md @@ -1,4 +1,5 @@ # Responder: a Familar HTTP Service Framework +*2018* diff --git a/engine.py b/engine.py index 48f7110..abdd620 100644 --- a/engine.py +++ b/engine.py @@ -62,6 +62,23 @@ def get_directory_structure(path): else: url_path = '/' + str(item.relative_to(DATA_DIR)) + # Extract date from markdown files + file_date = None + if item.is_file() and item.suffix == '.md': + try: + with open(item, 'r', encoding='utf-8') as f: + # Read first few lines to find date + for i, line in enumerate(f): + if i > 10: # Only check first 10 lines + break + # Look for date patterns like *January 2009* or *2014* + date_match = re.match(r'^\*([A-Za-z]+ \d{4}|\d{4})\*\s*$', line.strip()) + if date_match: + file_date = date_match.group(1) + break + except: + pass + item_info = { 'name': item.name, 'display_name': display_name, @@ -73,6 +90,7 @@ def get_directory_structure(path): 'size': item.stat().st_size if item.is_file() else None, 'created': datetime.fromtimestamp(item.stat().st_ctime), 'modified': datetime.fromtimestamp(item.stat().st_mtime), + 'file_date': file_date, # Date extracted from file content 'file_type': item.suffix.lower() if item.is_file() else 'directory', 'static_path': f"/static/data/{item.relative_to(DATA_DIR)}" if not item.is_dir() else None } diff --git a/templates/directory.html b/templates/directory.html index f0fc45b..4386cc0 100644 --- a/templates/directory.html +++ b/templates/directory.html @@ -204,8 +204,8 @@ {{ item.display_name }}{% if item.is_dir %}/{% endif %} - {% if not item.is_dir %} - {{ item.modified.strftime('%Y-%m-%d') }} + {% if not item.is_dir and item.file_date %} + {{ item.file_date }} {% endif %} {% endif %} @@ -223,8 +223,8 @@ {{ item.display_name }}{% if item.is_dir %}/{% endif %} - {% if not item.is_dir %} - {{ item.modified.strftime('%Y-%m-%d') }} + {% if not item.is_dir and item.file_date %} + {{ item.file_date }} {% endif %} {% endfor %}