epstein-files 1.0.15__tar.gz → 1.0.16__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. {epstein_files-1.0.15 → epstein_files-1.0.16}/PKG-INFO +1 -1
  2. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/documents/email.py +6 -2
  3. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/documents/messenger_log.py +1 -1
  4. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/epstein_files.py +1 -1
  5. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/util/constant/names.py +1 -0
  6. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/util/constant/urls.py +9 -0
  7. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/util/constants.py +14 -13
  8. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/util/highlighted_group.py +33 -29
  9. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/util/output.py +3 -5
  10. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/util/rich.py +17 -13
  11. {epstein_files-1.0.15 → epstein_files-1.0.16}/pyproject.toml +1 -1
  12. {epstein_files-1.0.15 → epstein_files-1.0.16}/LICENSE +0 -0
  13. {epstein_files-1.0.15 → epstein_files-1.0.16}/README.md +0 -0
  14. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/__init__.py +0 -0
  15. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/documents/communication.py +0 -0
  16. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/documents/document.py +0 -0
  17. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/documents/emails/email_header.py +0 -0
  18. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/documents/imessage/text_message.py +1 -1
  19. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/documents/json_file.py +0 -0
  20. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/documents/other_file.py +0 -0
  21. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/util/constant/common_words.py +0 -0
  22. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/util/constant/html.py +0 -0
  23. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/util/constant/output_files.py +0 -0
  24. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/util/constant/strings.py +0 -0
  25. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/util/data.py +0 -0
  26. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/util/doc_cfg.py +0 -0
  27. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/util/env.py +0 -0
  28. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/util/file_helper.py +0 -0
  29. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/util/logging.py +0 -0
  30. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/util/search_result.py +0 -0
  31. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/util/timer.py +0 -0
  32. {epstein_files-1.0.15 → epstein_files-1.0.16}/epstein_files/util/word_count.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: epstein-files
3
- Version: 1.0.15
3
+ Version: 1.0.16
4
4
  Summary: Tools for working with the Jeffrey Epstein documents released in November 2025.
5
5
  Home-page: https://michelcrypt4d4mus.github.io/epstein_text_messages/
6
6
  License: GPL-3.0-or-later
@@ -135,6 +135,7 @@ JUNK_EMAILERS = [
135
135
  ]
136
136
 
