├── .github ├── .gitignore └── workflows │ ├── hello.yaml │ ├── validate.yaml │ ├── knit.yaml │ └── generate_readme.yml ├── .gitignore ├── img ├── pyladies_blr_logo.jpeg ├── fallback_images │ ├── pyladies_bot.png │ └── pyladies_small.png └── icons │ ├── x.svg │ ├── youtube.svg │ ├── bluesky.svg │ ├── github.svg │ ├── mastodon.svg │ ├── instagram.svg │ └── safari.svg ├── requirements.txt ├── blogs ├── aplz.github.io.json ├── tuanacelik-medium.json ├── jtemporal.json ├── ines.io.json ├── karavdina.com.json ├── valerybriz.dev.to.json ├── cosimameyer.com.json ├── laceyhenschel.com.json ├── stefaniemolin.com.json ├── dehhmesquita.medium.json ├── sabrinebendimerad-medium.json ├── isabelizimm.github.io.json ├── pamelafox.org.json ├── roguelynn.com.json ├── mariatta.ca.json ├── christyheaton.github.io.json ├── jessica0greene-medium.json ├── jhylin.github.io.json ├── bilgeycl.medium.json ├── marenwestermann.github.io.json ├── pyladies-london.json ├── pyladies-blr.json ├── corriebartelheimer.com.json ├── szeitlin.github.io.json ├── blog.victoriaslocum.com.json ├── whykay-dev.to.json ├── cheuk.dev.json ├── pyladies-hamburg.json ├── ellenschwartau.com.json ├── pyladies-soflo.json ├── pyladies-berlin.json ├── emilyriederer.com.json └── karbartolome-blog.netlify.app.json ├── scripts ├── validate_jsons.R ├── .entry_schema.json └── generate_readme.py ├── LICENSE.md ├── LICENSE ├── CONTRIBUTING.md └── README.md /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | .DS_Store 6 | tmp 7 | -------------------------------------------------------------------------------- /img/pyladies_blr_logo.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosimameyer/awesome-pyladies-blogs/HEAD/img/pyladies_blr_logo.jpeg -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | certifi==2025.6.15 2 | charset-normalizer==3.4.2 3 | idna==3.10 4 | requests==2.32.4 5 | urllib3==2.5.0 6 | -------------------------------------------------------------------------------- /img/fallback_images/pyladies_bot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosimameyer/awesome-pyladies-blogs/HEAD/img/fallback_images/pyladies_bot.png -------------------------------------------------------------------------------- /img/fallback_images/pyladies_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosimameyer/awesome-pyladies-blogs/HEAD/img/fallback_images/pyladies_small.png -------------------------------------------------------------------------------- /img/icons/x.svg: -------------------------------------------------------------------------------- 1 | X -------------------------------------------------------------------------------- /img/icons/youtube.svg: -------------------------------------------------------------------------------- 1 | YouTube -------------------------------------------------------------------------------- /blogs/aplz.github.io.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Anja Pilz", 3 | "type": "blog", 4 | "url": "https://aplz.github.io", 5 | "photo_url": "https://raw.githubusercontent.com/aplz/aplz.github.io/master/images/avatar_me.jpg", 6 | "language": "en", 7 | "authors": [ 8 | { 9 | "name": "Anja Pilz", 10 | "social_media": [{ 11 | "github": "aplz", 12 | "website": "https://aplz.github.io", 13 | "linkedin": "anja-pilz" 14 | }] 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /.github/workflows/hello.yaml: -------------------------------------------------------------------------------- 1 | name: Auto message for Issues 2 | on: [issues] 3 | jobs: 4 | build: 5 | name: Hello new contributor 6 | runs-on: ubuntu-latest 7 | steps: 8 | - uses: actions/first-interaction@v1 9 | with: 10 | repo-token: ${{ secrets.SECRET_WRITE }} 11 | issue-message: "Hey, thank you for opening your first Issue ! 🙂 We will get to this as soon as we can!" 12 | pr-message: "Hey, thank you for opening your Pull Request ! 🙂 We will get to this as soon as we can!" 13 | -------------------------------------------------------------------------------- /blogs/tuanacelik-medium.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Tuana Celik", 3 | "type": "blog", 4 | "url": "https://medium.com/@tuanacelik", 5 | "photo_url": "https://haystack.deepset.ai/images/authors/tuana-celik.jpg", 6 | "rss_feed": "https://medium.com/feed/@tuanacelik", 7 | "language": "en", 8 | "authors": [ 9 | { 10 | "name": "Tuana Celik", 11 | "social_media": [{ 12 | "twitter": "tuanacelik", 13 | "mastodon": "@tuana@sigmoid.social", 14 | "github": "tuanacelik", 15 | "linkedin": "tuanacelik/" 16 | }] 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /blogs/jtemporal.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Jess Temporal", 3 | "type": "blog", 4 | "url": "https://jtemporal.com/en", 5 | "photo_url": "https://github.com/jtemporal.png", 6 | "language": "en", 7 | "authors": [ 8 | { 9 | "name": "Jess Temporal", 10 | "social_media": [{ 11 | "twitter": "jesstemporal", 12 | "mastodon": "@jesstemporal@mastodon.online", 13 | "website": "https://jtemporal.com", 14 | "github": "jtemporal", 15 | "linkedin": "jessicatemporal" 16 | }] 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /blogs/ines.io.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Ines Montani", 3 | "type": "blog", 4 | "url": "https://ines.io", 5 | "rss_feed": "https://ines.io/feed", 6 | "photo_url": "https://ines.io/static/31a698b834e1e4b6f7d15b9b306a9439/e9e8b/profile.jpg", 7 | "language": "en", 8 | "authors": [ 9 | { 10 | "name": "Ines Montani", 11 | "social_media": [ 12 | { 13 | "twitter": "@_inesmontani", 14 | "mastodon": "@ines@sigmoid.social", 15 | "github": "ines", 16 | "website": "https://ines.io", 17 | "linkedin": "inesmontani/" 18 | } 19 | ] 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /blogs/karavdina.com.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Anastasia's blog", 3 | "type": "blog", 4 | "url": "https://www.karavdina.com/blog", 5 | "photo_url": "https://static.wixstatic.com/media/160e52_7aba41375ff94da0a34b68dfbb95f603~mv2.jpg", 6 | "description": "ML/AI and building rewarding career in Data", 7 | "language": "en", 8 | "rss_feed": "https://www.karavdina.com/blog/blog-feed.xml", 9 | "authors": [ 10 | { 11 | "name": "Anastasia Karavdina", 12 | "social_media": [{ 13 | "website": "https://www.karavdina.com", 14 | "linkedin": "dr-anastasia-karavdina" 15 | }] 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /blogs/valerybriz.dev.to.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Valery C. Briz", 3 | "type": "blog", 4 | "url": "https://dev.to/valerybriz", 5 | "photo_url": "https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/213848/84c58823-8f3e-4848-8091-c04ac5c81d79.jpeg", 6 | "rss_feed": "https://dev.to/feed/valerybriz", 7 | "language": "en", 8 | "authors": [ 9 | { 10 | "name": "Valery C. Briz", 11 | "social_media": [{ 12 | "twitter": "valerybriz", 13 | "mastodon": "@valerybriz@fosstodon.org", 14 | "github": "valerybriz", 15 | "linkedin": "valerybriz/" 16 | }] 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /blogs/cosimameyer.com.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Cosima Meyer", 3 | "type": "blog", 4 | "url": "https://cosimameyer.com/", 5 | "photo_url": "https://cosimameyer.com/images/hero/avatar.jpg", 6 | "rss_feed": "https://cosimameyer.com/category/python-post/index.xml", 7 | "language": "en", 8 | "authors": [ 9 | { 10 | "name": "Cosima Meyer", 11 | "social_media": [{ 12 | "mastodon": "@cosima_meyer@mas.to", 13 | "github": "cosimameyer", 14 | "website": "https://cosimameyer.com/", 15 | "linkedin": "cosimameyer/", 16 | "bluesky": "@cosima.bsky.social" 17 | }] 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /blogs/laceyhenschel.com.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Lacey Henschel's blog", 3 | "type": "blog", 4 | "url": "https://www.laceyhenschel.com/blog", 5 | "photo_url": "https://avatars.githubusercontent.com/u/2286304?v=4", 6 | "rss_feed": "http://feeds.feedburner.com/LaceyWilliamsHenschel", 7 | "description": "Occasional posts about Python and Django", 8 | "language": "en", 9 | "authors": [ 10 | { 11 | "name": "Lacey Henschel", 12 | "social_media": [{ 13 | "github": "williln", 14 | "website": "https://www.laceyhenschel.com", 15 | "linkedin": "laceynwilliams" 16 | }] 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /blogs/stefaniemolin.com.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Stefanie Molin", 3 | "type": "blog", 4 | "url": "https://stefaniemolin.com/articles", 5 | "photo_url": "https://stefaniemolin.com/assets/portrait.jpeg", 6 | "rss_feed": "https://stefaniemolin.com/feeds/articles-rss.xml", 7 | "language": "en", 8 | "authors": [ 9 | { 10 | "name": "Stefanie Molin", 11 | "social_media": [{ 12 | "twitter": "StefanieMolin", 13 | "github": "stefmolin", 14 | "orcid": "0009-0001-3359-3346", 15 | "linkedin": "stefanie-molin", 16 | "website": "https://stefaniemolin.com" 17 | }] 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /blogs/dehhmesquita.medium.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Déborah Mesquita", 3 | "type": "blog", 4 | "url": "https://medium.com/@dehhmesquita", 5 | "photo_url": "https://avatars.githubusercontent.com/u/2621484?v=4", 6 | "description": "Blog posts on data science and MLOps", 7 | "rss_feed": "https://medium.com/feed/@dehhmesquita", 8 | "language": "en", 9 | "authors": [ 10 | { 11 | "name": "Déborah Mesquita", 12 | "social_media": [{ 13 | "github": "dmesquita", 14 | "linkedin": "deborahmesquita", 15 | "website": "https://deborahmesquita.com/" 16 | }] 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /img/icons/bluesky.svg: -------------------------------------------------------------------------------- 1 | Bluesky -------------------------------------------------------------------------------- /blogs/sabrinebendimerad-medium.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Sabrine Bendimerad", 3 | "type": "blog", 4 | "url": "https://medium.com/@sabrine.bendimerad1", 5 | "photo_url": "https://i.ibb.co/bNrv9db/1646312123517.jpg", 6 | "description": "Blog posts on Machine Learning, Python and statistics", 7 | "language": "en", 8 | "rss_feed": "https://medium.com/feed/@sabrine.bendimerad1", 9 | "authors": [ 10 | { 11 | "name": "Sabrine Bendimerad", 12 | "social_media": [{ 13 | "twitter": "BENDIMERADSabr1", 14 | "github": "sbendimerad", 15 | "linkedin": "sabrine-bendimerad-43570b107/" 16 | }] 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /blogs/isabelizimm.github.io.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Isabel Zimmerman", 3 | "type": "blog", 4 | "url": "https://isabelizimm.github.io/", 5 | "rss_feed": "https://isabelizimm.github.io/blog-python.xml", 6 | "photo_url": "https://avatars.githubusercontent.com/u/54685329?v=4", 7 | "language": "en", 8 | "authors": [ 9 | { 10 | "name": "Isabel Zimmerman", 11 | "social_media": [{ 12 | "twitter": "@isabelizimm", 13 | "mastodon": "@isabelizimm@fosstodon.org", 14 | "github": "isabelizimm", 15 | "linkedin": "isabel-zimmerman", 16 | "bluesky": "@isabelizimm.bsky.social" 17 | }] 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /blogs/pamelafox.org.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Pamela Fox", 3 | "type": "blog", 4 | "url": "http://blog.pamelafox.org/", 5 | "photo_url": "https://developer.microsoft.com/en-us/advocates/media/profiles/pamela-fox.png", 6 | "rss_feed": "http://blog.pamelafox.org/feeds/posts/default/?q=label:python", 7 | "language": "en", 8 | "authors": [ 9 | { 10 | "name": "Pamela Fox", 11 | "social_media": [{ 12 | "twitter": "pamelafox", 13 | "mastodon": "@pamelafox@fosstodon.org", 14 | "github": "pamelafox", 15 | "website": "https://www.pamelafox.org/", 16 | "linkedin": "pamela-fox-5668b1b4/" 17 | }] 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /blogs/roguelynn.com.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Lynn Root", 3 | "type": "blog", 4 | "url": "https://roguelynn.com/words", 5 | "photo_url": "https://www.roguelynn.com/images/self_square.png", 6 | "rss_feed": "https://www.roguelynn.com/index.xml", 7 | "language": "en", 8 | "authors": [ 9 | { 10 | "name": "Lynn Root", 11 | "social_media": [{ 12 | "twitter": "roguelynn", 13 | "mastodon": "@roguelynn@mastodon.online", 14 | "github": "econchick", 15 | "website": "https://roguelynn.com", 16 | "linkedin": "lynnroot", 17 | "instagram": "roguelynn" 18 | }] 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /blogs/mariatta.ca.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Mariatta's Blog", 3 | "type": "blog", 4 | "url": "https://mariatta.ca", 5 | "photo_url": "https://github.com/mariatta.png", 6 | "description": "Mariatta's Website", 7 | "language": "en", 8 | "rss_feed": "https://mariatta.ca/index.xml", 9 | "authors": [ 10 | { 11 | "name": "Mariatta", 12 | "social_media": [{ 13 | "twitter": "mariatta", 14 | "mastodon": "@mariatta@fosstodon.org", 15 | "github": "mariatta", 16 | "linkedin": "mariatta", 17 | "instagram": "mariatta81", 18 | "youtube": "mariattaw/videos", 19 | "bluesky": "@mariatta.ca" 20 | }] 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /blogs/christyheaton.github.io.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Christy Heaton", 3 | "subtitle": "Python and maps", 4 | "type": "blog", 5 | "url": "https://christyheaton.github.io/", 6 | "photo_url": "https://christyheaton.github.io/assets/images/Christy.jpg", 7 | "rss_feed": "https://christyheaton.github.io/feed.xml", 8 | "language": "en", 9 | "authors": [ 10 | { 11 | "name": "Christy Heaton", 12 | "social_media": [{ 13 | "mastodon": "@christyheaton@mas.to", 14 | "github": "christyheaton", 15 | "instagram": "christy.heaton", 16 | "website": "https://christyheaton.github.io/", 17 | "linkedin": "christyheaton" 18 | }] 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /blogs/jessica0greene-medium.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Jessica Greene (PyLadies Berlin) Medium account", 3 | "type": "blog", 4 | "url": "https://medium.com/@jessica0greene", 5 | "photo_url": "https://miro.medium.com/v2/resize:fill:96:96/1*vp3dQ60qsoukSFGws6dNlg.jpeg", 6 | "rss_feed": "https://medium.com/feed/@jessica0greene", 7 | "language": "en", 8 | "authors": [ 9 | { 10 | "name": "Jessica Greene", 11 | "social_media": [{ 12 | "twitter": "sleepypioneer", 13 | "mastodon": "@sleepypioneer@mastodon.social", 14 | "github": "sleepypioneer", 15 | "website": "http://onlinegurl.co.uk", 16 | "linkedin": "jessica0greene/" 17 | }] 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /blogs/jhylin.github.io.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Data in life", 3 | "type": "blog", 4 | "url": "https://jhylin.github.io/Data_in_life_blog/", 5 | "rss_feed": "https://jhylin.github.io/Data_in_life_blog/index-python.xml", 6 | "photo_url": "https://jhylin.github.io/Data_in_life_blog/profile%20avatar.jpg", 7 | "description": "A blog using data science on pharmaceutical and healthcare data", 8 | "language": "en", 9 | "authors": [ 10 | { 11 | "name": "Jennifer HY Lin", 12 | "social_media": [{ 13 | "twitter": "@jenhylin", 14 | "mastodon": "@jhylin@fosstodon.org", 15 | "github": "jhylin", 16 | "bluesky": "@jhylin.bsky.social" 17 | }] 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /blogs/bilgeycl.medium.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Bilge Yucel", 3 | "type": "blog", 4 | "url": "https://medium.com/@bilgeycl", 5 | "photo_url": "https://miro.medium.com/v2/1*vq38WKmsK8tz_JXI5scXnw.jpeg", 6 | "description": "Blog posts on NLP and open source", 7 | "rss_feed": "https://medium.com/feed/@bilgeycl", 8 | "language": "en", 9 | "authors": [ 10 | { 11 | "name": "Bilge Yucel", 12 | "social_media": [{ 13 | "twitter": "bilgeycl", 14 | "mastodon": "@bilgeyucel@sigmoid.social", 15 | "github": "bilgeyucel", 16 | "linkedin": "bilge-yucel/", 17 | "website": "https://bilgeyucel.github.io/" 18 | }] 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /blogs/marenwestermann.github.io.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Maren's blog about science and technology", 3 | "type": "blog", 4 | "url": "https://marenwestermann.github.io", 5 | "photo_url": "https://avatars.githubusercontent.com/u/17019042?v=4", 6 | "description": "Short description of what you blog about", 7 | "language": "en", 8 | "rss_feed": "https://marenwestermann.github.io/feed.xml", 9 | "authors": [ 10 | { 11 | "name": "Maren Westermann", 12 | "social_media": [{ 13 | "twitter": "MarenWestermann", 14 | "mastodon": "@maren@fosstodon.org", 15 | "github": "marenwestermann", 16 | "linkedin": "dr-maren-westermann-0b8575144" 17 | }] 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /blogs/pyladies-london.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "PyLadies London", 3 | "type": "youtube", 4 | "url": "https://www.youtube.com/@pyladieslondon2675", 5 | "photo_url": "https://pbs.twimg.com/profile_images/1092801659120562182/uBJeapSU_400x400.jpg", 6 | "language": "en", 7 | "rss_feed_youtube": "https://www.youtube.com/feeds/videos.xml?channel_id=UCyyvi0HywaHZHafPUdQB38g", 8 | "authors": [ 9 | { 10 | "name": "PyLadies London", 11 | "social_media": [{ 12 | "twitter": "PyLadiesLondon", 13 | "youtube": "pyladieslondon2675", 14 | "website": "https://pyladies.com/locations/london/", 15 | "linkedin": "pyladies-london", 16 | "meetup": "pyladieslondon" 17 | }] 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /scripts/validate_jsons.R: -------------------------------------------------------------------------------- 1 | validate_jsons <- function(files, schema){ 2 | validate <- jsonvalidate::json_validator( 3 | schema) 4 | k <- sapply(files, validate, 5 | verbose = TRUE, 6 | error = TRUE, 7 | greedy = TRUE) 8 | } 9 | 10 | files <- list.files( 11 | path = here::here("blogs"), 12 | full.names = TRUE 13 | ) 14 | ext <- grep("json$", files, invert = TRUE) 15 | if(length(ext) > 0) 16 | stop("File has wrong extention. Please rename to end with 'json'\n", 17 | paste0(basename(files[grep("json$", files, invert = TRUE)]), collapse ="\n"), 18 | call. = FALSE) 19 | 20 | # Validate blog json 21 | validate_jsons( 22 | files, 23 | here::here("scripts/.entry_schema.json") 24 | ) 25 | 26 | 27 | -------------------------------------------------------------------------------- /blogs/pyladies-blr.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "PyLadies Bengaluru", 3 | "type": "youtube", 4 | "url": "https://www.youtube.com/@pyladiesbengaluru7366", 5 | "photo_url": "https://raw.githubusercontent.com/cosimameyer/awesome-pyladies-blogs/main/img/pyladies_blr_logo.jpeg", 6 | "rss_feed_youtube": "https://www.youtube.com/feeds/videos.xml?channel_id=UCRF8Cf4Ppe4OFed4zbgujjg", 7 | "language": "en", 8 | "authors": [ 9 | { 10 | "name": "PyLadies Bengaluru", 11 | "social_media": [{ 12 | "twitter": "pyladiesblr", 13 | "youtube": "pyladiesbengaluru7366", 14 | "website": "https://pyladies.com/locations/blr/", 15 | "meetup": "PyLadies-Bangalore-Chapter" 16 | }] 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /blogs/corriebartelheimer.com.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Samples of Thoughts", 3 | "type": "blog", 4 | "url": "https://www.samples-of-thoughts.com", 5 | "photo_url": "https://www.samples-of-thoughts.com/about/_index_files/circle-cropped.png", 6 | "description": "about data, statistics and everything in between", 7 | "language": "en", 8 | "rss_feed": "https://www.samples-of-thoughts.com/tags/python/index.xml", 9 | "authors": [ 10 | { 11 | "name": "Corrie Bartelheimer", 12 | "social_media": [{ 13 | "twitter": "corrieaar", 14 | "mastodon": "@corrieaar@ohai.social", 15 | "github": "corriebar", 16 | "website": "corriebartelheimer.com", 17 | "linkedin": "corrie-bartelheimer/" 18 | }] 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /blogs/szeitlin.github.io.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Always Be Getting Data (ABGD)", 3 | "type": "blog", 4 | "url": "https://szeitlin.github.io", 5 | "photo_url": "https://girlgeek.io/wp-content/uploads/2020/09/sentry-girl-geek-samantha-g-zeitlin.png", 6 | "description": "Blog posts on python, management, AWS, spark, and other things I'm learning the hard way", 7 | "language": "en", 8 | "rss_feed": "https://szeitlin.github.io/index.xml", 9 | "authors": [ 10 | { 11 | "name": "Samantha Zeitlin", 12 | "social_media": 13 | [{ 14 | "twitter": "SamanthaZeitlin", 15 | "github": "szeitlin", 16 | "youtube": "@samanthazeitlin403", 17 | "researchgate": "Samantha-Zeitlin", 18 | "linkedin": "sgzeitlin" 19 | }] 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /blogs/blog.victoriaslocum.com.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Victoria Slocum's blog", 3 | "subtitle": "Learnings and doings", 4 | "type": "blog", 5 | "url": "https://blog.victoriaslocum.com", 6 | "photo_url": "https://i.postimg.cc/Yqm5QfGJ/headshot-2.png", 7 | "description": "Projects, tutorials, and cool things I learn in the AI / Machine Learning space.", 8 | "language": "en", 9 | "authors": [ 10 | { 11 | "name": "Victoria Slocum", 12 | "social_media": [{ 13 | "twitter": "victorialslocum", 14 | "mastodon": "@victorialslocum@sigmoid.social", 15 | "github": "victorialslocum", 16 | "website": "https://victoriaslocum.com", 17 | "linkedin": "victorialslocum", 18 | "bluesky": "@victorialslocum.bsky.social" 19 | }] 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /img/icons/github.svg: -------------------------------------------------------------------------------- 1 | GitHub -------------------------------------------------------------------------------- /blogs/whykay-dev.to.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "whykay @ dev.to", 3 | "type": "blog", 4 | "url": "https://dev.to/whykay", 5 | "photo_url": "https://media.licdn.com/dms/image/D4E03AQG3lcPFRvoCLA/profile-displayphoto-shrink_800_800/0/1671633150179?e=2147483647&v=beta&t=PIBSiQwOS4UE9OQ31JLrmWUoMEk8a4xSo3cUmiPaxg8", 6 | "language": "en", 7 | "rss_feed": "https://dev.to/feed/whykay", 8 | "authors": [ 9 | { 10 | "name": "Vicky Twomey-Lee", 11 | "social_media": [{ 12 | "twitter": "whykay", 13 | "mastodon": "@whykay@mastodon.ie", 14 | "github": "whykay", 15 | "instagram": "theycallmejanie", 16 | "website": "https://beacons.ai/whykay", 17 | "linkedin": "vickyleeire", 18 | "bluesky": "@whykay.bsky.social" 19 | }] 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /blogs/cheuk.dev.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Cheuk Ting Ho", 3 | "subtitle": "Python community and my 2 cents.", 4 | "type": "blog", 5 | "url": "https://cheuk.dev", 6 | "photo_url": "https://cheuk.dev/img/commission_main_hu_1109777618305171.jpeg", 7 | "description": "Python community and my 2 cents. Opnions are mine", 8 | "language": "en", 9 | "rss_feed": "https://cheuk.dev/index.xml", 10 | "authors": [ 11 | { 12 | "name": "Cheuk Ting Ho", 13 | "social_media": [{ 14 | "twitter": "@cheukting_ho", 15 | "mastodon": "@cheukting_ho@fosstodon.org", 16 | "github": "Cheukting", 17 | "youtube": "%40cheuktingho", 18 | "website": "https://cheuk.dev", 19 | "linkedin": "cheukting-ho", 20 | "bluesky": "@cheukting.bsky.social" 21 | }] 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /blogs/pyladies-hamburg.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "PyLadies Hamburg", 3 | "type": "youtube", 4 | "url": "https://www.youtube.com/@HamburgPyLadies", 5 | "photo_url": "https://yt3.googleusercontent.com/Fh10PC7hmhI-a7vvzqClrGbVWXFm2GoXSOPfCVvFcw8uOSTnY9-yVfOOM3Jk32aagC7i0df3uA=s160-c-k-c0x00ffffff-no-rj", 6 | "language": "en", 7 | "rss_feed_youtube": "https://www.youtube.com/feeds/videos.xml?channel_id=UC3RXyjipkLNG8HhVAzpZBCg", 8 | "authors": [ 9 | { 10 | "name": "PyLadies Hamburg", 11 | "social_media": [ 12 | { 13 | "youtube": "https://www.youtube.com/@PyLadiesHamburg", 14 | "linkedin": "pyladies-hamburg", 15 | "meetup": "PyLadies-Hamburg" 16 | } 17 | ] 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /blogs/ellenschwartau.com.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Ellens Blog", 3 | "subtitle": "Stuff she is interested in, mostly related to her profession as Software Engineer", 4 | "type": "blog", 5 | "url": "https://ellenschwartau.com", 6 | "rss_feed": "http://ellenschwartau.com/feed/", 7 | "photo_url": "https://ellenschwartau.files.wordpress.com/2021/09/3dcb1d37-6c2d-41ea-88c1-5dd8f31765e5.jpg?w=540", 8 | "description": "Short description of what you blog about", 9 | "language": "en, de", 10 | "authors": [ 11 | { 12 | "name": "Ellen Schwartau", 13 | "social_media": [{ 14 | "twitter": "ellenschwartau", 15 | "github": "ellenschwartau", 16 | "instagram": "ellllllllln", 17 | "website": "www.ellenschwartau.com", 18 | "linkedin": "ellen-schwartau-b53aa5133/" 19 | }] 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /blogs/pyladies-soflo.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "PyLadies SoFlo YouTube channel", 3 | "type": "youtube", 4 | "url": "https://www.youtube.com/channel/UCUPLdokEtQlQmbaW9UkJEVQ", 5 | "photo_url": "https://yt3.googleusercontent.com/d0Q0c1jMSCBrfIGhWgs25pBWmym2UPZO3ex5NiAK6yhwM71AUDfyyAmeoe4xh5-sGuHRz800pw=s176-c-k-c0x00ffffff-no-rj", 6 | "description": "PyLadies SoFlo YouTube channel. PyLadies SoFlo is a mentoring group with a focus on nurturing gender diversity in the South Florida Python community.", 7 | "language": "en", 8 | "rss_feed_youtube": "https://www.youtube.com/feeds/videos.xml?channel_id=UCUPLdokEtQlQmbaW9UkJEVQ", 9 | "authors": [ 10 | { 11 | "name": "PyLadies SoFlo", 12 | "social_media": [{ 13 | "twitter": "PyLadiesSoFlo", 14 | "github": "PyLadiesSoFlo", 15 | "linkedin": "pyladies-soflo", 16 | "meetup": "pyladies-soflo" 17 | }] 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /blogs/pyladies-berlin.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "PyLadies Berlin", 3 | "type": "youtube", 4 | "url": "https://www.youtube.com/@PyLadiesBerlin", 5 | "photo_url": "https://yt3.googleusercontent.com/ytc/AIdro_kXbyv32bPfyTn5CDr9e3yyqOXzUjNfumZKtpxeRNDHcw=s160-c-k-c0x00ffffff-no-rj", 6 | "language": "en", 7 | "rss_feed_youtube": "https://www.youtube.com/feeds/videos.xml?channel_id=UCVlzy-BMSYReFD0YnTzoh7w", 8 | "authors": [ 9 | { 10 | "name": "PyLadies Berlin", 11 | "social_media": [ 12 | { 13 | "twitter": "https://x.com/pyladiesber", 14 | "youtube": "https://www.youtube.com/@PyLadiesBerlin", 15 | "website": "https://berlin.pyladies.com/en/", 16 | "linkedin": "pyladies-berlin-32879a18a", 17 | "meetup": "PyLadies-Berlin" 18 | } 19 | ] 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /blogs/emilyriederer.com.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Emily Riederer", 3 | "type": "blog", 4 | "url": "https://emilyriederer.com", 5 | "photo_url": "https://avatars.githubusercontent.com/u/19798371", 6 | "description": "Thoughts on advancing the data analysis lifecycle -- from data quality and management, reproducible tooling, and statistical methods", 7 | "language": "en", 8 | "rss_feed": "https://www.emilyriederer.com/tags/python/index.xml", 9 | "authors": [ 10 | { 11 | "name": "Emily Riederer", 12 | "social_media": [{ 13 | "twitter": "emilyriederer", 14 | "mastodon": "@emilyriederer@mastodon.social", 15 | "github": "emilyriederer", 16 | "website": "emilyriederer.com", 17 | "linkedin": "emilyriederer/", 18 | "facebook": "emilyriederer", 19 | "orcid": "0000-0002-1788-7934", 20 | "bluesky": "@emilyriederer.bsky.social" 21 | }] 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /blogs/karbartolome-blog.netlify.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Karina Bartolome", 3 | "subtitle": "Personal blog", 4 | "type": "blog", 5 | "url": "https://karbartolome-blog.netlify.app", 6 | "rss_feed": "https://karbartolome-blog.netlify.app/categories/python/index.xml", 7 | "photo_url": "https://raw.githubusercontent.com/RLadies-BA/RLadies-BA/main/content/authors/kari/avatar.jpg", 8 | "description": "Data Science & Economics. Mostly in spanish, sometimes in english.", 9 | "language": "es", 10 | "authors": [ 11 | { 12 | "name": "Karina Bartolome", 13 | "social_media": [{ 14 | "twitter": "karbartolome", 15 | "mastodon": "@karbartolome@mastodon.social", 16 | "github": "karbartolome", 17 | "instagram": "karbartolome", 18 | "website": "https://karbartolome-blog.netlify.app", 19 | "linkedin": "karinabartolome", 20 | "meetup": "276190207" 21 | }] 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /img/icons/mastodon.svg: -------------------------------------------------------------------------------- 1 | Mastodon -------------------------------------------------------------------------------- /.github/workflows/validate.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | pull_request: 3 | paths: 4 | - 'blogs/**' 5 | 6 | name: Validate JSON 7 | 8 | jobs: 9 | validate: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout repo 13 | uses: actions/checkout@v2 14 | with: 15 | fetch-depth: 5 16 | - uses: r-lib/actions/setup-pandoc@v1 17 | - uses: r-lib/actions/setup-r@v2 18 | 19 | - name: Get changed files 20 | id: changed-files 21 | uses: tj-actions/changed-files@v46 22 | with: 23 | files: blogs/ 24 | 25 | - name: Cleanup json template comments 26 | run: | 27 | for f in ${{ steps.changed-files.outputs.all_changed_files }}; do 28 | echo Cleaning $f 29 | sed -i .bk 's.//required..g' $f 30 | rm ${f}.bk 31 | done 32 | - name: Install R dependencies 33 | run: | 34 | install.packages(c("jsonlite", "jsonvalidate", "rmarkdown", "here"), 35 | repos = "https://cloud.r-project.org/") 36 | shell: Rscript {0} 37 | 38 | - name: Validate jsons 39 | run: Rscript 'scripts/validate_jsons.R' 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /.github/workflows/knit.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | # pull_request: 6 | # types: 7 | # - closed 8 | jobs: 9 | if_merged: 10 | if: github.event.pull_request.merged == true 11 | runs-on: macOS-latest 12 | steps: 13 | - run: | 14 | echo The PR was merged 15 | - name: Install R dependencies 16 | run: | 17 | install.packages(c("jsonlite", "jsonvalidate", "rmarkdown", "reticulate", "here"), 18 | repos = "https://cloud.r-project.org/") 19 | shell: Rscript {0} 20 | 21 | - name: Install Python dependencies 22 | uses: py-actions/py-dependency-install@v4 23 | 24 | - name: Render readme files 25 | #if: github.event_name == 'push' 26 | run: rmarkdown::render("README.Rmd", output_format = "github_document") 27 | shell: Rscript {0} 28 | 29 | - name: Commit data 30 | #if: github.event_name == 'push' 31 | env: 32 | GITHUB_PAT: ${{ secrets.SECRET_WRITE }} 33 | run: | 34 | git config --local user.name "$GITHUB_ACTOR" 35 | git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com" 36 | git commit blogs/ -m 'Commit cleaned jsons' || echo "No changes to commit" 37 | git commit README.md -m 'Re-knit readme files' || echo "No changes to commit" 38 | git push origin || echo "Nothing to push" 39 | -------------------------------------------------------------------------------- /scripts/.entry_schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "type": "object", 4 | "properties": { 5 | "title": {"type": "string"}, 6 | "url": {"type": "string"}, 7 | "rss_feed": {"type": "string"}, 8 | "type": {"type": "string"}, 9 | "photo_url": {"type": "string"}, 10 | "description": {"type": "string"}, 11 | "language": {"type": "string"}, 12 | "authors": { 13 | "type": "array", 14 | "items": [ 15 | { 16 | "type": "object", 17 | "properties": { 18 | "name": {"type": "string"}, 19 | "social_media": { 20 | "type": "array", 21 | "items": [ 22 | { 23 | "type": "object", 24 | "properties": { 25 | "twitter": {"type": "string"}, 26 | "mastodon": {"type": "string"}, 27 | "linkedin": {"type": "string"}, 28 | "facebook": {"type": "string"}, 29 | "github": {"type": "string"}, 30 | "instagram": {"type": "string"}, 31 | "youtube": {"type": "string"}, 32 | "tiktok": {"type": "string"}, 33 | "periscope": {"type": "string"}, 34 | "researchgate": {"type": "string"}, 35 | "website": {"type": "string"}, 36 | "orcid": {"type": "string"}, 37 | "meetup": {"type": "string"} 38 | } 39 | } 40 | ] 41 | } 42 | }, 43 | "required": [ 44 | "name" 45 | ] 46 | } 47 | ] 48 | } 49 | }, 50 | "required": [ 51 | "title", 52 | "url", 53 | "type", 54 | "photo_url", 55 | "authors", 56 | "language" 57 | ] 58 | } 59 | -------------------------------------------------------------------------------- /img/icons/instagram.svg: -------------------------------------------------------------------------------- 1 | Instagram -------------------------------------------------------------------------------- /.github/workflows/generate_readme.yml: -------------------------------------------------------------------------------- 1 | name: Generate README and create PR 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | concurrency: 12 | group: ${{ github.workflow }}-${{ github.ref }} 13 | cancel-in-progress: true 14 | 15 | jobs: 16 | update-readme: 17 | runs-on: ubuntu-latest 18 | 19 | steps: 20 | - name: Checkout repo 21 | uses: actions/checkout@v4 22 | 23 | - uses: actions/setup-python@v5 24 | with: 25 | python-version: '3.11' 26 | 27 | - name: Install dependencies 28 | run: | 29 | python -m pip install --upgrade pip 30 | pip install requests 31 | pip install -r requirements.txt || echo "No requirements.txt found" 32 | 33 | - name: Run README generator 34 | run: python scripts/generate_readme.py 35 | 36 | - name: Configure git 37 | run: | 38 | git config user.name "github-actions" 39 | git config user.email "action@github.com" 40 | 41 | - name: Check for changes 42 | id: git-diff 43 | run: | 44 | git add README.md 45 | if git diff --cached --quiet; then 46 | echo "changed=false" >> $GITHUB_OUTPUT 47 | else 48 | echo "changed=true" >> $GITHUB_OUTPUT 49 | fi 50 | 51 | - name: Check for README changes in PR 52 | if: github.event_name == 'pull_request' 53 | run: | 54 | git add README.md 55 | if git diff --cached --quiet; then 56 | echo "No README changes detected during PR try run." 57 | else 58 | echo "README would be updated by this PR." 59 | fi 60 | 61 | - name: Push to temp branch and create PR 62 | if: github.event_name == 'push' && steps.git-diff.outputs.changed == 'true' 63 | env: 64 | GITHUB_PAT: ${{ secrets.ACTIONS_PAT }} 65 | run: | 66 | BRANCH_NAME="update/readme-${GITHUB_RUN_NUMBER}" 67 | 68 | git checkout -b $BRANCH_NAME 69 | git commit -m "chore: auto-update README" 70 | git remote set-url origin https://x-access-token:${GITHUB_PAT}@github.com/${{ github.repository }}.git 71 | git push origin $BRANCH_NAME 72 | 73 | # Create pull request JSON safely 74 | cat < pr_payload.json 75 | { 76 | "title": "chore: auto-update README", 77 | "head": "$BRANCH_NAME", 78 | "base": "main", 79 | "body": "Automated README update via workflow." 80 | } 81 | EOF 82 | 83 | # Call GitHub API to open the PR 84 | curl -s -X POST \ 85 | -H "Authorization: token ${GITHUB_PAT}" \ 86 | -H "Accept: application/vnd.github+json" \ 87 | https://api.github.com/repos/${{ github.repository }}/pulls \ 88 | -d @pr_payload.json 89 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | ## creative commons 2 | 3 | # CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER. 6 | 7 | ### Statement of Purpose 8 | 9 | The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work"). 10 | 11 | Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others. 12 | 13 | For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. 14 | 15 | 1. __Copyright and Related Rights.__ A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following: 16 | 17 | i. the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work; 18 | 19 | ii. moral rights retained by the original author(s) and/or performer(s); 20 | 21 | iii. publicity and privacy rights pertaining to a person's image or likeness depicted in a Work; 22 | 23 | iv. rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below; 24 | 25 | v. rights protecting the extraction, dissemination, use and reuse of data in a Work; 26 | 27 | vi. database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and 28 | 29 | vii. other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof. 30 | 31 | 2. __Waiver.__ To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose. 32 | 33 | 3. __Public License Fallback.__ Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose. 34 | 35 | 4. __Limitations and Disclaimers.__ 36 | 37 | a. No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document. 38 | 39 | b. Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law. 40 | 41 | c. Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work. 42 | 43 | d. Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work. 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /scripts/generate_readme.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | import random 4 | import requests 5 | from datetime import datetime, timezone 6 | from typing import Optional 7 | import urllib.parse 8 | 9 | fallback_images_dir = "img/fallback_images/" 10 | fallback_images = [f for f in os.listdir(fallback_images_dir) if f.lower().endswith(('.png', '.jpg', '.jpeg', '.gif'))] 11 | directory_path = "blogs/" 12 | 13 | def load_svg_inline_from_url(icon_url, color="black", size=20): 14 | try: 15 | response = requests.get(icon_url) 16 | response.raise_for_status() 17 | svg_content = response.text 18 | 19 | svg_content = svg_content.replace('{label} ' 50 | else: 51 | if platform == "linkedin": 52 | socials += ( 53 | f'' 54 | ) 55 | else: 56 | icon_url = add_platform_icon(platform, base_icon_url, url) 57 | if not icon_url: 58 | continue 59 | socials += ( 60 | f'' 61 | f'{icon_url}' 62 | f' ' 63 | ) 64 | 65 | return socials 66 | 67 | 68 | def add_platform_icon(platform: str, base_icon_url: str, url: Optional[str]) -> Optional[str]: 69 | """ 70 | Construct the full icon URL for a given platform if a URL is provided. 71 | 72 | Args: 73 | platform: Name of the platform (e.g., "twitter", "website"). 74 | base_icon_url: Base URL where icons are hosted. 75 | url: The URL to the user profile or site. If None or empty, returns None. 76 | 77 | Returns: 78 | A full URL to the platform icon, or None if no URL provided. 79 | """ 80 | if platform == "website": 81 | platform = "safari" 82 | elif platform == "twitter": 83 | platform = "x" 84 | 85 | if not url: 86 | return None 87 | 88 | icon_url = f"{base_icon_url}{platform}.svg" 89 | 90 | svg_icon_html = load_svg_inline_from_url(icon_url, color="#929dad", size=15) 91 | 92 | return svg_icon_html 93 | 94 | def build_social_url(platform, handle): 95 | if not handle: 96 | return None 97 | 98 | handle = handle.strip() 99 | 100 | # Decode URL-encoded characters like %40 → @ 101 | handle = urllib.parse.unquote(handle) 102 | 103 | # Remove leading @ for most platforms except Mastodon and Bluesky (which need them) 104 | if platform not in ["mastodon", "bluesky"]: 105 | handle = handle.lstrip("@") 106 | 107 | if platform == "twitter": 108 | if handle.startswith("http"): 109 | return handle 110 | return f"https://twitter.com/{handle}" 111 | 112 | elif platform == "mastodon": 113 | # Mastodon handle is @user@domain 114 | if handle.startswith("http"): 115 | return handle 116 | if "@" in handle[1:]: 117 | parts = handle.lstrip("@").split("@") 118 | if len(parts) == 2: 119 | user, domain = parts 120 | return f"https://{domain}/@{user}" 121 | return handle 122 | 123 | elif platform == "linkedin": 124 | if handle.startswith("http"): 125 | return handle 126 | handle = handle.rstrip("/") 127 | return f"https://www.linkedin.com/in/{handle}" 128 | 129 | elif platform == "github": 130 | if handle.startswith("http"): 131 | return handle 132 | return f"https://github.com/{handle}" 133 | 134 | elif platform == "youtube": 135 | # YouTube handles can be channel IDs or usernames, often URL encoded 136 | if handle.startswith("http"): 137 | return handle 138 | # If it starts with '@', it's a YouTube handle, e.g. @username → https://www.youtube.com/@username 139 | if handle.startswith("@"): 140 | return f"https://www.youtube.com/{handle}" 141 | else: 142 | return f"https://www.youtube.com/user/{handle}" 143 | 144 | elif platform == "website": 145 | if handle.startswith("http"): 146 | return handle 147 | else: 148 | return "http://" + handle 149 | 150 | elif platform == "bluesky": 151 | # Bluesky handles like @user.bsky.social → https://bsky.app/profile/user.bsky.social 152 | if handle.startswith("http"): 153 | return handle 154 | handle = handle.lstrip("@") 155 | return f"https://bsky.app/profile/{handle}" 156 | 157 | elif platform == "instagram": 158 | if handle.startswith("http"): 159 | return handle 160 | handle = handle.lstrip("@") 161 | return f"https://instagram.com/{handle}" 162 | 163 | return None 164 | 165 | def image_exists(url): 166 | try: 167 | response = requests.head(url, allow_redirects=True, timeout=5) 168 | return response.status_code == 200 169 | except requests.RequestException: 170 | return False 171 | 172 | # Load JSON data 173 | json_data = [] 174 | for filename in os.listdir(directory_path): 175 | if filename.endswith(".json"): 176 | with open(os.path.join(directory_path, filename), "r") as f: 177 | data = json.load(f) 178 | json_data.append(data) 179 | 180 | json_data.sort(key=lambda x: x['authors'][0]['name']) 181 | 182 | # Build contributors grid table 183 | header = "| | | |" 184 | first_row = "|:-------------------------:|:-------------------------:|:-------------------------:|" 185 | grid_entries = "" 186 | count = 0 187 | 188 | for entry in json_data: 189 | count += 1 190 | name = entry['authors'][0]['name'] 191 | photo_url = entry.get('photo_url') 192 | if not image_exists(photo_url): 193 | fallback_image = random.choice(fallback_images) 194 | photo_url = f"https://github.com/cosimameyer/awesome-pyladies-blogs/raw/main/{fallback_images_dir}{fallback_image}" 195 | blog_url = entry['url'] 196 | 197 | social_dict = entry['authors'][0].get('social_media', [{}])[0] 198 | social_icons = build_social_icons(social_dict) 199 | 200 | grid_entry = f'Image of {name}
{name}
{social_icons}|' 201 | if count % 3 == 0: 202 | grid_entry += '\n|' 203 | grid_entries += grid_entry 204 | 205 | 206 | # Build blog list and YouTube list 207 | blogs = [] 208 | youtube = [] 209 | 210 | for entry in json_data: 211 | entry_type = entry.get("type", "") 212 | title = entry["title"] 213 | url = entry["url"] 214 | authors = ", ".join([a["name"] for a in entry["authors"]]) 215 | line = f"- [{title}]({url}) by {authors}" 216 | if entry_type == "blog": 217 | blogs.append(line) 218 | elif entry_type == "youtube": 219 | youtube.append(line) 220 | 221 | if count % 3 != 0: 222 | remaining = 3 - (count % 3) 223 | grid_entries += "| " * remaining + "\n|" 224 | 225 | full_table = f"{header}\n{first_row}\n|{grid_entries}" 226 | 227 | # Combine everything into README.md content 228 | readme_content = f""" 229 | # Awesome PyLadies' Repository 230 | 231 | 232 | 233 | [![Awesome](https://awesome.re/badge.svg)](https://awesome.re) 234 | 235 | ## What Is This Repository About? 236 | 237 | It provides a curated list of awesome content by PyLadies and collects information to further promote content by [PyLadies on Mastodon](https://botsin.space/@pyladies_bot) 🤖 238 | 239 | To contribute, please see [contributing](CONTRIBUTING.md) ✨ 240 | 241 | ## List of Contributors as Tiles 242 | 243 | {full_table} 244 | 245 | ## List of Content 246 | 247 | ### Blogs 248 | {os.linesep.join(blogs)} 249 | 250 | ### YouTube Channels 251 | {os.linesep.join(youtube)} 252 | 253 | --- 254 | 255 | _Last updated on {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M UTC')}_ 256 | 257 | ## License 258 | 259 | [![CC0](https://upload.wikimedia.org/wikipedia/commons/6/69/CC0_button.svg)](https://creativecommons.org/publicdomain/zero/1.0/) 260 | """ 261 | 262 | with open("README.md", "w", encoding="utf-8") as f: 263 | f.write(readme_content) 264 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # About 2 | 3 | This repository relies heavily on the [Awesome R-Ladies blogs repository](https://github.com/rladies/awesome-rladies-blogs), to whom all credit goes. I can only repeat their words and their excellent description of how to submit a new entry below: 4 | 5 | It has a similar goal and collects PyLadies blogs. This includes those who identify as a minority gender (including but not limited to cis/trans women, trans men, non-binary, genderqueer, & agender). It would be great to have contributions to this list! If you identify with PyLadies and have a blog, please add yourself. 6 | 7 | With your submission, you agree that these entries will be used for the [PyLadies' Mastodon bot](https://botsin.space/@pyladies_bot), which will post (new) PyLadies' blog entries to promote the work of PyLadies around the world. 8 | 9 | # Contributing Checklist 10 | 11 | - [ ] The entry will be added to the [blogs/](blogs/) folder. 12 | - [ ] The filename of the entry ends with `.json'. 13 | - [ ] The json contains at least 14 | - [ ] title (blog title) 15 | - [ ] type ("blog" or "youtube") 16 | - [ ] url (blog URL) 17 | - [ ] rss_feed (if you wish to have your blog posts being promoted by the Mastodon bot; the RSS feed should be for Python-related posts) 18 | - [ ] rss_feed_youtube (if you wish to have your YouTube channel being promoted by the Mastodon bot; the RSS feed should be for Python-related videos) 19 | - [ ] photo_url (logo or profile) 20 | - [ ] language (one of the [ISO 639-1 language codes](https://www.w3schools.com/tags/ref_language_codes.asp)) 21 | - [ ] authors (list of authors) 22 | 23 | # Contribution Details 24 | 25 | All blogs are listed in the [blogs](blogs/) folder, where each blog is in its own json file. These files will be used to render a table on the upcoming redesigned R-Ladies website. Follow the instructions below to add to the list. If you have any problems, please create an issue so we can help you. 26 | 27 | Depending on how you are most comfortable, there are several ways to add new entries. 28 | 29 | ## Option 1: Not Too Familiar with JSON/GitHub? 30 | 31 | If you're not familiar with JSON, you can [open an issue](https://github.com/cosimameyer/awesome-pyladies-blogs/issues/new/choose) with your blog info and I'll create the JSON for you! 32 | 33 | ## Option 2: Create a New File 34 | 35 | Create a new file in the [blogs/](blogs/) folder by [using this link](https://github.com/cosimameyer/awesome-pyladies-blogs/new/main/?filename=blogs/your-blog-url.com.json&value=%7B%0A%20%20%22title%22%3A%20%22Your%20title%22%2C%20%2F%2Frequired%0A%20%20%22subtitle%22%3A%20%22subtitle%20or%20tagline%22%2C%20%2F%2Foptional%0A%20%20%22type%22%3A%20%22blog%22%2C%20%2F%2Frequired%0A%20%20%22url%22%3A%20%22https%3A%2F%2Fyour_blog.com%22%2C%20%2F%2Frequired%0A%20%20%22photo_url%22%3A%20%22https%3A%2F%2Fyour_blog.com%2Fyour_photo.png%22%2C%20%2F%2Frequired%0A%20%20%22description%22%3A%20%22Short%20description%20of%20what%20you%20blog%20about%22%2C%0A%20%20%22language%22%3A%20%22en%22%2C%20%2F%2Frequired%0A%20%20%22rss_feed%22%3A%20%22%5Burl%5D%2Ffile.xml%22%2C%20%2F%2Frequired%20if%20you%20want%20your%20feed%20to%20be%20promoted%20on%20Mastodon%0A%20%20%22rss_feed_youtube%22%3A%20%22%5Burl%5D%3Dchannel_or_playlist_id%22%2C%20%2F%2Frequired%20if%20you%20want%20your%20feed%20to%20be%20promoted%20on%20Mastodon%0A%20%20%22authors%22%3A%20%5B%20%2F%2Frequired%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%22name%22%3A%20%22Your%20Name%22%2C%20%2F%2Frequired%0A%20%20%20%20%20%20%22social_media%22%3A%20%5B%7B%0A%20%20%20%20%20%20%20%20%20%22twitter%22%3A%20%22username%22%2C%0A%20%20%20%20%20%20%20%20%20%22mastodon%22%3A%20%22%40username%40server.org%22%2C%0A%20%20%20%20%20%20%20%20%20%22github%22%3A%20%22username%22%2C%0A%20%20%20%20%20%20%20%20%20%22instagram%22%3A%20%22username%22%2C%0A%20%20%20%20%20%20%20%20%20%22youtube%22%3A%20%22username%2Fend-url%22%2C%0A%20%20%20%20%20%20%20%20%20%22tiktok%22%3A%20%22username%22%2C%0A%20%20%20%20%20%20%20%20%20%22periscope%22%3A%20%22username%22%2C%0A%20%20%20%20%20%20%20%20%20%22researchgate%22%3A%20%22username%22%2C%0A%20%20%20%20%20%20%20%20%20%22website%22%3A%20%22url%22%2C%0A%20%20%20%20%20%20%20%20%20%22linkedin%22%3A%20%22username%22%2C%0A%20%20%20%20%20%20%20%20%20%22facebook%22%3A%20%22username%22%2C%0A%20%20%20%20%20%20%20%20%20%22orcid%22%3A%20%22member%20number%22%2C%0A%20%20%20%20%20%20%20%20%20%22meetup%22%3A%20%22end-url%22%0A%20%20%20%20%20%20%7D%5D%0A%20%20%20%20%7D%0A%20%20%5D%0A%7D). 36 | 37 | This link will fork the repository to your user account, and initiate a new file with some template content in it. After filling the file, please [create a PR to the main branch](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). 38 | 39 | ### File Name 40 | 41 | The name of the file should be the site url (without `www` or `http(s)://` . This way we can ensure each file has a unique name and that duplication does not happen. 42 | 43 | ### File Content 44 | 45 | Using the link above will create a template for you to start with. 46 | Fill inn all the information that is relevant for your blog. 47 | There are several adaptations to an entry you can make that are not highlighted in every entry. 48 | Remove all mentions of `\\required`, these are just for making it clear which information you _must_ provide for the file to be valid. 49 | Any optional field you don't want to add, you may delete entirely. 50 | For instance, if you don't have a subtitle or tagline for your blog, remove the entire line of `"subtite": "subtitle or tagline"` rather than leaving it empty with `"subtite": ""` 51 | 52 | #### Photo 53 | 54 | The photo url you provide will be displayed as your blogs thumbnail. 55 | This may be a picture of you, or if you have a logo for your blog/website, it may be best to use this in stead. 56 | 57 | 58 | #### RSS Feed Website 59 | 60 | Please add a content-specific feed in `rss_feed`. Ideally, you have a specific RSS feed for Python-related posts. A title-based RSS feed is fine. 61 | 62 | Depending on how your website is set up, the implementation may differ. If you need more input on how to get your RSS, have a look [here](https://zapier.com/blog/how-to-find-rss-feed-url/). If you want to check how your RSS looks like, you can use [simple pie](https://simplepie.org/demo/). We collected a few of the most common approaches below: 63 | 64 |
Quarto 65 | - Change the code in `index.qmd` as (under listing, also described [here](https://quarto.org/docs/websites/website-blog.html#rss-feed)): 66 | 67 | ``` 68 | feed: 69 | categories: [Python] 70 | 71 | ``` 72 | 73 | - Note to new users that the category names will be the names of your category tags used in the blogs (not `posts`, which are the posts folder for Quarto blogs) 74 | - Then provide the RSS feed links as, `[url]/blog/index-r.xml` for R category posts (`[url]/blog/index.xml` will be the RSS feed link for main posts only) 75 | 76 |
77 | 78 |
Distill 79 | There is currently a [workaround](https://github.com/rladies/awesome-rladies-blogs/pull/54#issuecomment-1501263818) for adding RSS feeds in distill that works as follows: 80 | 81 | - In distill, there is a categories folder generated when a post is rendered which gets deleted when the blog is rendered 82 | - Store the folder and add it later because we need a categories folder, containing each specified category with an `index.xml` for each category 83 |
84 | 85 |
Hugo 86 | 87 | ###### Hugo Academic 88 | 89 | - Apparently the RSS feed is enabled by default and you can access it by using the field `category` in the YAML of your posts 90 | - Further readings for [Hugo Academic](https://cosimameyer.com/post/adding-your-hugo-academic-blog-to-r-bloggers-and-python-bloggers/) 91 | 92 | ###### Hugo Portio 93 | 94 | - Copy and paste the content of [this file](https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/embedded/templates/_default/rss.xml) (it’s Hugo’s default RSS settings) 95 | - Store it under `layouts/_default/rss.xml` (if there is no file, you need to create this one). 96 | - Exchange one line. Instead of `{{ .Summary | html }}`, we want `{{ .Content | html }}` (it’s at the very bottom of the file). This way, you RSS feed doesn’t show an excerpt but the full text. 97 | - More about [Hugo Portio](https://cosimameyer.com/post/adding-your-hugo-academic-blog-to-r-bloggers-and-python-bloggers/) 98 |
99 | 100 |
Medium 101 | Medium nicely describes on their website how to [get your RSS feed](https://help.medium.com/hc/en-us/articles/214874118-Using-RSS-feeds-of-profiles-publications-and-topics). Unfortunately it's not possible to have a tag specific feed (yet). To keep the bot sorted, please make sure to only post about Python-related topics (= things that could be interesting to the followers of the bot).
102 | 103 | #### RSS feed for YouTube videos 104 | 105 | The channel or playlist RSS feed will be used to build the RSS feed for your YouTube videos. You first need to get your channel or playlist ID. How to add get them is described [here](https://www.youtube.com/watch?v=vdk8dx08ExU). 106 | In the last step, you need to assemble them together with the base URL: 107 | 108 | - For *channels*: `https://www.youtube.com/feeds/videos.xml?channel_id=` + `CHANNEL_ID` 109 | - For *playlists*: `https://www.youtube.com/feeds/videos.xml?paylist_id=` + `PLAYLIST_ID` 110 | 111 | #### Authors 112 | 113 | The entry may have several authors. This is for blogs where maybe there are several blogging together. If it is a blog that mainly has guest bloggers, its better to list the editors/maintainers of the blog and add "guest bloggers" as authors also. 114 | 115 | Adding several authors means duplicating the content between the curlies `{}` in the author section, and adding a comma between each one. 116 | 117 | ```json 118 | "authors": [ 119 | { 120 | "name": "Athanasia Mo Mowinckel", 121 | "social_media": [{ 122 | "twitter": "DrMowinckels", 123 | "github": "Athanasiamo" 124 | }] 125 | }, 126 | { 127 | "name": "Mary Johnson", 128 | "social_media": [{ 129 | "linkedin": "maryj", 130 | "youtube": "maryj" 131 | }] 132 | }, 133 | { 134 | "name": "Guest bloggers" 135 | } 136 | ] 137 | ``` 138 | 139 | #### Social Media 140 | 141 | ```json 142 | "twitter": "username" 143 | "mastodon": "@username@instance" 144 | "github": "username" 145 | "instagram": "username" 146 | "youtube": "username/end-url" 147 | "tiktok": "username" 148 | "periscope": "username" 149 | "researchgate": "username" 150 | "website": "url" 151 | "linkedin": "username" 152 | "facebook": "username" 153 | "orcid": "member number" 154 | "meetup": "end-url" 155 | ``` 156 | 157 | #### Language 158 | The language field should be populated with the [ISO 639-1 Language Codes](https://www.w3schools.com/tags/ref_language_codes.asp) of the site content. 159 | Please be thorough when entering this information. 160 | 161 | #### Help Needed? 162 | 163 | If there is help needed, feel free to reach out to [me directly](mailto:contact@cosimameyer.com). 164 | -------------------------------------------------------------------------------- /img/icons/safari.svg: -------------------------------------------------------------------------------- 1 | Safari -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Awesome PyLadies' Repository 3 | 4 | 5 | 6 | [![Awesome](https://awesome.re/badge.svg)](https://awesome.re) 7 | 8 | ## What Is This Repository About? 9 | 10 | It provides a curated list of awesome content by PyLadies and collects information to further promote content by [PyLadies on Mastodon](https://botsin.space/@pyladies_bot) 🤖 11 | 12 | To contribute, please see [contributing](CONTRIBUTING.md) ✨ 13 | 14 | ## List of Contributors as Tiles 15 | 16 | | | | | 17 | |:-------------------------:|:-------------------------:|:-------------------------:| 18 | |Image of Anastasia Karavdina
Anastasia Karavdina
🌐 🧳 |Image of Anja Pilz
Anja Pilz
🌐 🐙 🧳 |Image of Bilge Yucel
Bilge Yucel
🌐 🐙 🐘 🧳 🐦 | 19 | |Image of Cheuk Ting Ho
Cheuk Ting Ho
🌐 🐙 🐘 🦋 ▶️ 🧳 🐦 |Image of Christy Heaton
Christy Heaton
🌐 🐙 🐘 📸 🧳 |Image of Corrie Bartelheimer
Corrie Bartelheimer
🌐 🐙 🐘 🧳 🐦 | 20 | |Image of Cosima Meyer
Cosima Meyer
🌐 🐙 🐘 🦋 🧳 |Image of Déborah Mesquita
Déborah Mesquita
🌐 🐙 🧳 |Image of Ellen Schwartau
Ellen Schwartau
🌐 🐙 📸 🧳 🐦 | 21 | |Image of Emily Riederer
Emily Riederer
🌐 🐙 🐘 🦋 🧳 🐦 |Image of Ines Montani
Ines Montani
🌐 🐙 🐘 🧳 🐦 |Image of Isabel Zimmerman
Isabel Zimmerman
🐙 🐘 🦋 🧳 🐦 | 22 | |Image of Jennifer HY Lin
Jennifer HY Lin
🐙 🐘 🦋 🐦 |Image of Jess Temporal
Jess Temporal
🌐 🐙 🐘 🧳 🐦 |Image of Jessica Greene
Jessica Greene
🌐 🐙 🐘 🧳 🐦 | 23 | |Image of Karina Bartolome
Karina Bartolome
🌐 🐙 🐘 📸 🧳 🐦 |Image of Lacey Henschel
Lacey Henschel
🌐 🐙 🧳 |Image of Lynn Root
Lynn Root
🌐 🐙 🐘 📸 🧳 🐦 | 24 | |Image of Maren Westermann
Maren Westermann
🐙 🐘 🧳 🐦 |Image of Mariatta
Mariatta
🐙 🐘 🦋 📸 ▶️ 🧳 🐦 |Image of Pamela Fox
Pamela Fox
🌐 🐙 🐘 🧳 🐦 | 25 | |Image of PyLadies Bengaluru
PyLadies Bengaluru
🌐 ▶️ 🐦 |Image of PyLadies Berlin
PyLadies Berlin
🌐 ▶️ 🧳 🐦 |Image of PyLadies Hamburg
PyLadies Hamburg
▶️ 🧳 | 26 | |Image of PyLadies London
PyLadies London
🌐 ▶️ 🧳 🐦 |Image of PyLadies SoFlo
PyLadies SoFlo
🐙 🧳 🐦 |Image of Sabrine Bendimerad
Sabrine Bendimerad
🐙 🧳 🐦 | 27 | |Image of Samantha Zeitlin
Samantha Zeitlin
🐙 ▶️ 🧳 🐦 |Image of Stefanie Molin
Stefanie Molin
🌐 🐙 🧳 🐦 |Image of Tuana Celik
Tuana Celik
🐙 🐘 🧳 🐦 | 28 | |Image of Valery C. Briz
Valery C. Briz
🐙 🐘 🧳 🐦 |Image of Vicky Twomey-Lee
Vicky Twomey-Lee
🌐 🐙 🐘 🦋 📸 🧳 🐦 |Image of Victoria Slocum
Victoria Slocum
🌐 🐙 🐘 🦋 🧳 🐦 | 29 | | 30 | 31 | ## List of Content 32 | 33 | ### Blogs 34 | - [Anastasia's blog](https://www.karavdina.com/blog) by Anastasia Karavdina 35 | - [Anja Pilz](https://aplz.github.io) by Anja Pilz 36 | - [Bilge Yucel](https://medium.com/@bilgeycl) by Bilge Yucel 37 | - [Cheuk Ting Ho](https://cheuk.dev) by Cheuk Ting Ho 38 | - [Christy Heaton](https://christyheaton.github.io/) by Christy Heaton 39 | - [Samples of Thoughts](https://www.samples-of-thoughts.com) by Corrie Bartelheimer 40 | - [Cosima Meyer](https://cosimameyer.com/) by Cosima Meyer 41 | - [Déborah Mesquita](https://medium.com/@dehhmesquita) by Déborah Mesquita 42 | - [Ellens Blog](https://ellenschwartau.com) by Ellen Schwartau 43 | - [Emily Riederer](https://emilyriederer.com) by Emily Riederer 44 | - [Ines Montani](https://ines.io) by Ines Montani 45 | - [Isabel Zimmerman](https://isabelizimm.github.io/) by Isabel Zimmerman 46 | - [Data in life](https://jhylin.github.io/Data_in_life_blog/) by Jennifer HY Lin 47 | - [Jess Temporal](https://jtemporal.com/en) by Jess Temporal 48 | - [Jessica Greene (PyLadies Berlin) Medium account](https://medium.com/@jessica0greene) by Jessica Greene 49 | - [Karina Bartolome](https://karbartolome-blog.netlify.app) by Karina Bartolome 50 | - [Lacey Henschel's blog](https://www.laceyhenschel.com/blog) by Lacey Henschel 51 | - [Lynn Root](https://roguelynn.com/words) by Lynn Root 52 | - [Maren's blog about science and technology](https://marenwestermann.github.io) by Maren Westermann 53 | - [Mariatta's Blog](https://mariatta.ca) by Mariatta 54 | - [Pamela Fox](http://blog.pamelafox.org/) by Pamela Fox 55 | - [Sabrine Bendimerad](https://medium.com/@sabrine.bendimerad1) by Sabrine Bendimerad 56 | - [Always Be Getting Data (ABGD)](https://szeitlin.github.io) by Samantha Zeitlin 57 | - [Stefanie Molin](https://stefaniemolin.com/articles) by Stefanie Molin 58 | - [Tuana Celik](https://medium.com/@tuanacelik) by Tuana Celik 59 | - [Valery C. Briz](https://dev.to/valerybriz) by Valery C. Briz 60 | - [whykay @ dev.to](https://dev.to/whykay) by Vicky Twomey-Lee 61 | - [Victoria Slocum's blog](https://blog.victoriaslocum.com) by Victoria Slocum 62 | 63 | ### YouTube Channels 64 | - [PyLadies Bengaluru](https://www.youtube.com/@pyladiesbengaluru7366) by PyLadies Bengaluru 65 | - [PyLadies Berlin](https://www.youtube.com/@PyLadiesBerlin) by PyLadies Berlin 66 | - [PyLadies Hamburg](https://www.youtube.com/@HamburgPyLadies) by PyLadies Hamburg 67 | - [PyLadies London](https://www.youtube.com/@pyladieslondon2675) by PyLadies London 68 | - [PyLadies SoFlo YouTube channel](https://www.youtube.com/channel/UCUPLdokEtQlQmbaW9UkJEVQ) by PyLadies SoFlo 69 | 70 | --- 71 | 72 | _Last updated on 2025-06-30 15:45 UTC_ 73 | 74 | ## License 75 | 76 | [![CC0](https://upload.wikimedia.org/wikipedia/commons/6/69/CC0_button.svg)](https://creativecommons.org/publicdomain/zero/1.0/) 77 | --------------------------------------------------------------------------------