fix(batch-9): resolve merge conflict with main after batch 8 merge
BIN
images/DonaldSkelton.webp
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
images/FelixLindner_1.png
Normal file
|
After Width: | Height: | Size: 691 KiB |
BIN
images/FelixLindner_2.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
images/JeromeHeckenkamp.jpg
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
images/KellyClark_1.jpg
Normal file
|
After Width: | Height: | Size: 148 KiB |
BIN
images/KellyClark_2.jpg
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
images/KevinMitnick.webp
Normal file
|
After Width: | Height: | Size: 45 KiB |
BIN
images/KrisNova.jpg
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
images/RCMartinez.jpg
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
images/RoyDavis_1.png
Normal file
|
After Width: | Height: | Size: 339 KiB |
BIN
images/RoyDavis_2.png
Normal file
|
After Width: | Height: | Size: 2.2 MiB |
BIN
images/RoyDavis_3.png
Normal file
|
After Width: | Height: | Size: 6.5 MiB |
BIN
images/SteveSteinberg.jpg
Normal file
|
After Width: | Height: | Size: 221 KiB |
BIN
images/TerryLeifeste.jpg
Normal file
|
After Width: | Height: | Size: 45 KiB |
BIN
images/y3t1_Art-Dan_Kaminsky.png
Normal file
|
After Width: | Height: | Size: 445 KiB |
15
people/aaronestis.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"firstname": "Aaron",
|
||||
"lastname": "Estis",
|
||||
"handle": "Bogaaron",
|
||||
"birth": "",
|
||||
"death": "2022",
|
||||
"obituary": "",
|
||||
"issue": "186",
|
||||
"affiliations": "DEF CON Goon",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>Aaron Estis, known as Bogaaron, was a DEF CON Goon and member of the information security community.</p>",
|
||||
"socialmedialinks": [],
|
||||
"contributions": [],
|
||||
"gallery": []
|
||||
}
|
||||
24
people/adrianlamo.json
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"firstname": "Adrian",
|
||||
"lastname": "Lamo",
|
||||
"handle": "",
|
||||
"birth": "1981",
|
||||
"death": "2018",
|
||||
"obituary": "",
|
||||
"issue": "209",
|
||||
"affiliations": "2600",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>Adrian Lamo was an American threat analyst and hacker. Known as the \"homeless hacker\" for his nomadic lifestyle, Lamo gained attention for breaking into several high-profile computer networks including those of The New York Times, Yahoo!, and Microsoft. He was later known for reporting Chelsea Manning to the U.S. Army in 2010 after Manning confided in him about leaking classified documents to WikiLeaks. Lamo was found dead in a Wichita, Kansas apartment in 2018 at the age of 37.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "Facebook",
|
||||
"siteurl": "https://www.facebook.com/LordlOfTheRings"
|
||||
},
|
||||
{
|
||||
"sitename": "Other",
|
||||
"siteurl": "https://www.npr.org/2019/09/19/760317486/the-mysterious-death-of-the-hacker-who-turned-in-chelsea-manning"
|
||||
}
|
||||
],
|
||||
"contributions": [],
|
||||
"gallery": []
|
||||
}
|
||||
30
people/brammoolenaar.json
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"firstname": "Bram",
|
||||
"lastname": "Moolenaar",
|
||||
"handle": "",
|
||||
"birth": "1961",
|
||||
"death": "2023",
|
||||
"obituary": "https://groups.google.com/g/vim_announce/c/tWahca9zkt4",
|
||||
"issue": "236",
|
||||
"affiliations": "",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>Bram Moolenaar was a Dutch software engineer and the creator, maintainer, and benevolent dictator for life of Vim, one of the most widely used text editors in the world. Moolenaar began developing Vim in 1991 as an improvement on the vi editor. He maintained and developed Vim for over 30 years, making it an essential tool for millions of programmers worldwide. Moolenaar was also the founder of the ICCF Holland charity, which supports children in Uganda.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "Wikipedia",
|
||||
"siteurl": "https://en.wikipedia.org/wiki/Bram_Moolenaar"
|
||||
},
|
||||
{
|
||||
"sitename": "Other",
|
||||
"siteurl": "https://www.theregister.com/2023/08/07/bram_moolenaar_obituary/"
|
||||
}
|
||||
],
|
||||
"contributions": [
|
||||
{
|
||||
"title": "Vim",
|
||||
"url": "https://github.com/vim/vim",
|
||||
"description": "Creator and maintainer of Vim, one of the most popular and enduring text editors, used by millions of developers worldwide."
|
||||
}
|
||||
],
|
||||
"gallery": []
|
||||
}
|
||||
15
people/carolanthony.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"firstname": "Carol",
|
||||
"lastname": "Anthony",
|
||||
"handle": "",
|
||||
"birth": "",
|
||||
"death": "",
|
||||
"obituary": "",
|
||||
"issue": "206",
|
||||
"affiliations": "ISACA, MTA, Bank of America, Phillips, Protiviti",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>Carol Anthony was a cybersecurity professional with experience at ISACA, MTA, Bank of America, Phillips, and Protiviti.</p>",
|
||||
"socialmedialinks": [],
|
||||
"contributions": [],
|
||||
"gallery": []
|
||||
}
|
||||
15
people/chrisnightstalker.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"firstname": "Chris",
|
||||
"lastname": "",
|
||||
"handle": "The Nightstalker",
|
||||
"birth": "",
|
||||
"death": "",
|
||||
"obituary": "https://web.archive.org/web/20181021094502/http://w3.cultdeadcow.com/cms/nightstalker.html",
|
||||
"issue": "201",
|
||||
"affiliations": "Cult of the Dead Cow",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>Chris, known as The Nightstalker, was a member of Cult of the Dead Cow (cDc), one of the oldest and most influential hacking groups in the United States.</p>",
|
||||
"socialmedialinks": [],
|
||||
"contributions": [],
|
||||
"gallery": []
|
||||
}
|
||||
36
people/chrisscott.json
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"firstname": "Chris",
|
||||
"lastname": "Scott",
|
||||
"handle": "Cyb3r_Assassin",
|
||||
"birth": "1983",
|
||||
"death": "2021",
|
||||
"obituary": "https://www.clary-glenn.com/obituary/christopher-chris-scott",
|
||||
"issue": "167",
|
||||
"affiliations": "FoD, DEF CON Goon, DC615",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>Chris Scott, known as Cyb3r_Assassin, was a DEF CON Goon and member of the DC615 Nashville DEF CON group. He was active in the hacker community and contributed through multiple security groups and events.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "Twitter",
|
||||
"siteurl": "https://twitter.com/Cyb3r_Assassin"
|
||||
},
|
||||
{
|
||||
"sitename": "Github",
|
||||
"siteurl": "https://github.com/Cyb3r-Assassin"
|
||||
},
|
||||
{
|
||||
"sitename": "YouTube",
|
||||
"siteurl": "https://www.youtube.com/channel/UCr-NX4TPEi9JNrwtBJreIwQ"
|
||||
},
|
||||
{
|
||||
"sitename": "WordPress",
|
||||
"siteurl": "https://cyb3rassassin.wordpress.com/"
|
||||
},
|
||||
{
|
||||
"sitename": "MX Sponsor",
|
||||
"siteurl": "https://www.mxsponsor.com/riders/chris-a-scott"
|
||||
}
|
||||
],
|
||||
"contributions": [],
|
||||
"gallery": []
|
||||
}
|
||||
40
people/dankaminsky.json
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"firstname": "Dan",
|
||||
"lastname": "Kaminsky",
|
||||
"handle": "",
|
||||
"birth": "",
|
||||
"death": "2021",
|
||||
"obituary": "https://www.securityweek.com/security-researcher-dan-kaminsky-passes-away",
|
||||
"issue": "169",
|
||||
"affiliations": "",
|
||||
"mainimage": "/images/y3t1_Art-Dan_Kaminsky.png",
|
||||
"maintext": "<p>Dan Kaminsky was an American computer security researcher. He was a co-founder and chief scientist of WhiteOps (now HUMAN Security). Kaminsky was widely known for his work on DNS security, most notably for discovering a fundamental flaw in the DNS protocol in 2008 that could allow attackers to easily perform cache poisoning attacks on most nameservers. He worked with DNS vendors worldwide in secret to develop a patch, coordinating one of the largest simultaneous security fixes in internet history. Kaminsky was a popular speaker at conferences including DEF CON and Black Hat, known for his wide-ranging curiosity and infectious enthusiasm for exploring security across diverse domains.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "Twitter",
|
||||
"siteurl": "https://twitter.com/dakami"
|
||||
},
|
||||
{
|
||||
"sitename": "Wikipedia",
|
||||
"siteurl": "https://en.wikipedia.org/wiki/Dan_Kaminsky"
|
||||
}
|
||||
],
|
||||
"contributions": [
|
||||
{
|
||||
"title": "DNS Cache Poisoning Research",
|
||||
"url": "https://en.wikipedia.org/wiki/Dan_Kaminsky#DNS_cache_poisoning",
|
||||
"description": "Discovered a fundamental flaw in the DNS protocol in 2008 that allowed cache poisoning attacks, coordinating a massive multi-vendor patch effort."
|
||||
},
|
||||
{
|
||||
"title": "Bitcoin Flaws Analysis",
|
||||
"url": "https://www.businessinsider.com/dan-kaminsky-highlights-flaws-bitcoin-2013-4?op=1",
|
||||
"description": "Research highlighting flaws in Bitcoin."
|
||||
},
|
||||
{
|
||||
"title": "DEF CON Documentary Interview (2012)",
|
||||
"url": "https://www.youtube.com/watch?v=ZkqY4l6mPtc",
|
||||
"description": "Full 30-minute interview with Dan Kaminsky about DEF CON, speaking at hacking cons, and what makes them special. Released from the vaults by @textfiles with permission from @thedarktangent."
|
||||
}
|
||||
],
|
||||
"gallery": []
|
||||
}
|
||||
20
people/donaldskelton.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"firstname": "Donald",
|
||||
"lastname": "Skelton",
|
||||
"handle": "",
|
||||
"birth": "1989",
|
||||
"death": "2023",
|
||||
"obituary": "",
|
||||
"issue": "191",
|
||||
"affiliations": "303",
|
||||
"mainimage": "/images/DonaldSkelton.webp",
|
||||
"maintext": "<p>Donald Duane Skelton was a member of the 303 hacking group. He passed away on January 18, 2023, after a prolonged battle with illness. He is survived by his wife and two sons.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "GoFundMe",
|
||||
"siteurl": "https://www.gofundme.com/f/donald-dwayne-skelton"
|
||||
}
|
||||
],
|
||||
"contributions": [],
|
||||
"gallery": []
|
||||
}
|
||||
15
people/fabianrodriguez.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"firstname": "Fabian",
|
||||
"lastname": "Rodriguez",
|
||||
"handle": "scrotum man",
|
||||
"birth": "",
|
||||
"death": "2022",
|
||||
"obituary": "",
|
||||
"issue": "185",
|
||||
"affiliations": "",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>Fabian Rodriguez, known as scrotum man, was a member of the hacker community.</p>",
|
||||
"socialmedialinks": [],
|
||||
"contributions": [],
|
||||
"gallery": []
|
||||
}
|
||||
30
people/felixlindner.json
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"firstname": "Felix",
|
||||
"lastname": "Lindner",
|
||||
"handle": "Fx",
|
||||
"birth": "",
|
||||
"death": "2026",
|
||||
"obituary": "https://blog.recurity-labs.com/2026-03-02/Farewell_Felix",
|
||||
"issue": "308",
|
||||
"affiliations": "Phenoelit",
|
||||
"mainimage": "/images/FelixLindner_1.png",
|
||||
"maintext": "<p>Felix \"FX\" Lindner was a renowned German security researcher and founder of Recurity Labs. He was a member of Phenoelit, a hacking group known for their research on network infrastructure security. FX was a prolific speaker at security conferences worldwide, presenting research on topics ranging from router exploitation to Cisco IOS security. He was widely respected for his deep technical expertise and contributions to understanding vulnerabilities in critical network infrastructure.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "Website",
|
||||
"siteurl": "https://phenoelit.de/"
|
||||
},
|
||||
{
|
||||
"sitename": "Other",
|
||||
"siteurl": "https://infocondb.org/presenter/felix-lindner-fx"
|
||||
}
|
||||
],
|
||||
"contributions": [],
|
||||
"gallery": [
|
||||
{
|
||||
"url": "/images/FelixLindner_2.png",
|
||||
"title": "Felix Lindner (FX)",
|
||||
"caption": "Photo of Felix Lindner shared by The Dark Tangent"
|
||||
}
|
||||
]
|
||||
}
|
||||
20
people/genekan.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"firstname": "Gene",
|
||||
"lastname": "Kan",
|
||||
"handle": "",
|
||||
"birth": "1976",
|
||||
"death": "2002",
|
||||
"obituary": "",
|
||||
"issue": "163",
|
||||
"affiliations": "",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>Gene Kan was a computer programmer and open source advocate best known for his work on Gnutella, the peer-to-peer file sharing network. He was an early and prominent developer of the Gnutella protocol and its open source implementations, and became a visible spokesperson for the peer-to-peer movement. Kan was also a contributor to various open source projects and a frequent speaker on decentralized networking technology.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "Wikipedia",
|
||||
"siteurl": "https://en.wikipedia.org/wiki/Gene_Kan"
|
||||
}
|
||||
],
|
||||
"contributions": [],
|
||||
"gallery": []
|
||||
}
|
||||
20
people/glenneccard.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"firstname": "Glenn",
|
||||
"lastname": "Eccard",
|
||||
"handle": "V310C1TY",
|
||||
"birth": "",
|
||||
"death": "2021",
|
||||
"obituary": "",
|
||||
"issue": "183",
|
||||
"affiliations": "Hackers For Charity",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>Glenn Eccard, known as V310C1TY, was a member of Hackers For Charity and the broader information security community.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "Twitter",
|
||||
"siteurl": "https://twitter.com/V310C1TY/"
|
||||
}
|
||||
],
|
||||
"contributions": [],
|
||||
"gallery": []
|
||||
}
|
||||
20
people/ilyazhitomirskiy.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"firstname": "Ilya",
|
||||
"lastname": "Zhitomirskiy",
|
||||
"handle": "",
|
||||
"birth": "1989",
|
||||
"death": "2011",
|
||||
"obituary": "",
|
||||
"issue": "164",
|
||||
"affiliations": "",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>Ilya Zhitomirskiy was a software developer and co-founder of Diaspora, a decentralized social networking platform created as a privacy-aware alternative to Facebook. While a student at New York University, Zhitomirskiy and three classmates launched a successful Kickstarter campaign in 2010 to fund development of the open source social network. The project drew widespread attention as a response to growing concerns about privacy on centralized social media platforms.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "Other",
|
||||
"siteurl": "https://www.forbes.com/sites/meghancasserly/2011/11/16/ilya-zhitomirskiy-diaspora-suicide-speculation-depression-stress-anxiety/"
|
||||
}
|
||||
],
|
||||
"contributions": [],
|
||||
"gallery": []
|
||||
}
|
||||
20
people/jamesdolan.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"firstname": "James",
|
||||
"lastname": "Dolan",
|
||||
"handle": "",
|
||||
"birth": "1981",
|
||||
"death": "2017",
|
||||
"obituary": "",
|
||||
"issue": "162",
|
||||
"affiliations": "",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>James Dolan was a computer security expert and Marine veteran. He was a co-creator of SecureDrop, the open-source whistleblower submission system, alongside Aaron Swartz and Kevin Poulsen. SecureDrop is used by major news organizations worldwide to securely receive documents from anonymous sources.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "Wikipedia",
|
||||
"siteurl": "https://en.wikipedia.org/wiki/James_Dolan_(computer_security_expert)"
|
||||
}
|
||||
],
|
||||
"contributions": [],
|
||||
"gallery": []
|
||||
}
|
||||
35
people/jasonsnitker.json
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"firstname": "Jason",
|
||||
"lastname": "Snitker",
|
||||
"handle": "Parmaster",
|
||||
"birth": "",
|
||||
"death": "2026",
|
||||
"obituary": "",
|
||||
"issue": "307",
|
||||
"affiliations": "",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>Jason Snitker, known as Parmaster, was a member of the hacker and information security community. His story was featured on the Darknet Diaries podcast.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "Bluesky",
|
||||
"siteurl": "https://bsky.app/profile/did:plc:low75hwexu2oc5v2rj5p2lbu"
|
||||
}
|
||||
],
|
||||
"contributions": [
|
||||
{
|
||||
"title": "Darknet Diaries Episode 169",
|
||||
"url": "https://darknetdiaries.com/transcript/169/",
|
||||
"description": "Jason's story featured on the Darknet Diaries podcast."
|
||||
}
|
||||
],
|
||||
"gallery": [
|
||||
{
|
||||
"url": "https://fxtwitter.com/WeldPond/status/2024682841292898378",
|
||||
"caption": "WeldPond memorial tweet"
|
||||
},
|
||||
{
|
||||
"url": "https://www.youtube.com/watch?v=BkeXk9rBBrs&t=1s",
|
||||
"caption": "YouTube video"
|
||||
}
|
||||
]
|
||||
}
|
||||
28
people/jeromeheckenkamp.json
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"firstname": "Jerome",
|
||||
"lastname": "Heckenkamp",
|
||||
"handle": "Sk8",
|
||||
"birth": "1979",
|
||||
"death": "2016",
|
||||
"obituary": "https://www.legacy.com/funeral-homes/obituaries/name/jerome-heckenkamp-obituary?pid=178007168&v=batesville",
|
||||
"issue": "208",
|
||||
"affiliations": "",
|
||||
"mainimage": "/images/JeromeHeckenkamp.jpg",
|
||||
"maintext": "<p>Jerome Heckenkamp, known as Sk8 (also linked to the handle MagicFX), was a hacker who gained notoriety for unauthorized access to computer networks at several organizations including Qualcomm, eBay, and others. His case became notable in computer law, involving questions about search and seizure of computer evidence. He was defended by Jennifer Granick of the Stanford Cyberlaw Clinic.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "Memorial Site",
|
||||
"siteurl": "https://www.jeromeheckenkamp.com/"
|
||||
},
|
||||
{
|
||||
"sitename": "IT Law Wiki",
|
||||
"siteurl": "https://itlaw.fandom.com/wiki/U.S._v._Heckenkamp"
|
||||
},
|
||||
{
|
||||
"sitename": "Free Sk8 Archive",
|
||||
"siteurl": "https://web.archive.org/web/20031008121704/http://www.freesk8.com/"
|
||||
}
|
||||
],
|
||||
"contributions": [],
|
||||
"gallery": []
|
||||
}
|
||||
20
people/kellyclark.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"firstname": "Kelly",
|
||||
"lastname": "Clark",
|
||||
"handle": "",
|
||||
"birth": "",
|
||||
"death": "",
|
||||
"obituary": "",
|
||||
"issue": "204",
|
||||
"affiliations": "",
|
||||
"mainimage": "/images/KellyClark_1.jpg",
|
||||
"maintext": "<p>Kelly Clark was a member of the hacker and information security community.</p>",
|
||||
"socialmedialinks": [],
|
||||
"contributions": [],
|
||||
"gallery": [
|
||||
{
|
||||
"url": "/images/KellyClark_2.jpg",
|
||||
"caption": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
30
people/kellytodd.json
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"firstname": "Kelly",
|
||||
"lastname": "Todd",
|
||||
"handle": "Lyger",
|
||||
"birth": "",
|
||||
"death": "2022",
|
||||
"obituary": "",
|
||||
"issue": "198",
|
||||
"affiliations": "Attrition",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>Kelly Todd, known as Lyger, was a member of the Attrition.org crew. He was active in the information security community and contributed to security research and documentation efforts through Attrition.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "Twitter",
|
||||
"siteurl": "https://twitter.com/lazlo_d_plumber"
|
||||
},
|
||||
{
|
||||
"sitename": "Website",
|
||||
"siteurl": "https://attrition.org/~lyger/"
|
||||
}
|
||||
],
|
||||
"contributions": [
|
||||
{
|
||||
"title": "Tribute Video",
|
||||
"url": "https://www.youtube.com/watch?v=zOH5jEK4dhk",
|
||||
"description": "Video tribute to Kelly Todd (Lyger)."
|
||||
}
|
||||
],
|
||||
"gallery": []
|
||||
}
|
||||
24
people/kevinestis.json
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"firstname": "Kevin",
|
||||
"lastname": "Estis",
|
||||
"handle": "",
|
||||
"birth": "",
|
||||
"death": "2021",
|
||||
"obituary": "",
|
||||
"issue": "165",
|
||||
"affiliations": "DEF CON Goon",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>Kevin Estis was a member of the information security community and a DEF CON Goon.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "Twitter",
|
||||
"siteurl": "https://twitter.com/kevinestis"
|
||||
},
|
||||
{
|
||||
"sitename": "GoFundMe",
|
||||
"siteurl": "https://www.gofundme.com/f/aid-for-kevin-estis-family-and-pets"
|
||||
}
|
||||
],
|
||||
"contributions": [],
|
||||
"gallery": []
|
||||
}
|
||||
40
people/kevinmitnick.json
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"firstname": "Kevin",
|
||||
"lastname": "Mitnick",
|
||||
"handle": "Condor",
|
||||
"birth": "1963",
|
||||
"death": "2023",
|
||||
"obituary": "https://www.dignitymemorial.com/obituaries/las-vegas-nv/kevin-mitnick-11371668",
|
||||
"issue": "197",
|
||||
"affiliations": "",
|
||||
"mainimage": "/images/KevinMitnick.webp",
|
||||
"maintext": "<p>Kevin David Mitnick was an American computer security consultant, author, and convicted hacker. Once the FBI's most-wanted computer criminal, Mitnick was known for his social engineering skills and his ability to gain unauthorized access to computer systems and networks. After serving five years in prison, he became a security consultant and public speaker. He authored several books including <em>The Art of Deception</em>, <em>The Art of Intrusion</em>, and his autobiography <em>Ghost in the Wires</em>. Mitnick founded Mitnick Security Consulting and KnowBe4's Chief Hacking Officer.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "Twitter",
|
||||
"siteurl": "https://twitter.com/kevinmitnick"
|
||||
},
|
||||
{
|
||||
"sitename": "Wikipedia",
|
||||
"siteurl": "https://en.wikipedia.org/wiki/Kevin_Mitnick"
|
||||
}
|
||||
],
|
||||
"contributions": [
|
||||
{
|
||||
"title": "CNN Obituary",
|
||||
"url": "https://www.cnn.com/2023/07/21/us/computer-hacker-kevin-mitnick-obit/index.html",
|
||||
"description": "CNN obituary for Kevin Mitnick."
|
||||
},
|
||||
{
|
||||
"title": "BBC Obituary",
|
||||
"url": "https://www.bbc.com/news/world-us-canada-66263235",
|
||||
"description": "BBC obituary for Kevin Mitnick."
|
||||
},
|
||||
{
|
||||
"title": "AP News Obituary",
|
||||
"url": "https://apnews.com/article/mitnick-hacker-ghost-wires-cybersecurity-social-engineering-5648301b615635cb4c781f0c220681d9",
|
||||
"description": "Associated Press obituary for Kevin Mitnick."
|
||||
}
|
||||
],
|
||||
"gallery": []
|
||||
}
|
||||
20
people/kevinriggins.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"firstname": "Kevin",
|
||||
"lastname": "Riggins",
|
||||
"handle": "",
|
||||
"birth": "",
|
||||
"death": "2022",
|
||||
"obituary": "https://www.hamiltonsfuneralhome.com/services/services_detail.aspx?rid=62762",
|
||||
"issue": "188",
|
||||
"affiliations": "",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>Kevin William Riggins was a member of the information security community.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "Twitter",
|
||||
"siteurl": "https://twitter.com/kriggins"
|
||||
}
|
||||
],
|
||||
"contributions": [],
|
||||
"gallery": []
|
||||
}
|
||||
40
people/krisnova.json
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"firstname": "Kris",
|
||||
"lastname": "Nova",
|
||||
"handle": "Kris Nova",
|
||||
"birth": "1986",
|
||||
"death": "2023",
|
||||
"obituary": "https://www.sportskeeda.com/pop-culture/news-kris-nova-accident-tributes-pour-github-engineer-passes-away",
|
||||
"issue": "251",
|
||||
"affiliations": "GitHub, Cloud Native Computing Foundation",
|
||||
"mainimage": "/images/KrisNova.jpg",
|
||||
"maintext": "<p>Kris Nova was an author, engineer, computer scientist, and alpinist best known for her work on Linux, Kubernetes, and Aurae. She was a Senior Developer Advocate for Heptio and an ambassador for the Cloud Native Computing Foundation. Prior to Heptio, Nova worked as a developer advocate for Microsoft and as an engineer on Kubernetes in Azure. She was a prolific open source contributor and the founder of Hachyderm, a Mastodon instance for technology professionals. Nova was also an avid mountaineer and YouTube host.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "Twitter",
|
||||
"siteurl": "https://twitter.com/krisnova"
|
||||
},
|
||||
{
|
||||
"sitename": "Github",
|
||||
"siteurl": "https://github.com/krisnova"
|
||||
},
|
||||
{
|
||||
"sitename": "Website",
|
||||
"siteurl": "https://krisnova.net/"
|
||||
},
|
||||
{
|
||||
"sitename": "Hachyderm",
|
||||
"siteurl": "https://hachyderm.io/@nova"
|
||||
},
|
||||
{
|
||||
"sitename": "YouTube",
|
||||
"siteurl": "https://www.youtube.com/@KrisNovaLive"
|
||||
},
|
||||
{
|
||||
"sitename": "Twitch",
|
||||
"siteurl": "https://twitch.tv/krisnova"
|
||||
}
|
||||
],
|
||||
"contributions": [],
|
||||
"gallery": []
|
||||
}
|
||||
15
people/mariamoraru.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"firstname": "Maria",
|
||||
"lastname": "Moraru",
|
||||
"handle": "",
|
||||
"birth": "",
|
||||
"death": "",
|
||||
"obituary": "",
|
||||
"issue": "205",
|
||||
"affiliations": "",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>Maria Moraru was a member of the hacker and information security community.</p>",
|
||||
"socialmedialinks": [],
|
||||
"contributions": [],
|
||||
"gallery": []
|
||||
}
|
||||
26
people/markshapiro.json
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"firstname": "Mark",
|
||||
"lastname": "Shapiro",
|
||||
"handle": "gntlmnguardian",
|
||||
"birth": "1979",
|
||||
"death": "2020",
|
||||
"obituary": "https://www.dignitymemorial.com/obituaries/falls-church-va/mark-shapiro-9170264",
|
||||
"issue": "158",
|
||||
"affiliations": "",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>Mark Edward Shapiro was a cybersecurity professional employed at Jacobs Critical Mission Solutions as a Project Manager of cybersecurity, intelligence, and information operations for the Securities and Exchange Commission in Washington, D.C. Only weeks prior to his death, Mark had completed his first cybersecurity industry convention presentation, giving a featured talk at BSides NoVA on \"Democratizing Intelligence.\" He also trained in Executive Protection and Physical Security, and often assisted in this capacity at media conventions.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "Twitter",
|
||||
"siteurl": "https://twitter.com/gntlmnguardian"
|
||||
}
|
||||
],
|
||||
"contributions": [
|
||||
{
|
||||
"title": "BSides NoVA 2020 - Democratized Intelligence: Promises and Pitfalls",
|
||||
"url": "https://www.youtube.com/watch?v=qKWQyk7Xypw&list=PLrwRJhfJmJRjleUT5gEBno3S5csqNIhFo&index=6&t=320s",
|
||||
"description": "A talk on the advancement of privatized intelligence capacity, examining how individuals can stand up a functional intelligence apparatus and the hazards of doing so from analytical and operational perspectives."
|
||||
}
|
||||
],
|
||||
"gallery": []
|
||||
}
|
||||
15
people/michaelpark.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"firstname": "Michael",
|
||||
"lastname": "Park",
|
||||
"handle": "Hosaka",
|
||||
"birth": "",
|
||||
"death": "2023",
|
||||
"obituary": "",
|
||||
"issue": "199",
|
||||
"affiliations": "r00t",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>Michael Park, known as Hosaka, was a member of the r00t hacking group.</p>",
|
||||
"socialmedialinks": [],
|
||||
"contributions": [],
|
||||
"gallery": []
|
||||
}
|
||||
37
people/mikemurray.json
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"firstname": "Mike",
|
||||
"lastname": "Murray",
|
||||
"handle": "",
|
||||
"birth": "1976",
|
||||
"death": "2022",
|
||||
"obituary": "https://jamesreidfuneralhome.com/tribute/details/14089/Michael-Murray/obituary.html",
|
||||
"issue": "187",
|
||||
"affiliations": "",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>Mike Murray was a cybersecurity professional and the founder of Scope Security. He was known for his work in the information security industry and was active in the security community.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "Twitter",
|
||||
"siteurl": "https://twitter.com/mmurray"
|
||||
},
|
||||
{
|
||||
"sitename": "Instagram",
|
||||
"siteurl": "https://www.instagram.com/michael_l_murray/"
|
||||
},
|
||||
{
|
||||
"sitename": "Scope Security",
|
||||
"siteurl": "https://scopesecurity.com/"
|
||||
}
|
||||
],
|
||||
"contributions": [],
|
||||
"gallery": [
|
||||
{
|
||||
"url": "https://www.instagram.com/p/CcJDPCevFBg/?igshid=YmMyMTA2M2Y=",
|
||||
"caption": "Instagram memorial post"
|
||||
},
|
||||
{
|
||||
"url": "https://twitter.com/scopesecurity_/status/1512927318481723394",
|
||||
"caption": "Scope Security memorial tweet"
|
||||
}
|
||||
]
|
||||
}
|
||||
20
people/ozzieosband.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"firstname": "Ozzie",
|
||||
"lastname": "Osband",
|
||||
"handle": "Cheshire Catalyst",
|
||||
"birth": "",
|
||||
"death": "2023",
|
||||
"obituary": "https://talkoftitusville.com/2023/08/06/ozzie-osband-originator-of-3-2-1-telephone-area-code-and-rocket-hobo-passes-away-at-72/",
|
||||
"issue": "241",
|
||||
"affiliations": "",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>Ozzie Osband, known as Cheshire Catalyst, was a phreaker and hacker active in the early days of the hacking scene. He was the editor of the Technology Assistance Program (TAP) newsletter, a successor to the YIPL (Youth International Party Line) newsletter that was a key publication in the phone phreaking community. He was known for originating the 321 telephone area code and was sometimes referred to as the Rocket Hobo.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "LinkedIn",
|
||||
"siteurl": "https://www.linkedin.com/in/ozzie321/"
|
||||
}
|
||||
],
|
||||
"contributions": [],
|
||||
"gallery": []
|
||||
}
|
||||
28
people/rcmartinez.json
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"firstname": "RC",
|
||||
"lastname": "Martinez",
|
||||
"handle": "GodFix",
|
||||
"birth": "",
|
||||
"death": "2021",
|
||||
"obituary": "https://www.skydogcon.com/2021/04/in-memoriam-godfix.html",
|
||||
"issue": "168",
|
||||
"affiliations": "DEF CON Goon, SkyDogCon Staff",
|
||||
"mainimage": "/images/RCMartinez.jpg",
|
||||
"maintext": "<p>RC Martinez, known as GodFix, was a DEF CON Goon and SkyDogCon staff member. Described as the \"Fixer of Itches\" and \"Finder of All-the-things,\" he was a staff member for five different conferences since 2007. When not filling roles at a con, he worked as a Senior Infrastructure Engineer. RC was known for his welcoming nature, always greeting people with a hug and a smile. He lost his battle with pneumonia caused by COVID-19 on April 17, 2021, leaving behind his wife Debra and two children.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "Twitter",
|
||||
"siteurl": "https://twitter.com/GodFix"
|
||||
},
|
||||
{
|
||||
"sitename": "GoFundMe",
|
||||
"siteurl": "https://gofund.me/b33cca5a"
|
||||
},
|
||||
{
|
||||
"sitename": "Facebook Memorial",
|
||||
"siteurl": "https://www.facebook.com/132688066753041/posts/4140135462674928/"
|
||||
}
|
||||
],
|
||||
"contributions": [],
|
||||
"gallery": []
|
||||
}
|
||||
20
people/reverendrat.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"firstname": "",
|
||||
"lastname": "",
|
||||
"handle": "Reverend Rat",
|
||||
"birth": "",
|
||||
"death": "",
|
||||
"obituary": "",
|
||||
"issue": "184",
|
||||
"affiliations": "",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>Reverend Rat was a member of the hacker and information security community.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "Twitter Memorial",
|
||||
"siteurl": "https://twitter.com/marcwrogers/status/1438186471907737600"
|
||||
}
|
||||
],
|
||||
"contributions": [],
|
||||
"gallery": []
|
||||
}
|
||||
15
people/richardbatka.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"firstname": "Richard",
|
||||
"lastname": "Batka",
|
||||
"handle": "Master Chemist",
|
||||
"birth": "",
|
||||
"death": "2023",
|
||||
"obituary": "",
|
||||
"issue": "200",
|
||||
"affiliations": "",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>Richard Batka, known as Master Chemist, was a member of the hacker and information security community.</p>",
|
||||
"socialmedialinks": [],
|
||||
"contributions": [],
|
||||
"gallery": []
|
||||
}
|
||||
49
people/roydavis.json
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
{
|
||||
"firstname": "Roy",
|
||||
"lastname": "Davis",
|
||||
"handle": "Hack_All_Things",
|
||||
"birth": "1968",
|
||||
"death": "2025",
|
||||
"obituary": "",
|
||||
"issue": "295",
|
||||
"affiliations": "",
|
||||
"mainimage": "/images/RoyDavis_1.png",
|
||||
"maintext": "<p>Roy Davis, known as Hack All Things, was a security researcher and hacker. He was known for his engaging conference talks, including a notable presentation on buying and hacking into an ATM. Roy challenged the industry to think about alternative approaches to measuring vulnerability severity through the VISS (Vulnerability Impact Scoring System) project at Zoom. He was active in the bug bounty community and participated in events such as H1-4420.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "Twitter",
|
||||
"siteurl": "https://x.com/Hack_All_Things"
|
||||
},
|
||||
{
|
||||
"sitename": "LinkedIn",
|
||||
"siteurl": "https://www.linkedin.com/in/roy-davis/"
|
||||
}
|
||||
],
|
||||
"contributions": [
|
||||
{
|
||||
"title": "ATM Hacking Talk",
|
||||
"url": "https://www.youtube.com/watch?v=9cG-JL0LHYw",
|
||||
"description": "Conference talk on buying an ATM and hacking into it."
|
||||
},
|
||||
{
|
||||
"title": "VISS - Vulnerability Impact Scoring System",
|
||||
"url": "https://viss.zoom.com/",
|
||||
"description": "An alternative approach to measuring vulnerability severity developed at Zoom."
|
||||
},
|
||||
{
|
||||
"title": "Zoom H1-4420 Event Blog Post",
|
||||
"url": "https://www.zoom.com/en/blog/zoom-hackerone-h1-4420-event-2023/",
|
||||
"description": "Roy's blog post about the Zoom HackerOne H1-4420 event in London 2023."
|
||||
}
|
||||
],
|
||||
"gallery": [
|
||||
{
|
||||
"url": "/images/RoyDavis_2.png",
|
||||
"caption": "Roy Davis at H1-4420 2023 in London"
|
||||
},
|
||||
{
|
||||
"url": "/images/RoyDavis_3.png",
|
||||
"caption": "Roy Davis at Infosecurity Europe 2023 in London"
|
||||
}
|
||||
]
|
||||
}
|
||||
15
people/stevesteinberg.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"firstname": "Steve",
|
||||
"lastname": "Steinberg",
|
||||
"handle": "Frank Drake",
|
||||
"birth": "1970",
|
||||
"death": "2020",
|
||||
"obituary": "https://boingboing.net/2020/10/09/steve-steinberg-hacker-writer-friend-1970-2020.html",
|
||||
"issue": "160",
|
||||
"affiliations": "",
|
||||
"mainimage": "/images/SteveSteinberg.jpg",
|
||||
"maintext": "<p>Steve Steinberg, also known as Frank Drake, was a hacker and writer. He was the publisher of WORM and Intertek, notable hacker-era publications. He was remembered as \"a true hacker\" by those who knew him.</p>",
|
||||
"socialmedialinks": [],
|
||||
"contributions": [],
|
||||
"gallery": []
|
||||
}
|
||||
20
people/terryleifeste.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"firstname": "Terry",
|
||||
"lastname": "Leifeste",
|
||||
"handle": "phliKtid",
|
||||
"birth": "1969",
|
||||
"death": "2026",
|
||||
"obituary": "https://www.crespoandjirrels.com/obituaries/Terry-Lynn-Leifeste?obId=47082591",
|
||||
"issue": "303",
|
||||
"affiliations": "DEF CON Goon SpeakerOps",
|
||||
"mainimage": "/images/TerryLeifeste.jpg",
|
||||
"maintext": "<p>Terry Lynn Leifeste, known as phliKtid, was a DEF CON Goon who worked in SpeakerOps, helping coordinate speakers and presentations at the conference.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "LinkedIn Memorial",
|
||||
"siteurl": "https://www.linkedin.com/posts/activity-7418849222084542464-BktK"
|
||||
}
|
||||
],
|
||||
"contributions": [],
|
||||
"gallery": []
|
||||
}
|
||||
20
people/timskorick.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"firstname": "Tim",
|
||||
"lastname": "Skorick",
|
||||
"handle": "Timmah",
|
||||
"birth": "",
|
||||
"death": "2026",
|
||||
"obituary": "",
|
||||
"issue": "304",
|
||||
"affiliations": "303",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>Tim Skorick, known as Timmah, was a member of the 303 hacking group and the information security community.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "GoFundMe",
|
||||
"siteurl": "https://www.gofundme.com/f/support-for-the-skorick-family"
|
||||
}
|
||||
],
|
||||
"contributions": [],
|
||||
"gallery": []
|
||||
}
|
||||
33
people/trycatchhcf.json
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"firstname": "Joe",
|
||||
"lastname": "",
|
||||
"handle": "TryCatchHCF",
|
||||
"birth": "",
|
||||
"death": "2023",
|
||||
"obituary": "",
|
||||
"issue": "190",
|
||||
"affiliations": "",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>Joe, known as TryCatchHCF, was a security researcher and open source developer. He was known in the hacker community for his security tools and contributions on GitHub. He passed away peacefully in his sleep after a battle with cancer, surrounded by people he loved. He was remembered as a private but deeply caring person who enjoyed birds, ethics discussions, and the outdoors.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "Twitter",
|
||||
"siteurl": "https://twitter.com/TryCatchHCF"
|
||||
},
|
||||
{
|
||||
"sitename": "Github",
|
||||
"siteurl": "https://github.com/TryCatchHCF/"
|
||||
}
|
||||
],
|
||||
"contributions": [],
|
||||
"gallery": [
|
||||
{
|
||||
"url": "https://twitter.com/rotate26chars/status/1612242052955398144",
|
||||
"caption": "Memorial thread by rotate26chars"
|
||||
},
|
||||
{
|
||||
"url": "https://twitter.com/Flex_Capacitor/status/1612551832261238794",
|
||||
"caption": "Remembrance from Joe's child"
|
||||
}
|
||||
]
|
||||
}
|
||||
31
people/vijaygill.json
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"firstname": "Vijay",
|
||||
"lastname": "Gill",
|
||||
"handle": "",
|
||||
"birth": "1971",
|
||||
"death": "2022",
|
||||
"obituary": "https://www.legacy.com/us/obituaries/name/vijay-gill-obituary?id=36166748",
|
||||
"issue": "232",
|
||||
"affiliations": "IAB, IETF, NANOG",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>Vijay Gill was a prolific network engineer employed by various ISPs and hyperscale networks including UUNet, AOL, Microsoft, Google, and Salesforce. He was a contributor to the wider Internet community through his involvement with the IETF, IAB, and NANOG, and co-authored multiple RFCs related to Internet architecture and routing.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "LinkedIn",
|
||||
"siteurl": "https://www.linkedin.com/in/vgill/"
|
||||
}
|
||||
],
|
||||
"contributions": [
|
||||
{
|
||||
"title": "RFC 3582 - Goals for IPv6 Site-Multihoming Architectures",
|
||||
"url": "https://www.rfc-editor.org/rfc/rfc3582.txt",
|
||||
"description": "Co-authored RFC defining goals for IPv6 site-multihoming architectures."
|
||||
},
|
||||
{
|
||||
"title": "RFC 4451 - BGP MULTI_EXIT_DISC (MED) Considerations",
|
||||
"url": "https://www.rfc-editor.org/rfc/rfc4451.txt",
|
||||
"description": "Co-authored RFC on BGP MED attribute considerations for network routing."
|
||||
}
|
||||
],
|
||||
"gallery": []
|
||||
}
|
||||
15
people/williamcopley.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"firstname": "William",
|
||||
"lastname": "Copley",
|
||||
"handle": "The Pull",
|
||||
"birth": "",
|
||||
"death": "2022",
|
||||
"obituary": "",
|
||||
"issue": "189",
|
||||
"affiliations": "cDc",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>William Andrew \"Drew\" Copley, known as The Pull, was a founding member of Hacktivismo and a respected friend of Cult of the Dead Cow (cDc). He was a tireless advocate of internet freedom and a valued security researcher. The Pull was a ridiculously smart guy with a great sense of humor and exemplary work ethic. He was dedicated to making a mark for the better, was a core contributor to the hacktivist movement, writing a steganography app called Camera/Shy. He died of cancer in 2022.</p>",
|
||||
"socialmedialinks": [],
|
||||
"contributions": [],
|
||||
"gallery": []
|
||||
}
|
||||
26
people/yonathanklijnsma.json
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"firstname": "Yonathan",
|
||||
"lastname": "Klijnsma",
|
||||
"handle": "ydklijnsma",
|
||||
"birth": "",
|
||||
"death": "2021",
|
||||
"obituary": "",
|
||||
"issue": "161",
|
||||
"affiliations": "",
|
||||
"mainimage": "/images/face-silhouette-clipart.png",
|
||||
"maintext": "<p>Yonathan Klijnsma was a security researcher known for his work in threat intelligence and cybersecurity. He passed away due to cancer in January 2021.</p>",
|
||||
"socialmedialinks": [
|
||||
{
|
||||
"sitename": "Twitter",
|
||||
"siteurl": "https://twitter.com/ydklijnsma"
|
||||
}
|
||||
],
|
||||
"contributions": [
|
||||
{
|
||||
"title": "Cybersecurity Interviews Podcast",
|
||||
"url": "https://cybersecurityinterviews.com/episodes/61-yonathan-klijnsma-get-compromised-get-compromised/",
|
||||
"description": "Episode 61 - Yonathan Klijnsma - Get Compromised, Get Compromised"
|
||||
}
|
||||
],
|
||||
"gallery": []
|
||||
}
|
||||
152
peoplelist.json
|
|
@ -228,6 +228,158 @@
|
|||
"displayname": "Ben Preston (Veruus)",
|
||||
"filename": "benpreston"
|
||||
},
|
||||
{
|
||||
"displayname": "Dan Kaminsky",
|
||||
"filename": "dankaminsky"
|
||||
},
|
||||
{
|
||||
"displayname": "Kevin Mitnick (Condor)",
|
||||
"filename": "kevinmitnick"
|
||||
},
|
||||
{
|
||||
"displayname": "Adrian Lamo",
|
||||
"filename": "adrianlamo"
|
||||
},
|
||||
{
|
||||
"displayname": "Bram Moolenaar",
|
||||
"filename": "brammoolenaar"
|
||||
},
|
||||
{
|
||||
"displayname": "Kris Nova",
|
||||
"filename": "krisnova"
|
||||
},
|
||||
{
|
||||
"displayname": "Kelly Todd (Lyger)",
|
||||
"filename": "kellytodd"
|
||||
},
|
||||
{
|
||||
"displayname": "Michael Park (Hosaka)",
|
||||
"filename": "michaelpark"
|
||||
},
|
||||
{
|
||||
"displayname": "Richard Batka (Master Chemist)",
|
||||
"filename": "richardbatka"
|
||||
},
|
||||
{
|
||||
"displayname": "Ozzie Osband (Cheshire Catalyst)",
|
||||
"filename": "ozzieosband"
|
||||
},
|
||||
{
|
||||
"displayname": "Felix Lindner (Fx)",
|
||||
"filename": "felixlindner"
|
||||
},
|
||||
{
|
||||
"displayname": "Mark Shapiro (gntlmnguardian)",
|
||||
"filename": "markshapiro"
|
||||
},
|
||||
{
|
||||
"displayname": "Steve Steinberg (Frank Drake)",
|
||||
"filename": "stevesteinberg"
|
||||
},
|
||||
{
|
||||
"displayname": "Yonathan Klijnsma",
|
||||
"filename": "yonathanklijnsma"
|
||||
},
|
||||
{
|
||||
"displayname": "James Dolan",
|
||||
"filename": "jamesdolan"
|
||||
},
|
||||
{
|
||||
"displayname": "Gene Kan",
|
||||
"filename": "genekan"
|
||||
},
|
||||
{
|
||||
"displayname": "Ilya Zhitomirskiy",
|
||||
"filename": "ilyazhitomirskiy"
|
||||
},
|
||||
{
|
||||
"displayname": "Kevin Estis",
|
||||
"filename": "kevinestis"
|
||||
},
|
||||
{
|
||||
"displayname": "Chris Scott (Cyb3r_Assassin)",
|
||||
"filename": "chrisscott"
|
||||
},
|
||||
{
|
||||
"displayname": "RC Martinez (GodFix)",
|
||||
"filename": "rcmartinez"
|
||||
},
|
||||
{
|
||||
"displayname": "Glenn Eccard (V310C1TY)",
|
||||
"filename": "glenneccard"
|
||||
},
|
||||
{
|
||||
"displayname": "Fabian Rodriguez",
|
||||
"filename": "fabianrodriguez"
|
||||
},
|
||||
{
|
||||
"displayname": "Aaron Estis (Bogaaron)",
|
||||
"filename": "aaronestis"
|
||||
},
|
||||
{
|
||||
"displayname": "Mike Murray",
|
||||
"filename": "mikemurray"
|
||||
},
|
||||
{
|
||||
"displayname": "Kevin William Riggins",
|
||||
"filename": "kevinriggins"
|
||||
},
|
||||
{
|
||||
"displayname": "William Andrew Copley (The Pull)",
|
||||
"filename": "williamcopley"
|
||||
},
|
||||
{
|
||||
"displayname": "TryCatchHCF (Joe)",
|
||||
"filename": "trycatchhcf"
|
||||
},
|
||||
{
|
||||
"displayname": "Donald Duane Skelton",
|
||||
"filename": "donaldskelton"
|
||||
},
|
||||
{
|
||||
"displayname": "Kelly Clark",
|
||||
"filename": "kellyclark"
|
||||
},
|
||||
{
|
||||
"displayname": "Maria Moraru",
|
||||
"filename": "mariamoraru"
|
||||
},
|
||||
{
|
||||
"displayname": "Carol Anthony",
|
||||
"filename": "carolanthony"
|
||||
},
|
||||
{
|
||||
"displayname": "Jerome Heckenkamp (Sk8)",
|
||||
"filename": "jeromeheckenkamp"
|
||||
},
|
||||
{
|
||||
"displayname": "Vijay Gill",
|
||||
"filename": "vijaygill"
|
||||
},
|
||||
{
|
||||
"displayname": "Roy Davis (Hack All Things)",
|
||||
"filename": "roydavis"
|
||||
},
|
||||
{
|
||||
"displayname": "Terry Leifeste (phliKtid)",
|
||||
"filename": "terryleifeste"
|
||||
},
|
||||
{
|
||||
"displayname": "Tim Skorick (Timmah)",
|
||||
"filename": "timskorick"
|
||||
},
|
||||
{
|
||||
"displayname": "Jason Snitker (Parmaster)",
|
||||
"filename": "jasonsnitker"
|
||||
},
|
||||
{
|
||||
"displayname": "Reverend Rat",
|
||||
"filename": "reverendrat"
|
||||
},
|
||||
{
|
||||
"displayname": "Chris (The Nightstalker)",
|
||||
"filename": "chrisnightstalker"
|
||||
},
|
||||
{
|
||||
"displayname": "AP Delchi",
|
||||
"filename": "apdelchi"
|
||||
|
|
|
|||
|
|
@ -1,32 +0,0 @@
|
|||
github:
|
||||
repo: restincode/restincode
|
||||
# Token will be read from GITHUB_TOKEN environment variable
|
||||
|
||||
archive:
|
||||
archive_org_enabled: true
|
||||
archive_today_enabled: true
|
||||
|
||||
processing:
|
||||
dry_run: false
|
||||
max_concurrent: 5
|
||||
|
||||
paths:
|
||||
people_dir: people
|
||||
images_dir: images
|
||||
peoplelist: peoplelist.json
|
||||
template: people/_template.json
|
||||
logs_dir: logs
|
||||
|
||||
priorities:
|
||||
# High-profile people to process first
|
||||
high_profile:
|
||||
- Kevin David Mitnick
|
||||
- Dan Kaminsky
|
||||
- Bram Moolenaar
|
||||
- Adrian Lamo
|
||||
- Kris Nova
|
||||
- Kelly Todd
|
||||
- Michael Park
|
||||
- Richard Batka
|
||||
- Chris Hurley
|
||||
- Ozzie Osband
|
||||
|
|
@ -1,514 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
RestInCode Issue Processing Automation
|
||||
|
||||
Processes GitHub Issues to create memorial JSON files and submit PRs.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import re
|
||||
import logging
|
||||
import subprocess
|
||||
import yaml
|
||||
import argparse
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
|
||||
|
||||
class IssueProcessor:
|
||||
"""Main class for processing GitHub Issues into memorial entries."""
|
||||
|
||||
def __init__(self, config_path: str = "scripts/config.yaml"):
|
||||
"""Initialize the processor with configuration."""
|
||||
self.load_config(config_path)
|
||||
self.setup_logging()
|
||||
self.repo_root = Path.cwd()
|
||||
|
||||
def load_config(self, config_path: str):
|
||||
"""Load configuration from YAML file."""
|
||||
with open(config_path, 'r') as f:
|
||||
self.config = yaml.safe_load(f)
|
||||
|
||||
def setup_logging(self):
|
||||
"""Configure logging to file and console."""
|
||||
log_dir = Path(self.config['paths']['logs_dir'])
|
||||
log_dir.mkdir(exist_ok=True)
|
||||
|
||||
log_file = log_dir / f"processing_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log"
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s - %(message)s',
|
||||
handlers=[
|
||||
logging.FileHandler(log_file),
|
||||
logging.StreamHandler(sys.stdout)
|
||||
]
|
||||
)
|
||||
self.logger = logging.getLogger(__name__)
|
||||
self.logger.info("Issue Processor initialized")
|
||||
|
||||
def fetch_issues(self, label: str) -> List[Dict]:
|
||||
"""
|
||||
Fetch issues from GitHub using gh CLI.
|
||||
|
||||
Args:
|
||||
label: Issue label to filter by ('Add Person' or 'Add Data')
|
||||
|
||||
Returns:
|
||||
List of issue dictionaries
|
||||
"""
|
||||
self.logger.info(f"Fetching issues with label: {label}")
|
||||
|
||||
cmd = [
|
||||
'gh', 'issue', 'list',
|
||||
'--repo', self.config['github']['repo'],
|
||||
'--label', label,
|
||||
'--limit', '100',
|
||||
'--json', 'number,title,body,author,comments,labels,url',
|
||||
'--state', 'open'
|
||||
]
|
||||
|
||||
try:
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
|
||||
issues = json.loads(result.stdout)
|
||||
self.logger.info(f"Fetched {len(issues)} issues with label '{label}'")
|
||||
return issues
|
||||
except subprocess.CalledProcessError as e:
|
||||
self.logger.error(f"Failed to fetch issues: {e}")
|
||||
return []
|
||||
|
||||
def fetch_issue_details(self, issue_number: int) -> Optional[Dict]:
|
||||
"""
|
||||
Fetch detailed issue information including comments.
|
||||
|
||||
Args:
|
||||
issue_number: GitHub issue number
|
||||
|
||||
Returns:
|
||||
Issue dictionary with full details
|
||||
"""
|
||||
self.logger.info(f"Fetching details for issue #{issue_number}")
|
||||
|
||||
cmd = [
|
||||
'gh', 'issue', 'view', str(issue_number),
|
||||
'--repo', self.config['github']['repo'],
|
||||
'--json', 'number,title,body,author,comments,labels,url'
|
||||
]
|
||||
|
||||
try:
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
|
||||
issue = json.loads(result.stdout)
|
||||
return issue
|
||||
except subprocess.CalledProcessError as e:
|
||||
self.logger.error(f"Failed to fetch issue #{issue_number}: {e}")
|
||||
return None
|
||||
|
||||
def parse_issue_template(self, issue_body: str) -> Dict[str, str]:
|
||||
"""
|
||||
Parse issue template to extract structured data.
|
||||
|
||||
Args:
|
||||
issue_body: Raw markdown body of the issue
|
||||
|
||||
Returns:
|
||||
Dictionary of extracted fields
|
||||
"""
|
||||
data = {}
|
||||
|
||||
if not issue_body:
|
||||
return data
|
||||
|
||||
# Define field patterns to extract (handle both - and * bullets)
|
||||
# Use [^\n\r]+ to match everything except newlines
|
||||
patterns = {
|
||||
'firstname': r'[*-]\s*First name:\s*([^\n\r]+)',
|
||||
'lastname': r'[*-]\s*Last name:\s*([^\n\r]+)',
|
||||
'handle': r'[*-]\s*Handle:\s*([^\n\r]+)',
|
||||
'birth': r'[*-]\s*Birth Year:\s*([^\n\r]+)',
|
||||
'death': r'[*-]\s*Death Year:\s*([^\n\r]+)',
|
||||
'obituary': r'[*-]\s*Link to Obituary:\s*([^\n\r]+)',
|
||||
'affiliations': r'[*-]\s*Group Affiliations:\s*([^\n\r]+)',
|
||||
'mainimage_url': r'[*-]\s*URL to main photo[^:]*:\s*([^\n\r]+)',
|
||||
'description': r'[*-]\s*Description of person[^:]*:\s*([^\n\r]+)',
|
||||
'twitter': r'[*-]\s*Twitter:\s*([^\n\r]+)',
|
||||
'github': r'[*-]\s*Github:\s*([^\n\r]+)',
|
||||
'linkedin': r'[*-]\s*LinkedIn:\s*([^\n\r]+)',
|
||||
'facebook': r'[*-]\s*Facebook:\s*([^\n\r]+)',
|
||||
'wikipedia': r'[*-]\s*Wikipedia:\s*([^\n\r]+)',
|
||||
'other_url': r'[*-]\s*Other:\s*([^\n\r]+)',
|
||||
}
|
||||
|
||||
for field, pattern in patterns.items():
|
||||
match = re.search(pattern, issue_body, re.IGNORECASE)
|
||||
if match:
|
||||
value = match.group(1).strip()
|
||||
# Clean up empty values and values that are just bullets
|
||||
if value and value not in ['', 'N/A', 'n/a', 'None', 'none'] and not value.startswith('*') and not value.startswith('-'):
|
||||
data[field] = value
|
||||
|
||||
# Extract contributions (can be multiple)
|
||||
contributions = []
|
||||
contrib_pattern = r'[*-]\s*Project name:\s*(.+?)[\n\r]+[*-]\s*Project URL:\s*(.+?)[\n\r]+[*-]\s*Project Description:\s*(.+?)(?=\n[*-]|\n\*\*|$)'
|
||||
for match in re.finditer(contrib_pattern, issue_body, re.IGNORECASE | re.DOTALL):
|
||||
title = match.group(1).strip()
|
||||
url = match.group(2).strip()
|
||||
desc = match.group(3).strip()
|
||||
if title and title not in ['', '[project name]']:
|
||||
contributions.append({'title': title, 'url': url, 'description': desc})
|
||||
if contributions:
|
||||
data['contributions'] = contributions
|
||||
|
||||
# Extract gallery URLs
|
||||
gallery_match = re.search(r'\*\*Photo Gallery\*\*.*?URL\(s\).*?:(.+?)(?=\n\*\*|$)', issue_body, re.IGNORECASE | re.DOTALL)
|
||||
if gallery_match:
|
||||
gallery_text = gallery_match.group(1)
|
||||
# Find all URLs in the gallery section
|
||||
url_pattern = r'https?://[^\s\)]+(?:\.jpg|\.jpeg|\.png|\.gif)?'
|
||||
gallery_urls = re.findall(url_pattern, gallery_text, re.IGNORECASE)
|
||||
if gallery_urls:
|
||||
data['gallery_urls'] = gallery_urls
|
||||
|
||||
return data
|
||||
|
||||
def normalize_filename(self, name: str, handle: str = None) -> str:
|
||||
"""
|
||||
Convert a person's name to a normalized filename.
|
||||
|
||||
Args:
|
||||
name: Person's full name
|
||||
handle: Optional handle/nickname
|
||||
|
||||
Returns:
|
||||
Normalized filename (lowercase, no spaces, no special chars)
|
||||
"""
|
||||
# Use handle if provided and seems better
|
||||
if handle:
|
||||
# Remove @ symbol if present
|
||||
handle = handle.lstrip('@')
|
||||
# If handle is simple (no spaces), prefer it
|
||||
if ' ' not in handle:
|
||||
base = handle
|
||||
else:
|
||||
base = name
|
||||
else:
|
||||
base = name
|
||||
|
||||
# Remove parenthetical nicknames
|
||||
base = re.sub(r'\([^)]*\)', '', base).strip()
|
||||
|
||||
# Convert to lowercase
|
||||
base = base.lower()
|
||||
|
||||
# Remove special characters, keep only alphanumeric
|
||||
base = re.sub(r'[^a-z0-9]+', '', base)
|
||||
|
||||
return base
|
||||
|
||||
def extract_person_data(self, issue: Dict) -> Dict:
|
||||
"""
|
||||
Extract and structure person data from issue.
|
||||
|
||||
Args:
|
||||
issue: GitHub issue dictionary
|
||||
|
||||
Returns:
|
||||
Structured person data dictionary
|
||||
"""
|
||||
self.logger.info(f"Extracting data from issue #{issue['number']}: {issue['title']}")
|
||||
|
||||
# Parse the issue body
|
||||
parsed_data = self.parse_issue_template(issue.get('body', ''))
|
||||
|
||||
# Also check comments for additional data
|
||||
for comment in issue.get('comments', []):
|
||||
comment_data = self.parse_issue_template(comment.get('body', ''))
|
||||
# Merge comment data (don't overwrite existing)
|
||||
for key, value in comment_data.items():
|
||||
if key not in parsed_data:
|
||||
parsed_data[key] = value
|
||||
|
||||
# Build person data structure
|
||||
person = {
|
||||
'issue_number': issue['number'],
|
||||
'issue_url': issue['url'],
|
||||
'firstname': parsed_data.get('firstname', ''),
|
||||
'lastname': parsed_data.get('lastname', ''),
|
||||
'handle': parsed_data.get('handle', ''),
|
||||
'birth': parsed_data.get('birth', ''),
|
||||
'death': parsed_data.get('death', ''),
|
||||
'obituary': parsed_data.get('obituary', ''),
|
||||
'affiliations': parsed_data.get('affiliations', ''),
|
||||
'description': parsed_data.get('description', ''),
|
||||
'mainimage_url': parsed_data.get('mainimage_url', ''),
|
||||
'socialmedialinks': [],
|
||||
'contributions': parsed_data.get('contributions', []),
|
||||
'gallery_urls': parsed_data.get('gallery_urls', []),
|
||||
}
|
||||
|
||||
# Build social media links
|
||||
social_mapping = {
|
||||
'Twitter': 'twitter',
|
||||
'Github': 'github',
|
||||
'LinkedIn': 'linkedin',
|
||||
'Facebook': 'facebook',
|
||||
'Wikipedia': 'wikipedia',
|
||||
'Website': 'other_url',
|
||||
}
|
||||
|
||||
for sitename, field in social_mapping.items():
|
||||
url = parsed_data.get(field, '')
|
||||
if url and url.startswith('http'):
|
||||
person['socialmedialinks'].append({'sitename': sitename, 'siteurl': url})
|
||||
|
||||
# Generate display name
|
||||
if person['firstname'] and person['lastname']:
|
||||
displayname = f"{person['firstname']} {person['lastname']}"
|
||||
elif person['firstname']:
|
||||
displayname = person['firstname']
|
||||
elif person['lastname']:
|
||||
displayname = person['lastname']
|
||||
elif person['handle']:
|
||||
displayname = person['handle']
|
||||
else:
|
||||
# Fall back to issue title
|
||||
displayname = issue['title']
|
||||
|
||||
# Add handle to display name if present
|
||||
if person['handle'] and person['handle'] not in displayname:
|
||||
displayname = f"{displayname} ({person['handle']})"
|
||||
|
||||
person['displayname'] = displayname
|
||||
|
||||
# Generate filename
|
||||
name_for_file = f"{person['firstname']} {person['lastname']}".strip()
|
||||
if not name_for_file:
|
||||
name_for_file = person['handle'] or displayname
|
||||
person['filename'] = self.normalize_filename(name_for_file, person['handle'])
|
||||
|
||||
return person
|
||||
|
||||
def generate_biography(self, person: Dict) -> str:
|
||||
"""
|
||||
Generate HTML biography from person data.
|
||||
|
||||
Args:
|
||||
person: Person data dictionary
|
||||
|
||||
Returns:
|
||||
HTML biography string
|
||||
"""
|
||||
bio = person.get('description', '')
|
||||
|
||||
if not bio:
|
||||
# Generate placeholder bio
|
||||
name = person.get('firstname', person.get('handle', 'This individual'))
|
||||
affiliation = person.get('affiliations', '')
|
||||
if affiliation:
|
||||
bio = f"{name} was an information security professional and {affiliation} member."
|
||||
else:
|
||||
bio = f"{name} was an information security professional."
|
||||
|
||||
# Wrap in paragraph tags
|
||||
if not bio.startswith('<p>'):
|
||||
bio = f"<p>{bio}</p>"
|
||||
|
||||
return bio
|
||||
|
||||
def generate_memorial_json(self, person: Dict) -> Dict:
|
||||
"""
|
||||
Generate memorial JSON structure from person data.
|
||||
|
||||
Args:
|
||||
person: Person data dictionary
|
||||
|
||||
Returns:
|
||||
Complete memorial JSON dictionary
|
||||
"""
|
||||
self.logger.info(f"Generating memorial JSON for {person['displayname']}")
|
||||
|
||||
# Read template
|
||||
template_path = self.repo_root / self.config['paths']['template']
|
||||
with open(template_path, 'r') as f:
|
||||
memorial = json.load(f)
|
||||
|
||||
# Populate fields
|
||||
memorial['firstname'] = person['firstname']
|
||||
memorial['lastname'] = person['lastname']
|
||||
memorial['handle'] = person['handle']
|
||||
memorial['birth'] = person['birth']
|
||||
memorial['death'] = person['death']
|
||||
memorial['obituary'] = person.get('obituary', '')
|
||||
memorial['issue'] = str(person['issue_number'])
|
||||
memorial['affiliations'] = person.get('affiliations', '')
|
||||
memorial['maintext'] = self.generate_biography(person)
|
||||
|
||||
# Social media links (only non-empty)
|
||||
memorial['socialmedialinks'] = [
|
||||
link for link in person['socialmedialinks']
|
||||
if link.get('siteurl')
|
||||
]
|
||||
|
||||
# Contributions (only non-empty)
|
||||
memorial['contributions'] = [
|
||||
contrib for contrib in person.get('contributions', [])
|
||||
if contrib.get('title')
|
||||
]
|
||||
|
||||
# Main image - will be set during image processing
|
||||
# For now, use default if no URL provided
|
||||
if person.get('mainimage_url'):
|
||||
memorial['mainimage'] = f"/images/{person['filename']}.jpg"
|
||||
else:
|
||||
memorial['mainimage'] = "/images/face-silhouette-clipart.png"
|
||||
|
||||
# Gallery - will be populated during image processing
|
||||
memorial['gallery'] = []
|
||||
|
||||
return memorial
|
||||
|
||||
def save_memorial_json(self, person: Dict, memorial: Dict, dry_run: bool = False) -> bool:
|
||||
"""
|
||||
Save memorial JSON to file.
|
||||
|
||||
Args:
|
||||
person: Person data dictionary
|
||||
memorial: Memorial JSON dictionary
|
||||
dry_run: If True, don't actually write file
|
||||
|
||||
Returns:
|
||||
True if successful
|
||||
"""
|
||||
filename = person['filename']
|
||||
json_path = self.repo_root / self.config['paths']['people_dir'] / f"{filename}.json"
|
||||
|
||||
if dry_run:
|
||||
self.logger.info(f"[DRY RUN] Would save memorial JSON to: {json_path}")
|
||||
self.logger.info(f"[DRY RUN] Content: {json.dumps(memorial, indent=2)}")
|
||||
return True
|
||||
|
||||
try:
|
||||
with open(json_path, 'w') as f:
|
||||
json.dump(memorial, f, indent=2, ensure_ascii=False)
|
||||
f.write('\n') # Ensure file ends with newline
|
||||
self.logger.info(f"Saved memorial JSON to: {json_path}")
|
||||
return True
|
||||
except Exception as e:
|
||||
self.logger.error(f"Failed to save memorial JSON: {e}")
|
||||
return False
|
||||
|
||||
def prioritize_issues(self, issues: List[Dict]) -> List[Dict]:
|
||||
"""
|
||||
Sort issues by priority (high-profile people first).
|
||||
|
||||
Args:
|
||||
issues: List of issue dictionaries
|
||||
|
||||
Returns:
|
||||
Sorted list of issues
|
||||
"""
|
||||
high_profile = self.config['priorities']['high_profile']
|
||||
|
||||
def get_priority(issue):
|
||||
title = issue['title']
|
||||
# Check if any high-profile name is in the title
|
||||
for idx, name in enumerate(high_profile):
|
||||
if name.lower() in title.lower():
|
||||
return idx # Lower number = higher priority
|
||||
return 999 # Low priority
|
||||
|
||||
sorted_issues = sorted(issues, key=get_priority)
|
||||
|
||||
self.logger.info(f"Prioritized {len(sorted_issues)} issues")
|
||||
for i, issue in enumerate(sorted_issues[:5]):
|
||||
self.logger.info(f" Priority {i+1}: #{issue['number']} - {issue['title']}")
|
||||
|
||||
return sorted_issues
|
||||
|
||||
def process_issue(self, issue_number: int, dry_run: bool = False) -> bool:
|
||||
"""
|
||||
Process a single issue end-to-end.
|
||||
|
||||
Args:
|
||||
issue_number: GitHub issue number
|
||||
dry_run: If True, don't make any file changes
|
||||
|
||||
Returns:
|
||||
True if successful
|
||||
"""
|
||||
self.logger.info(f"{'[DRY RUN] ' if dry_run else ''}Processing issue #{issue_number}")
|
||||
|
||||
# Fetch issue details
|
||||
issue = self.fetch_issue_details(issue_number)
|
||||
if not issue:
|
||||
return False
|
||||
|
||||
# Extract person data
|
||||
person = self.extract_person_data(issue)
|
||||
|
||||
# Validate minimum requirements
|
||||
if not person['filename']:
|
||||
self.logger.error(f"Cannot generate filename for issue #{issue_number}")
|
||||
return False
|
||||
if not person['death']:
|
||||
self.logger.warning(f"No death year for issue #{issue_number}")
|
||||
|
||||
# Generate memorial JSON
|
||||
memorial = self.generate_memorial_json(person)
|
||||
|
||||
# Save memorial JSON
|
||||
success = self.save_memorial_json(person, memorial, dry_run=dry_run)
|
||||
|
||||
return success
|
||||
|
||||
|
||||
def main():
|
||||
"""Main entry point."""
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Process RestInCode GitHub Issues to create memorials',
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter
|
||||
)
|
||||
parser.add_argument('--issue', type=int, help='Process specific issue number')
|
||||
parser.add_argument('--dry-run', action='store_true', default=True,
|
||||
help='Run without making any file changes (DEFAULT)')
|
||||
parser.add_argument('--live', action='store_true',
|
||||
help='Actually create files (disables dry-run)')
|
||||
args = parser.parse_args()
|
||||
|
||||
# Determine if this is a dry run
|
||||
dry_run = not args.live
|
||||
|
||||
processor = IssueProcessor()
|
||||
|
||||
# Show mode clearly
|
||||
mode = "DRY RUN MODE - NO CHANGES WILL BE MADE" if dry_run else "LIVE MODE - WILL CREATE FILES"
|
||||
processor.logger.info("=" * 60)
|
||||
processor.logger.info(f"MODE: {mode}")
|
||||
processor.logger.info("=" * 60)
|
||||
|
||||
if not dry_run:
|
||||
processor.logger.warning("LIVE mode enabled - files will be created!")
|
||||
response = input("Are you sure you want to continue? (yes/no): ")
|
||||
if response.lower() != 'yes':
|
||||
processor.logger.info("Aborted by user")
|
||||
return 0
|
||||
|
||||
# Default to test issue if none specified
|
||||
test_issue = args.issue or 197
|
||||
processor.logger.info(f"Processing issue #{test_issue}")
|
||||
|
||||
success = processor.process_issue(test_issue, dry_run=dry_run)
|
||||
|
||||
if success:
|
||||
processor.logger.info("Processing completed successfully")
|
||||
else:
|
||||
processor.logger.error("Processing failed")
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
PyYAML>=6.0
|
||||
Pillow>=10.0.0
|
||||
requests>=2.31.0
|
||||