137
137
  MAILING_LISTS = [
138
+ CAROLYN_RANGEL,
138
139
  INTELLIGENCE_SQUARED,
139
140
  'middle.east.update@hotmail.com',
140
141
  JP_MORGAN_USGIO,
@@ -342,6 +343,9 @@ class Email(Communication):
342
343
  else:
343
344
  for recipient in self.header.recipients():
344
345
  self.recipients.extend(self._emailer_names(recipient))
346
+
347
+ if self.author in MAILING_LISTS and (len(self.recipients) == 0 or self.recipients == [self.author]):
348
+ self.recipients = [JEFFREY_EPSTEIN] # Assume mailing list emails are to Epstein
345
349
  except Exception as e:
346
350
  console.print_exception()
347
351
  console.line(2)
@@ -590,7 +594,7 @@ class Email(Communication):
590
594
  self._merge_lines(3) # Merge 4th and 5th rows
591
595
  elif self.file_id in '026609 029402 032405 022695'.split():
592
596
  self._merge_lines(4) # Merge 5th and 6th rows
593
- elif self.file_id in ['019407', '031980', '030384', '033144', '030999', '033575', '029835', '030381', '033357']:
597
+ elif self.file_id in ['019407', '031980', '030384', '033144', '030999', '033575', '029835', '030381', '033357', '026924']:
594
598
  self._merge_lines(2, 4)
595
599
  elif self.file_id in ['029154', '029163']:
596
600
  self._merge_lines(2, 5)
@@ -693,7 +697,7 @@ class Email(Communication):
693
697
  self.config.description = extracted_description
694
698
 
695
699
  self.config.is_interesting = self.config.is_interesting or extracted_from_doc_cfg.is_interesting
696
- self.warn(f"Constructed synthetic config: {self.config}")
700
+ self.log(f"Constructed synthetic config: {self.config}")
697
701
 
698
702
  def __rich_console__(self, console: Console, options: ConsoleOptions) -> RenderResult:
699
703
  logger.debug(f"Printing '{self.filename}'...")
@@ -12,7 +12,7 @@ from epstein_files.documents.communication import Communication
12
12
  from epstein_files.documents.imessage.text_message import TextMessage
13
13
  from epstein_files.util.constant.names import JEFFREY_EPSTEIN, UNKNOWN
14
14
  from epstein_files.util.constant.strings import AUTHOR, TIMESTAMP_STYLE
15
- from epstein_files.util.data import days_between, days_between_str, iso_timestamp, listify, sort_dict
15
+ from epstein_files.util.data import days_between, days_between_str, iso_timestamp, sort_dict
16
16
  from epstein_files.util.doc_cfg import Metadata, TextCfg
17
17
  from epstein_files.util.highlighted_group import get_style_for_name
18
18
  from epstein_files.util.logging import logger
@@ -29,7 +29,7 @@ from epstein_files.util.env import DOCS_DIR, args, logger
29
29
  from epstein_files.util.file_helper import file_size_str
30
30
  from epstein_files.util.highlighted_group import HIGHLIGHTED_NAMES, HighlightedNames, get_info_for_name, get_style_for_name
31
31
  from epstein_files.util.rich import (DEFAULT_NAME_STYLE, LAST_TIMESTAMP_STYLE, NA_TXT, add_cols_to_table,
32
- print_all_files_page_link, build_table, console, highlighter, link_text_obj, link_markup, print_author_header, print_centered,
32
+ print_other_page_link, build_table, console, highlighter, link_text_obj, link_markup, print_author_header, print_centered,
33
33
  print_panel, print_section_header, vertically_pad)
34
34
  from epstein_files.util.search_result import SearchResult
35
35
  from epstein_files.util.timer import Timer
@@ -38,6 +38,7 @@ BRAD_EDWARDS = 'Brad Edwards'
38
38
  BRAD_KARP = 'Brad Karp'
39
39
  BRAD_WECHSLER = 'Brad Wechsler'
40
40
  BORIS_NIKOLIC = 'Boris Nikolic'
41
+ CAROLYN_RANGEL = 'Carolyn Rangel'
41
42
  CECILE_DE_JONGH = 'Cecile de Jongh'
42
43
  CECILIA_STEEN = 'Cecilia Steen'
43
44
  CELINA_DUBIN = 'Celina Dubin'
@@ -6,6 +6,7 @@ from inflection import parameterize
6
6
  from rich.text import Text
7
7
 
8
8
  from epstein_files.util.constant.output_files import *
9
+ from epstein_files.util.env import args
9
10
  from epstein_files.util.file_helper import coerce_file_stem
10
11
 
11
12
  # Style stuff
@@ -101,4 +102,12 @@ def link_text_obj(url: str, link_text: str | None = None, style: str = ARCHIVE_L
101
102
  return Text.from_markup(link_markup(url, link_text, style))
102
103
 
103
104
 
105
+ def other_site_type() -> SiteType:
106
+ return TEXT_MESSAGE if args.all_emails else EMAIL
107
+
108
+
109
+ def other_site_url() -> str:
110
+ return SITE_URLS[other_site_type()]
111
+
112
+
104
113
  CRYPTADAMUS_TWITTER = link_markup('https://x.com/cryptadamist', '@cryptadamist')
@@ -198,7 +198,7 @@ EMAILERS = [
198
198
  'Vladimir Yudashkin',
199
199
  ]
200
200
 
201
- EMAILER_REGEXES = deepcopy(EMAILER_ID_REGEXES)
201
+ EMAILER_REGEXES = deepcopy(EMAILER_ID_REGEXES) # Keep a copy without the simple EMAILERS regexes
202
202
 
203
203
  # Add simple matching regexes for EMAILERS entries to EMAILER_REGEXES
204
204
  for emailer in EMAILERS:
@@ -536,6 +536,7 @@ EMAILS_CONFIG = [
536
536
  EmailCfg(id='033274', recipients=[JEFFREY_EPSTEIN]), # this is a note sent to self
537
537
  EmailCfg(id='032780', recipients=[JEFFREY_EPSTEIN]), # Bad OCR (nofix)
538
538
  EmailCfg(id='029324', recipients=[JEFFREY_EPSTEIN, "Jojo Fontanilla", "Lyn Fontanilla"]), # Bad OCR (nofix)
539
+ EmailCfg(id='013482', recipients=[JEFFREY_EPSTEIN], is_fwded_article=True), # other recipients redacted. "The view from the US: Stem cell therapy steps up a gear with firs"
539
540
  EmailCfg(id='033456', recipients=["Joel"], attribution_reason='Reply'),
540
541
  EmailCfg(id='033458', recipients=["Joel"], attribution_reason='Reply'),
541
542
  EmailCfg(id='033460', recipients=["Joel"], attribution_reason='Reply'),
@@ -626,7 +627,6 @@ EMAILS_CONFIG = [
626
627
  EmailCfg(id='021740', is_fwded_article=True), # Miami Herald article about Epstein prosecutor
627
628
  EmailCfg(id='023126', is_fwded_article=True), # Miami Herald on Alex Acosta
628
629
  EmailCfg(id='029625', is_fwded_article=True), # Conchita Sarnoff Daily Beast Articles - Epstein Sex Trafficking Investigation and Settlement
629
- EmailCfg(id='013482', is_fwded_article=True), # The view from the US: Stem cell therapy steps up a gear with firs
630
630
  EmailCfg(id='029505', is_fwded_article=True), # Foreign Policy Middle Eastern Monarchs Look at the Trump
631
631
  EmailCfg(id='029859', is_fwded_article=True), # Palm Beach Post: Epstein paid three women $5.5 million to end lawsuits
632
632
  EmailCfg(id='031988', is_fwded_article=True), # NYT review of Inside Job
@@ -1005,7 +1005,7 @@ OTHER_FILES_ARTICLES = [
1005
1005
  DocCfg(id='023046', author=VI_DAILY_NEWS, description='article', date='2019-02-27'),
1006
1006
  DocCfg(id='031170', author=VI_DAILY_NEWS, description='article', date='2019-03-06'),
1007
1007
  DocCfg(id='016506', author=VI_DAILY_NEWS, description='article', date='2019-02-28'),
1008
- DocCfg(id='016507', author=VI_DAILY_NEWS, description=f"'Perversion of Justice' by {JULIE_K_BROWN}", date='2018-12-19'),
1008
+ DocCfg(id='016507', author=VI_DAILY_NEWS, description=f'"Perversion of Justice" by {JULIE_K_BROWN}', date='2018-12-19'),
1009
1009
  DocCfg(id='019212', author=WAPO, description=f'and Times Tribune articles about Bannon, Trump, and healthcare execs'),
1010
1010
  DocCfg(id='033379', author=WAPO, description=f'"How Washington Pivoted From Finger-Wagging to Appeasement" (about Viktor Orban)', date='2018-05-25'),
1011
1011
  DocCfg(
@@ -1020,12 +1020,12 @@ OTHER_FILES_ARTICLES = [
1020
1020
  DocCfg(id='026648', description=f'article about {JASTA} lawsuit against Saudi Arabia by 9/11 victims (Russian propaganda?)', date='2017-05-13'),
1021
1021
  DocCfg(id='032159', description=f"article about microfinance and cell phones in Zimbabwe, Strive Masiyiwa (Econet Wireless)"),
1022
1022
  DocCfg(id='030825', description=f'{ARTICLE_DRAFT} Syria'),
1023
- DocCfg(id='027051', description=f"German language article about the 2013 Lifeball / AIDS Gala", date='2013-01-01'),
1023
+ DocCfg(id='027051', description=f"German article about the 2013 Lifeball / AIDS Gala", date='2013-01-01', attached_to_email_id='027049'),
1024
1024
  DocCfg(id='033480', description=f"John Bolton press clipping", date='2018-04-06', duplicate_ids=['033481']),
1025
1025
  DocCfg(id='013403', description=f"{LEXIS_NEXIS} result from The Evening Standard about Bernie Madoff", date='2009-12-24'),
1026
1026
  DocCfg(id='021093', description=f"page of unknown article about Epstein and Maxwell"),
1027
1027
  DocCfg(id='031191', description=f"single page of unknown article about Epstein and Trump's relationship in 1997"),
1028
- DocCfg(id='026520', description=f'Spanish language article about {SULTAN_BIN_SULAYEM}', date='2013-09-27'),
1028
+ DocCfg(id='026520', description=f'Spanish article about {SULTAN_BIN_SULAYEM}', date='2013-09-27'),
1029
1029
  DocCfg(
1030
1030
  id='031736',
1031
1031
  description=f"{TRANSLATION} Arabic article by Abdulnaser Salamah 'Trump; Prince of Believers (Caliph)!'",
@@ -1418,7 +1418,7 @@ OTHER_FILES_POLITICS = [
1418
1418
  DocCfg(
1419
1419
  id='025849',
1420
1420
  author='US Office of Government Information Services',
1421
- description=f"Building a Bridge Between FOIA Requesters & Agencies",
1421
+ description=f'"Building a Bridge Between FOIA Requesters & Agencies"',
1422
1422
  ),
1423
1423
  DocCfg(id='031670', description=f"letter from General Mike Flynn's lawyers to senators Mark Warner & Richard Burr about subpoena"),
1424
1424
  DocCfg(
@@ -1496,6 +1496,13 @@ OTHER_FILES_RESUMES = [
1496
1496
  OTHER_FILES_ARTS = [
1497
1497
  DocCfg(id='018703', author=ANDRES_SERRANO, description=f"artist statement about Trump objects"),
1498
1498
  DocCfg(id='023438', author=BROCKMAN_INC, description=f"announcement of auction of 'Noise' by Daniel Kahneman, Olivier Sibony, and Cass Sunstein"),
1499
+ DocCfg(
1500
+ id='025147',
1501
+ author=BROCKMAN_INC,
1502
+ description=f'hot list Frankfurt Book Fair (includes article about Silk Road/Ross Ulbricht)',
1503
+ date='2016-10-23',
1504
+ is_interesting=True,
1505
+ ),
1499
1506
  DocCfg(id='030769', author='Independent Filmmaker Project (IFP)', description=f"2017 Gotham Awards invitation"),
1500
1507
  DocCfg(
1501
1508
  id='025205',
@@ -1520,12 +1527,6 @@ OTHER_FILES_MISC = [
1520
1527
  author=f'linkspirit (French?) and {LAWRENCE_KRAUSS}',
1521
1528
  is_interesting=True, # we don't know who linkspirit is yet
1522
1529
  ),
1523
- DocCfg(
1524
- id='025147',
1525
- author=BROCKMAN_INC,
1526
- description=f'hot list Frankfurt Book Fair (includes article about Silk Road/Ross Ulbricht)',
1527
- date='2016-10-23',
1528
- ),
1529
1530
  DocCfg(id='022494', author='DOJ', description=f'Foreign Corrupt Practices Act (FCPA) Resource Guide'),
1530
1531
  DocCfg(id='023096', author=EPSTEIN_FOUNDATION, description=f'blog post', date='2012-11-15'),
1531
1532
  DocCfg(id='029326', author=EPSTEIN_FOUNDATION, description=f'{PRESS_RELEASE}', date='2013-02-15'),
@@ -1533,7 +1534,7 @@ OTHER_FILES_MISC = [
1533
1534
  DocCfg(id='027071', author=FEMALE_HEALTH_COMPANY, description=f"brochure requesting donations for female condoms in Uganda"),
1534
1535
  DocCfg(id='027074', author=FEMALE_HEALTH_COMPANY, description=f"pitch deck (USAID was a customer)"),
1535
1536
  DocCfg(id='032735', author=GORDON_GETTY, description=f"on Trump", date='2018-03-20'), # Dated based on concurrent emails from Getty
1536
- DocCfg(id='025540', author=JEFFREY_EPSTEIN, description=f"rough draft of Epstein's side of the story?"),
1537
+ DocCfg(id='025540', author=JEFFREY_EPSTEIN, description=f"rough draft of his side of the story"),
1537
1538
  DocCfg(id='026634', author='Michael Carrier', description=f"comments about an Apollo linked hedge fund 'DE Fund VIII'"),
1538
1539
  DocCfg(id='031425', author=SCOTT_J_LINK, description=f'completely redacted email from', is_interesting=False),
1539
1540
  DocCfg(id='020447', author='Working Group on Chinese Influence Activities in the U.S.', description=f'Promoting Constructive Vigilance'),
@@ -15,7 +15,7 @@ from epstein_files.util.data import extract_last_name, listify, without_falsey
15
15
  CIVIL_ATTORNEY = 'civil attorney'
16
16
  CRIMINAL_DEFENSE_ATTORNEY = 'criminal defense attorney'
17
17
  CRIMINAL_DEFENSE_2008 = f"{CRIMINAL_DEFENSE_ATTORNEY} on 2008 case"
18
- EPSTEIN_LAWYER = 'epstein_lawyer'
18
+ EPSTEIN_LAWYER = 'Epstein lawyer'
19
19
  EPSTEIN_V_ROTHSTEIN_EDWARDS_ATTORNEY = f"{CIVIL_ATTORNEY} working on {EPSTEIN_V_ROTHSTEIN_EDWARDS}"
20
20
  ESTATE_EXECUTOR = 'estate executor'
21
21
  EPSTEIN_ESTATE_EXECUTOR = f"Epstein {ESTATE_EXECUTOR}"
@@ -103,7 +103,7 @@ class HighlightedNames(HighlightedText):
103
103
  def get_info(self, name: str) -> str | None:
104
104
  """Label and additional info for 'name' if 'name' is in self.emailers."""
105
105
  info_pieces = [
106
- None if len(self.emailers) == 1 else (self.category or self.label.title()),
106
+ None if len(self.emailers) == 1 else (self.category or self.label.replace('_', ' ')),
107
107
  self.emailers.get(name),
108
108
  ]
109
109
 
@@ -111,7 +111,7 @@ class HighlightedNames(HighlightedText):
111
111
  return ', '.join(info_pieces) if info_pieces else None
112
112
 
113
113
  def _emailer_pattern(self, name: str) -> str:
114
- """Pattern matching 'name'. Extends value in EMAILER_ID_REGEXES with last name if it exists."""
114
+ """Pattern matching 'name'. Extends value in EMAILER_ID_REGEXES with first/last name if it exists."""
115
115
  name = remove_question_marks(name)
116
116
  last_name = extract_last_name(name)
117
117
  first_name = name.removesuffix(f" {last_name}")
@@ -141,7 +141,7 @@ class HighlightedNames(HighlightedText):
141
141
 
142
142
  HIGHLIGHTED_NAMES = [
143
143
  HighlightedNames(
144
- label='africa',
144
+ label='Africa',
145
145
  style='light_pink4',
146
146
  pattern=r'Econet(\s*Wireless)|Ghana(ian)?|Johannesburg|Kenya|Nigerian?|Senegal(ese)?|Serengeti|(South\s*)?African?|(Strive\s*)?Masiyiwa|Tanzania|Ugandan?|Zimbabwe(an)?',
147
147
  emailers={
@@ -183,12 +183,15 @@ HIGHLIGHTED_NAMES = [
183
183
  pattern=r"CBD|cannabis|marijuana|THC|WEED(guide|maps)?[^s]?",
184
184
  ),
185
185
  HighlightedNames(
186
- label='china',
186
+ label='China',
187
187
  style='bright_red',
188
- pattern=r"Ali.?baba|Beijing|CCP|Chin(a|e?se)(?! Daily)|DPRK|Gino\s+Yu|Global Times|Guo|Hong|Huaw[ae]i|Kim\s*Jong\s*Un|Kong|Jack\s+Ma|Kwok|Ministry\sof\sState\sSecurity|Mongolian?|MSS|North\s*Korea|Peking|PRC|SCMP|Tai(pei|wan)|Xi(aomi)?|Jinping",
188
+ pattern=r"Ali.?baba|Beijing|CCP|Chin(a|e?se)(?! Daily)|DPRK|Global Times|Guo|Hong|Huaw[ae]i|Kim\s*Jong\s*Un|Kong|Jack\s+Ma|Kwok|Ministry\sof\sState\sSecurity|Mongolian?|MSS|North\s*Korea|Peking|PRC|SCMP|Tai(pei|wan)|Xi(aomi)?|Jinping",
189
+ emailers={
190
+ 'Gino Yu': 'professor / game designer in Hong Kong',
191
+ }
189
192
  ),
190
193
  HighlightedNames(
191
- label='deepak_chopra',
194
+ label='Deepak Chopra',
192
195
  style='dark_sea_green4',
193
196
  emailers = {
194
197
  'Carolyn Rangel': 'assistant',
@@ -196,7 +199,7 @@ HIGHLIGHTED_NAMES = [
196
199
  }
197
200
  ),
198
201
  HighlightedNames(
199
- label='democrats',
202
+ label='Democrats',
200
203
  style='sky_blue1',
201
204
  pattern=r'(Al\s*)?Franken|((Bill|Hillart?y)\s*)?Clinton|((Chuck|Charles)\s*)?S(ch|hc)umer|(Diana\s*)?DeGette|DNC|Elena\s*Kagan|(Eliott?\s*)?Spitzer(, Eliot)?|George\s*Mitchell|(George\s*)?Soros|Hill?ary|Dem(ocrat(ic)?)?|(Jo(e|seph)\s*)?Biden|(John\s*)?Kerry|Lisa Monaco|(Matteo\s*)?Salvini|Maxine\s*Waters|(Barac?k )?Obama|(Nancy )?Pelosi|Ron\s*Dellums|Schumer|(Tim\s*)?Geithner|Vernon\s*Jordan',
202
205
  ),
@@ -271,7 +274,7 @@ HIGHLIGHTED_NAMES = [
271
274
  HighlightedNames(
272
275
  label=ESTATE_EXECUTOR,
273
276
  style='purple3 bold',
274
- category='epstein lawyer',
277
+ category='Epstein lawyer',
275
278
  emailers = {
276
279
  DARREN_INDYKE: EPSTEIN_ESTATE_EXECUTOR,
277
280
  RICHARD_KAHN: EPSTEIN_ESTATE_EXECUTOR,
@@ -280,7 +283,7 @@ HIGHLIGHTED_NAMES = [
280
283
  HighlightedNames(
281
284
  label='europe',
282
285
  style='light_sky_blue3',
283
- pattern=r'(Angela )?Merk(el|le)|Austria|(Benjamin\s*)?Harnwell|Berlin|Borge|Boris\s*Johnson|Brexit(eers?)?|Brit(ain|ish)|Brussels|Cannes|(Caroline|Jack)?\s*Lang(, Caroline)?|Cypr(iot|us)|Davos|ECB|England|EU|Europe(an)?(\s*Union)?|Fr(ance|ench)|Geneva|Germany?|Gillard|Gree(ce|k)|Ital(ian|y)|Jacques|(Kevin\s*)?Rudd|Le\s*Pen|London|Macron|Melusine|Munich|(Natalia\s*)?Veselnitskaya|(Nicholas\s*)?Sarkozy|Nigel(\s*Farage)?|Norw(ay|egian)|Oslo|Paris|Polish|(Sebastian )?Kurz|(Vi(c|k)tor\s+)?Orbah?n|Edward Rod Larsen|Strasbourg|Strauss[- ]?Kahn|Swed(en|ish)(?![-\s]+America)|Switzerland|(Tony\s)?Blair|U\.?K\.?|Ukrain(e|ian)|Vienna|(Vitaly\s*)?Churkin|Zug',
286
+ pattern=r'(Angela )?Merk(el|le)|Austria|(Benjamin\s*)?Harnwell|Berlin|Borge|Boris\s*Johnson|Brexit(eers?)?|Brit(ain|ish)|Brussels|Cannes|(Caroline|Jack)?\s*Lang(, Caroline)?|Cypr(iot|us)|Davos|ECB|England|EU|Europe(an)?(\s*Union)?|Fr(ance|ench)|Geneva|Germany?|Gillard|Gree(ce|k)|Ital(ian|y)|Jacques|(Kevin\s*)?Rudd|Le\s*Pen|London|Macron|Melusine|Munich|(Natalia\s*)?Veselnitskaya|(Nicholas\s*)?Sarkozy|Nigel(\s*Farage)?|Norw(ay|egian)|Oslo|Paris|Polish|pope|(Sebastian )?Kurz|(Vi(c|k)tor\s+)?Orbah?n|Edward Rod Larsen|Strasbourg|Strauss[- ]?Kahn|Swed(en|ish)(?![-\s]+America)|Switzerland|(Tony\s)?Blair|U\.?K\.?|Ukrain(e|ian)|Vienna|(Vitaly\s*)?Churkin|Zug',
284
287
  emailers = {
285
288
  ANDRZEJ_DUDA: 'former president of Poland',
286
289
  MIROSLAV_LAJCAK: 'Russia-friendly Slovakian politician, friend of Steve Bannon',
@@ -290,9 +293,8 @@ HIGHLIGHTED_NAMES = [
290
293
  }
291
294
  ),
292
295
  HighlightedNames(
293
- label='famous_lawyer',
296
+ label='famous lawyer',
294
297
  style='medium_purple3',
295
- category='famous_lawyer',
296
298
  pattern=r'(David\s*)?Bo[il]es|dersh|(Gloria\s*)?Allred|(Mi(chael|ke)\s*)?Avenatti',
297
299
  emailers = {
298
300
  ALAN_DERSHOWITZ: 'Harvard Law School professor and all around (in)famous American lawyer',
@@ -316,7 +318,8 @@ HIGHLIGHTED_NAMES = [
316
318
  MELANIE_SPINELLA: f'representative of {LEON_BLACK}',
317
319
  MORTIMER_ZUCKERMAN: 'business partner of Epstein',
318
320
  PAUL_BARRETT: None,
319
- PAUL_MORRIS: 'Deutsche Bank',
321
+ PAUL_MORRIS: DEUTSCHE_BANK,
322
+ 'Steven Elkman': DEUTSCHE_BANK,
320
323
  }
321
324
  ),
322
325
  HighlightedNames(
@@ -334,7 +337,7 @@ HIGHLIGHTED_NAMES = [
334
337
  },
335
338
  ),
336
339
  HighlightedNames(
337
- label=HARVARD.lower(),
340
+ label=HARVARD,
338
341
  style='light_goldenrod3',
339
342
  pattern=r'Cambridge|(Derek\s*)?Bok|Elisa(\s*New)?|Harvard(\s*(Business|Law|University)(\s*School)?)?|(Jonathan\s*)?Zittrain|(Stephen\s*)?Kosslyn',
340
343
  emailers = {
@@ -349,7 +352,7 @@ HIGHLIGHTED_NAMES = [
349
352
  }
350
353
  ),
351
354
  HighlightedNames(
352
- label='india',
355
+ label='India',
353
356
  style='bright_green',
354
357
  pattern=r'Abraaj|Anna\s*Hazare|(Arif\s*)?Naqvi|(Arvind\s*)?Kejriwal|Hardeep( Pur[ei]e)?|Indian?|InsightsPod|Modi|Mumbai|Tranchulas',
355
358
  emailers = {
@@ -359,7 +362,7 @@ HIGHLIGHTED_NAMES = [
359
362
  }
360
363
  ),
361
364
  HighlightedNames(
362
- label='israel',
365
+ label='Israel',
363
366
  style='dodger_blue2',
364
367
  pattern=r"AIPAC|Bibi|(eh|(Ehud|Nili Priell) )?barak|Ehud\s*Barack|Israeli?|Jerusalem|J\s*Street|Mossad|Netanyahu|(Sheldon\s*)?Adelson|Tel\s*Aviv|(The\s*)?Shimon\s*Post|Yitzhak|Rabin|YIVO|zionist",
365
368
  emailers={
@@ -369,7 +372,7 @@ HIGHLIGHTED_NAMES = [
369
372
  }
370
373
  ),
371
374
  HighlightedNames(
372
- label='japan',
375
+ label='Japan',
373
376
  style='color(168)',
374
377
  pattern=r'BOJ|(Bank\s+of\s+)?Japan(ese)?|jpy?(?! Morgan)|SG|Singapore|Toky[op]',
375
378
  ),
@@ -389,7 +392,7 @@ HIGHLIGHTED_NAMES = [
389
392
  }
390
393
  ),
391
394
  HighlightedNames(
392
- label='latin america',
395
+ label='Latin America',
393
396
  style='yellow',
394
397
  pattern=r'Argentin(a|ian)|Bolsonar[aio]|Bra[sz]il(ian)?|Bukele|Caracas|Castro|Colombian?|Cuban?|El\s*Salvador|((Enrique )?Pena )?Nieto|LatAm|Lula|Mexic(an|o)|(Nicolas\s+)?Maduro|Panama( Papers)?|Peru|Venezuelan?|Zambrano',
395
398
  ),
@@ -419,8 +422,8 @@ HIGHLIGHTED_NAMES = [
419
422
  HighlightedNames(
420
423
  label='mideast',
421
424
  style='dark_sea_green4',
422
- # this won't match ever because of word boundary: [-\s]9/11[\s.]
423
- pattern=r"Abdulmalik Al-Makhlafi|Abdullah|Abu\s+Dhabi|Afghanistan|Al[-\s]?Qa[ei]da|Ahmadinejad|Arab|Aramco|Assad|Bahrain|Basiji?|Benghazi|Cairo|Chagoury|Dj[iu]bo?uti|Doha|Dubai|Egypt(ian)?|Emir(at(es?|i))?|Erdogan|Fashi|Gaddafi|(Hamid\s*)?Karzai|Hamad\s*bin\s*Jassim|HBJ|Houthi|Imran\s+Khan|Iran(ian)?|Isi[ls]|Islam(abad|ic|ist)?|Istanbul|Kh?ashoggi|(Kairat\s*)?Kelimbetov|kasshohgi|Kaz(akh|ich)stan|Kazakh?|Kh[ao]menei|Khalid\s*Sheikh\s*Mohammed|KSA|Leban(ese|on)|Libyan?|Mahmoud|Marra[hk]e[cs]h|MB(N|S|Z)|Mohammed\s+bin\s+Salman|Morocco|Mubarak|Muslim|Nayaf|Pakistani?|Omar|(Osama\s*)?Bin\s*Laden|Osama(?! al)|Palestin(e|ian)|Persian?|Riya(dh|nd)|Saddam|Salman|Saudi(\s+Arabian?)?|Shariah?|SHC|sheikh|shia|(Sultan\s*)?Yacoub|Syrian?|(Tarek\s*)?El\s*Sayed|Tehran|Tunisian?|Turk(ey|ish)|UAE|((Iraq|Iran|Kuwait|Qatar|Yemen)i?)",
425
+ # something like this won't match ever because of word boundary: [-\s]9/11[\s.]
426
+ pattern=r"Abdulmalik Al-Makhlafi|Abdullah|Abu\s+Dhabi|Afghanistan|Al[-\s]?Qa[ei]da|Ahmadinejad|Arab|Aramco|Assad|Bahrain|Basiji?|Benghazi|Cairo|Chagoury|Dj[iu]bo?uti|Doha|Dubai|Egypt(ian)?|Emir(at(es?|i))?|Erdogan|Fashi|Gaddafi|(Hamid\s*)?Karzai|Hamad\s*bin\s*Jassim|HBJ|Houthi|Imran\s+Khan|Iran(ian)?|Isi[ls]|Islam(abad|ic|ist)?|Istanbul|Kh?ashoggi|(Kairat\s*)?Kelimbetov|kasshohgi|Kaz(akh|ich)stan|Kazakh?|Kh[ao]menei|Khalid\s*Sheikh\s*Mohammed|KSA|Leban(ese|on)|Libyan?|Mahmoud|Marra[hk]e[cs]h|MB(N|S|Z)|Mid(dle)?\s*East|Mohammed\s+bin\s+Salman|Morocco|Mubarak|Muslim|Nayaf|Pakistani?|Omar|(Osama\s*)?Bin\s*Laden|Osama(?! al)|Palestin(e|ian)|Persian?|Riya(dh|nd)|Saddam|Salman|Saudi(\s+Arabian?)?|Shariah?|SHC|sheikh|shia|(Sultan\s*)?Yacoub|Syrian?|(Tarek\s*)?El\s*Sayed|Tehran|Tunisian?|Turk(ey|ish)|UAE|((Iraq|Iran|Kuwait|Qatar|Yemen)i?)",
424
427
  emailers = {
425
428
  ANAS_ALRASHEED: f'former information minister of Kuwait {QUESTION_MARKS}',
426
429
  AZIZA_ALAHMADI: 'Abu Dhabi Department of Culture & Tourism',
@@ -463,7 +466,7 @@ HIGHLIGHTED_NAMES = [
463
466
  }
464
467
  ),
465
468
  HighlightedNames(
466
- label='republicans',
469
+ label='Republicans',
467
470
  style='bold dark_red',
468
471
  pattern=r'Alberto\sGonzale[sz]|(Alex\s*)?Acosta|(Bill\s*)?Barr|Bill\s*Shine|(Bob\s*)?Corker|(John\s*(R.?\s*)?)Bolton|Broidy|(Chris\s)?Christie|Devin\s*Nunes|(Don\s*)?McGa[hn]n|McMaster|(George\s*)?Nader|GOP|(Brett\s*)?Kavanaugh|Kissinger|Kobach|Koch\s*Brothers|Kolfage|Kudlow|Lewandowski|(Marco\s)?Rubio|(Mark\s*)Meadows|Mattis|McCain|(?<!Merwin Dela )Cruz|(Michael\s)?Hayden|((General|Mike)\s*)?(Flynn|Pence)|(Mitt\s*)?Romney|Mnuchin|Nikki|Haley|(Paul\s+)?(Manafort|Volcker)|(Peter\s)?Navarro|Pompeo|Reagan|Reince|Priebus|Republican|(Rex\s*)?Tillerson|(?<!Cynthia )(Richard\s*)?Nixon|Sasse|Tea\s*Party',
469
472
  # There's no emails from these people, they're just here to automate the regex creation for both first + last names
@@ -481,7 +484,7 @@ HIGHLIGHTED_NAMES = [
481
484
  },
482
485
  ),
483
486
  HighlightedNames(
484
- label='russia',
487
+ label='Russia',
485
488
  style='red bold',
486
489
  pattern=r'Alfa\s*Bank|Anya\s*Rasulova|Chernobyl|Day\s+One\s+Ventures|(Dmitry\s)?(Kiselyov|(Lana\s*)?Pozhidaeva|Medvedev|Rybolo(o?l?ev|vlev))|Dmitry|FSB|GRU|KGB|Kislyak|Kremlin|Kuznetsova|Lavrov|Lukoil|Moscow|(Oleg\s*)?Deripaska|Oleksandr Vilkul|Rosneft|RT|St.?\s*?Petersburg|Russian?|Sberbank|Soviet(\s*Union)?|USSR|Vladimir|(Vladimir\s*)?(Putin|Yudashkin)|Women\s*Empowerment|Xitrans',
487
490
  emailers = {
@@ -511,7 +514,7 @@ HIGHLIGHTED_NAMES = [
511
514
  },
512
515
  ),
513
516
  HighlightedNames(
514
- label='southeast_asia',
517
+ label='southeast Asia',
515
518
  style='light_salmon3 bold',
516
519
  pattern=r'Bangkok|Burm(a|ese)|Cambodian?|Laos|Malaysian?|Myan?mar|Thai(land)?|Vietnam(ese)?',
517
520
  ),
@@ -541,7 +544,7 @@ HIGHLIGHTED_NAMES = [
541
544
  pattern=r'BVI|(Jane|Tiffany)\s*Doe|Katie\s*Johnson|(Virginia\s+((L\.?|Roberts)\s+)?)?Giuffre|Virginia\s+Roberts',
542
545
  ),
543
546
  HighlightedNames(
544
- label='victim_lawyer',
547
+ label='victim lawyer',
545
548
  style='dark_magenta bold',
546
549
  pattern=r'(Alan(\s*P.)?|MINTZ)\s*FRAADE|Paul\s*(G.\s*)?Cassell|Rothstein\s*Rosenfeldt\s*Adler|(Scott\s*)?Rothstein|(J\.?\s*)?(Stan(ley)?\s*)?Pottinger',
547
550
  emailers = {
@@ -554,7 +557,7 @@ HIGHLIGHTED_NAMES = [
554
557
  style='sea_green1',
555
558
  pattern=r'Antigua|Bahamas|Caribb?ean|Dominican\s*Republic|(Great|Little)\s*St.?\s*James|Haiti(an)?|(John\s*)deJongh(\s*Jr\.?)|(Kenneth E\. )?Mapp|Palm\s*Beach(?!\s*Post)|PBI|S(ain)?t.?\s*Thomas|USVI|(?<!Epstein )VI|(The\s*)?Virgin\s*Islands(\s*Daily\s*News)?', # TODO: VI Daily News should be yellow but it's hard bc Daily News xists
556
559
  emailers = {
557
- CECILE_DE_JONGH: f'First lady 2007-2015',
560
+ CECILE_DE_JONGH: f'first lady 2007-2015',
558
561
  STACEY_PLASKETT: 'non-voting member of Congress',
559
562
  KENNETH_E_MAPP: 'Governor',
560
563
  },
@@ -573,6 +576,9 @@ HIGHLIGHTED_NAMES = [
573
576
  label=STEVE_BANNON,
574
577
  style='color(58)',
575
578
  pattern=r'((Steve|Sean)\s*)?Bannon?|(American\s*)?Dharma',
579
+ emailers = {
580
+ STEVE_BANNON: 'Trump campaign manager, memecoin grifter, convicted criminal',
581
+ }
576
582
  ),
577
583
  HighlightedNames(
578
584
  emailers={STEVEN_HOFFENBERG: HEADER_ABBREVIATIONS['Hoffenberg']},
@@ -646,7 +652,7 @@ ALL_HIGHLIGHTS = HIGHLIGHTED_NAMES + HIGHLIGHTED_TEXTS
646
652
 
647
653
 
648
654
  class EpsteinHighlighter(RegexHighlighter):
649
- """rich.highlighter that finds and colors interesting keywords based on the above config."""
655
+ """Finds and colors interesting keywords based on the above config."""
650
656
  base_style = f"{REGEX_STYLE_PREFIX}."
651
657
  highlights = [highlight_group.regex for highlight_group in ALL_HIGHLIGHTS]
652
658
 
@@ -666,10 +672,8 @@ def get_style_for_category(category: str) -> str | None:
666
672
  elif category == SOCIAL:
667
673
  return get_style_for_category(PUBLICIST)
668
674
 
669
- category = CATEGORY_STYLE_MAPPING.get(category, category)
670
-
671
675
  for highlight_group in HIGHLIGHTED_NAMES:
672
- if highlight_group.label == category:
676
+ if highlight_group.label == CATEGORY_STYLE_MAPPING.get(category, category):
673
677
  return highlight_group.style
674
678
 
675
679
 
@@ -33,7 +33,6 @@ DEFAULT_EMAILERS = [
33
33
  EHUD_BARAK,
34
34
  MARTIN_NOWAK,
35
35
  STEVE_BANNON,
36
- PRINCE_ANDREW,
37
36
  JIDE_ZEITLIN,
38
37
  DAVID_STERN,
39
38
  MOHAMED_WAHEED_HASSAN,
@@ -47,9 +46,8 @@ DEFAULT_EMAILERS = [
47
46
  # Order matters. Default names to print tables w/email subject, timestamp, etc for. # TODO: get rid of this ?
48
47
  DEFAULT_EMAILER_TABLES: list[str | None] = [
49
48
  GHISLAINE_MAXWELL,
50
- LEON_BLACK,
49
+ PRINCE_ANDREW,
51
50
  SULTAN_BIN_SULAYEM,
52
- DEEPAK_CHOPRA,
53
51
  ARIANE_DE_ROTHSCHILD,
54
52
  ]
55
53
 
@@ -60,7 +58,7 @@ if len(set(DEFAULT_EMAILERS).intersection(set(DEFAULT_EMAILER_TABLES))) > 0:
60
58
  def print_emails_section(epstein_files: EpsteinFiles) -> list[Email]:
61
59
  """Returns emails that were printed (may contain dupes if printed for both author and recipient)."""
62
60
  print_section_header(('Selections from ' if not args.all_emails else '') + 'His Emails')
63
- print_all_files_page_link(epstein_files)
61
+ print_other_page_link(epstein_files)
64
62
  emailers_to_print: list[str | None]
65
63
  emailer_tables: list[str | None] = []
66
64
  already_printed_emails: list[Email] = []
@@ -148,7 +146,7 @@ def print_other_files_section(files: list[OtherFile], epstein_files: EpsteinFile
148
146
  if args.all_other_files:
149
147
  console.line(1)
150
148
  else:
151
- print_all_files_page_link(epstein_files)
149
+ print_other_page_link(epstein_files)
152
150
  console.line(2)
153
151
 
154
152
  for table in [category_table, other_files_preview_table]:
@@ -143,13 +143,6 @@ def parenthesize(msg: str | Text, style: str = '') -> Text:
143
143
  return Text('(', style=style).append(txt).append(')')
144
144
 
145
145
 
146
- def print_all_files_page_link(epstein_files: 'EpsteinFiles') -> None:
147
- markup_msg = link_markup(SITE_URLS[EMAIL], 'the other page', style='light_slate_grey bold')
148
- txt = Text.from_markup(markup_msg).append(f' is uncurated and has all {len(epstein_files.other_files)}')
149
- txt.append(f" unclassifiable files and {len(epstein_files.emails):,} emails")
150
- print_centered(parenthesize(txt), style='dim')
151
-
152
-
153
146
  def print_author_header(msg: str, color: str | None, footer: str | None = None) -> None:
154
147
  txt = Text(msg, justify='center')
155
148
  color = color or 'white'
@@ -195,14 +188,12 @@ def print_header(epstein_files: 'EpsteinFiles') -> None:
195
188
 
196
189
  console.print(f"{not_optimized_msg}.\n", style='dim')
197
190
  print_page_title(width=TITLE_WIDTH)
198
- site_type: SiteType = EMAIL if args.all_emails else TEXT_MESSAGE
191
+ site_type = EMAIL if args.all_emails else TEXT_MESSAGE
199
192
  print_starred_header(f"This is the Epstein {site_type.title()}s site", num_spaces=4, num_stars=14)
200
- other_site_type: SiteType = TEXT_MESSAGE if site_type == EMAIL else EMAIL
201
- other_site_msg = "another site with" + (' all of' if other_site_type == EMAIL else '')
193
+ other_site_msg = "another site with" + (' all of' if other_site_type() == EMAIL else '')
202
194
  other_site_msg += f" Epstein's {other_site_type}s also generated by this code"
203
-
204
- markup_msg = link_markup(SITE_URLS[other_site_type], other_site_msg, OTHER_SITE_LINK_STYLE)
205
- print_centered(parenthesize(Text.from_markup(markup_msg)), style='bold')
195
+ other_site_link_markup = link_markup(other_site_url(), other_site_msg, OTHER_SITE_LINK_STYLE)
196
+ print_centered(parenthesize(Text.from_markup(other_site_link_markup)), style='bold')
206
197
  word_count_link = link_text_obj(WORD_COUNT_URL, 'most frequently used words in the emails and texts', AUX_SITE_LINK_STYLE)
207
198
  print_centered(parenthesize(word_count_link))
208
199
  metadata_link = link_text_obj(JSON_METADATA_URL, 'author attribution explanations', AUX_SITE_LINK_STYLE)
@@ -272,6 +263,19 @@ def print_numbered_list_of_emailers(_list: list[str | None], epstein_files = Non
272
263
  console.line()
273
264
 
274
265
 
266
+ def print_other_page_link(epstein_files: 'EpsteinFiles') -> None:
267
+ markup_msg = link_markup(other_site_url(), 'the other page', style='light_slate_grey bold')
268
+
269
+ if other_site_type() == EMAIL:
270
+ txt = Text.from_markup(markup_msg).append(f' is uncurated and has all {len(epstein_files.other_files)}')
271
+ txt.append(f" unclassifiable files and {len(epstein_files.emails):,} emails")
272
+ else:
273
+ txt = Text.from_markup(markup_msg).append(f' displays only a small collection of emails and')
274
+ txt.append(" unclassifiable files of particular interest")
275
+
276
+ print_centered(parenthesize(txt), style='dim')
277
+
278
+
275
279
  def print_page_title(expand: bool = True, width: int | None = None) -> None:
276
280
  title_panel = Panel(Text(PAGE_TITLE, justify='center'), expand=expand, style=TITLE_STYLE, width=width)
277
281
  console.print(Align.center(vertically_pad(title_panel)))
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "epstein-files"
3
- version = "1.0.15"
3
+ version = "1.0.16"
4
4
  description = "Tools for working with the Jeffrey Epstein documents released in November 2025."
5
5
  authors = ["Michel de Cryptadamus"]
6
6
  readme = "README.md"
File without changes
File without changes
@@ -75,7 +75,7 @@ class TextMessage:
75
75
  return msg_txt
76
76
 
77
77
  def __rich__(self) -> Text:
78
+ timestamp_txt = Text(f"[{self.timestamp_str}]", style=TIMESTAMP_DIM).append(' ')
78
79
  author_style = get_style_for_name(self.author_str if self.author_str.startswith('+') else self.author)
79
80
  author_txt = Text(self.author_str, style=author_style)
80
- timestamp_txt = Text(f"[{self.timestamp_str}]", style=TIMESTAMP_DIM).append(' ')
81
81
  return Text('').append(timestamp_txt).append(author_txt).append(': ', style='dim').append(self._message())