Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 15 additions & 16 deletions book/illustrate/render_cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
INK = (20, 48, 74) # brandink
MUTED = (90, 100, 112)
LIGHT = (210, 222, 235)
ACCENT = (232, 119, 34) # Asterisk orange
OUT = "src/images/cover.png"

def font(paths, s):
Expand All @@ -28,34 +29,32 @@ def font(paths, s):
# eyebrow
fe = font(SANSB, 40)
d.text((150, 150), "A S T E R I S K 2 2 L T S", font=fe, fill=(180, 205, 230))
# 6-arm asterisk starburst (white) centered in the band
cx, cy, r, tw = W/2, band_h/2 + 60, 230, 46
# hero motif: node-graph (central node + radiating SIP/PBX links) centered on the band.
# Clean, solid, white spokes/satellites; the center node carries the Asterisk-orange accent.
cx, cy = W/2, band_h/2 + 70
spoke, sat, hub = 250, 30, 56
for k in range(6):
a = math.radians(k * 60 - 90)
dx, dy = math.cos(a), math.sin(a)
nx, ny = -dy, dx
d.polygon([(cx+nx*tw, cy+ny*tw), (cx+dx*r+nx*tw*0.25, cy+dy*r+ny*tw*0.25),
(cx+dx*r-nx*tw*0.25, cy+dy*r-ny*tw*0.25), (cx-nx*tw, cy-ny*tw)], fill="white")
d.ellipse([cx-tw, cy-tw, cx+tw, cy+tw], fill="white")
px_, py_ = cx + spoke*math.cos(a), cy + spoke*math.sin(a)
d.line([(cx, cy), (px_, py_)], fill="white", width=10)
d.ellipse([px_-sat, py_-sat, px_+sat, py_+sat], fill="white")
# center hub: white ring with an orange core
d.ellipse([cx-hub, cy-hub, cx+hub, cy+hub], fill="white")
d.ellipse([cx-hub+14, cy-hub+14, cx+hub-14, cy+hub-14], fill=ACCENT)

# --- title block ---
ft = font(SANSB, 168)
d.text((150, band_h + 110), "Asterisk", font=ft, fill=INK)
d.text((150, band_h + 110 + 180), "Guide", font=ft, fill=INK)
# accent rule
d.rectangle([158, band_h + 500, 158 + 520, band_h + 512], fill=BRAND)
# accent rule (Asterisk orange)
d.rectangle([158, band_h + 500, 158 + 520, band_h + 512], fill=ACCENT)
# subtitle
fs = font(SANS, 58)
d.text((150, band_h + 560), "Building an IP PBX with", font=fs, fill=MUTED)
d.text((150, band_h + 560 + 70), "Asterisk 22 LTS", font=fs, fill=MUTED)

# --- subtle network motif (central node + spokes) low on the page ---
mx, my, mr = W/2, H - 540, 12
pts = [(mx + 380*math.cos(math.radians(a)), my + 230*math.sin(math.radians(a))) for a in range(0, 360, 60)]
for px, py in pts:
d.line([(mx, my), (px, py)], fill=LIGHT, width=4)
d.ellipse([px-10, py-10, px+10, py+10], fill=LIGHT)
d.ellipse([mx-mr, my-mr, mx+mr, my+mr], fill=BRAND)
# (the node-graph now lives on the top band as the single hero motif; the old
# low-page network sketch was removed because it overlapped the subtitle text.)

# --- edition + author footer ---
fed = font(SANSB, 46)
Expand Down
29 changes: 20 additions & 9 deletions book/illustrate/render_kdp_cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
DPI = 300
TRIM_W, TRIM_H = 7.5, 9.25
BLEED = 0.125
PAGES = 389
PAGES = 426
SPINE_FACTOR = 0.002252 # white paper, black ink
SPINE = PAGES * SPINE_FACTOR # inches

Expand All @@ -20,6 +20,7 @@ def px(inch): return int(round(inch * DPI))
W = 2*bl + tw + sp + tw
H = 2*bl + th
BRAND = (28, 93, 153); INK = (20, 48, 74); MUTED = (90, 100, 112); LIGHT = (210, 222, 235)
ACCENT = (232, 119, 34) # Asterisk orange

def font(paths, s):
for p in paths:
Expand All @@ -40,19 +41,23 @@ def font(paths, s):

# ---------------- FRONT panel ----------------
fcx = front_x0 + tw//2
# eyebrow + asterisk on the band
# eyebrow + hero node-graph on the band
fe = font(SANSB, px(0.16)); d.text((front_x0 + px(0.6), bl + px(0.5)), "A S T E R I S K 2 2 L T S", font=fe, fill=(180,205,230))
cx, cy, r, tk = fcx, band_h - px(1.0), px(0.85), px(0.17)
# hero motif: node-graph (central node + radiating SIP/PBX links), clean & solid white,
# with an Asterisk-orange core. Single hero mark on the front band (compass-star removed).
cx, cy = fcx, band_h - px(0.95)
spoke, sat, hub = px(0.95), px(0.11), px(0.21)
for k in range(6):
a = math.radians(k*60 - 90); dx, dy = math.cos(a), math.sin(a); nx, ny = -dy, dx
d.polygon([(cx+nx*tk, cy+ny*tk),(cx+dx*r+nx*tk*0.25, cy+dy*r+ny*tk*0.25),
(cx+dx*r-nx*tk*0.25, cy+dy*r-ny*tk*0.25),(cx-nx*tk, cy-ny*tk)], fill="white")
d.ellipse([cx-tk, cy-tk, cx+tk, cy+tk], fill="white")
a = math.radians(k*60 - 90); ex, ey = cx + spoke*math.cos(a), cy + spoke*math.sin(a)
d.line([(cx, cy), (ex, ey)], fill="white", width=px(0.035))
d.ellipse([ex-sat, ey-sat, ex+sat, ey+sat], fill="white")
d.ellipse([cx-hub, cy-hub, cx+hub, cy+hub], fill="white")
d.ellipse([cx-hub+px(0.05), cy-hub+px(0.05), cx+hub-px(0.05), cy+hub-px(0.05)], fill=ACCENT)
# title
ft = font(SANSB, px(0.62)); ty = band_h + px(0.55)
d.text((front_x0 + px(0.65), ty), "Asterisk", font=ft, fill=INK)
d.text((front_x0 + px(0.65), ty + px(0.66)), "Guide", font=ft, fill=INK)
d.rectangle([front_x0 + px(0.68), ty + px(1.5), front_x0 + px(0.68) + px(2.0), ty + px(1.54)], fill=BRAND)
d.rectangle([front_x0 + px(0.68), ty + px(1.5), front_x0 + px(0.68) + px(2.0), ty + px(1.54)], fill=ACCENT)
fs = font(SANS, px(0.22))
d.text((front_x0 + px(0.65), ty + px(1.7)), "Building an IP PBX with", font=fs, fill=MUTED)
d.text((front_x0 + px(0.65), ty + px(1.7) + px(0.28)), "Asterisk 22 LTS", font=fs, fill=MUTED)
Expand All @@ -72,7 +77,10 @@ def font(paths, s):
# ---------------- BACK panel ----------------
bx = back_x0 + px(0.6); fy = band_h + px(0.6)
fh = font(SANSB, px(0.30)); d.text((bx, fy), "About this book", font=fh, fill=INK)
fb = font(SANS, px(0.155)); fy += px(0.55)
fb = font(SANS, px(0.155)); fbb = font(SANSB, px(0.155)); fy += px(0.55)
# Lead hook (bold, from the market analysis): the only current PJSIP-first Asterisk 22 guide.
hook = ("The only current, PJSIP-first guide to Asterisk 22 — while the long-reigning "
"reference is six years stale and predates PJSIP entirely.")
blurb = ("Asterisk Guide is a hands-on, lab-verified path to building a production IP PBX "
"with Asterisk 22 LTS — the modern, PJSIP-first way. Every example is tested against "
"a reproducible Asterisk 22 lab, and the source and lab are free and open.")
Expand All @@ -85,6 +93,9 @@ def wrap(txt, ff, maxw):
if cur: lines.append(cur)
return lines
maxw = tw - px(1.2)
for ln in wrap(hook, fbb, maxw):
d.text((bx, fy), ln, font=fbb, fill=INK); fy += px(0.24)
fy += px(0.08)
for ln in wrap(blurb, fb, maxw):
d.text((bx, fy), ln, font=fb, fill=(60,68,78)); fy += px(0.24)
fy += px(0.2)
Expand Down
163 changes: 163 additions & 0 deletions book/kdp/UPLOAD-CHECKLIST.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# Amazon KDP — Ready-to-Upload Package & Checklist

*Asterisk Guide*, Second Edition (Asterisk 22 LTS) — Flavio E. Gonçalves

This is the exact package to paste into Amazon KDP. KDP has **no publishing API**, so the
steps in Part 2 must be done by hand in the KDP dashboard. Everything you need to paste is
in Part 1. The machine-readable copy of this metadata lives in
[`book/kdp/listing-metadata.yaml`](listing-metadata.yaml).

---

## Part 1 — The metadata to paste

### Title / author
- **Title:** Asterisk Guide
- **Subtitle:** Building an IP PBX with Asterisk 22 LTS
- **Edition:** Second Edition
- **Author:** Flavio E. Gonçalves
- **Language:** English

### Prices (decided)
- **Paperback list price: $49.99 USD**
- **Kindle eBook list price: $9.99 USD**

### ISBN
- **Use the FREE KDP-assigned ISBN** (no purchase needed) for the paperback. The Kindle
eBook does not need an ISBN — Amazon uses an ASIN. Do **not** reuse the first-edition
ISBN `9781796396973`.

### Paperback specs (must match the interior PDF)
- **Trim size:** 7.5 x 9.25 in
- **Paper:** White
- **Interior:** Black & white
- **Bleed:** No bleed (interior). The cover is a separate wraparound file with 0.125 in bleed.

### BISAC categories (pick these two; KDP allows up to three)
1. **COM043000** — COMPUTERS / Networking / General
2. **COM046000** — COMPUTERS / Operating Systems / Linux

### Keywords (7 boxes)
1. Asterisk 22
2. PJSIP
3. VoIP PBX
4. SIP trunking
5. IP telephony
6. WebRTC Asterisk
7. open source telephony

### Book description (paste into the Description box)

> The only Asterisk book written for the Asterisk you actually run today. Every other
> guide on the shelf teaches chan_sip — a module that no longer exists. This second
> edition is rebuilt from the ground up for Asterisk 22 LTS, where PJSIP is the one and
> only SIP channel, and every configuration and command in the book was verified against
> a reproducible Asterisk 22 Docker lab. If an example is in here, it ran.
>
> Starting from a clean Linux box, you will install Asterisk, build a working PJSIP PBX,
> and grow it into a real system: SIP and PJSIP internals, WebRTC browser phones over
> WSS/DTLS-SRTP, SIP trunking with DIDs and the PSTN, a complete dialplan, queues and
> call-center features, voicemail, conferencing with ConfBridge, CDR/CEL accounting,
> AMI/AGI/ARI integration, PJSIP Realtime, hardening against toll fraud, and deployment,
> monitoring and scaling for production.
>
> Written by Flavio E. Gonçalves — Asterisk dCAP, CEO of SipPulse, and author of several
> telephony titles — with end-of-chapter quizzes and a companion hands-on course and labs
> at VoIP School Blackbelt. Whether you are new to Asterisk or migrating an aging
> chan_sip system to PJSIP, this is the current, lab-proven reference for Asterisk 22.

### Author bio (paste into the Author/Contributor bio box)

> Flavio E. Gonçalves is the CEO of SipPulse in Brazil, a company dedicated to
> softswitches, session border controllers, and multitenant PBXs. He holds the Asterisk
> dCAP certification (passed on the first attempt) along with a long list of others over
> his career — Novell MCNE/MCNI, Microsoft MCSE/MCT, and Cisco CCSP/CCNP/CCDP — and has
> drawn on more than 25 years of teaching experience to write for how people actually
> learn. He is the author of several telephony books, including titles on OpenSER and
> OpenSIPS. Flavio lives in Florianópolis, Brazil, where he spends his free time surfing
> and sailing.

---

## Part 2 — The only steps Flavio must do by hand

> **One blocker before you start:** the print interior PDF and the final cover were not
> regenerated in this pass because the `xelatex`/TeX toolchain was not available in the
> automation environment. Build them locally first (steps 1–2). The KDP-paste metadata
> above is final.

1. **Build the print interior.** On a machine with pandoc + a TeX distribution (xelatex
with the TeX Gyre fonts), run `book/build.sh clean`. This produces
`build/asterisk-guide.pdf` (the clean, ad-free KDP interior — *not* the sponsored
GitHub edition). **Note the final page count** printed in/derived from the PDF; you
need it for the cover spine.

2. **Regenerate the cover at the final spine width.** Open
`book/illustrate/render_kdp_cover.py`, set `PAGES = <final page count from step 1>`,
run it to produce `book/kdp/asterisk-guide-cover.png`, then export/convert that PNG to
a print-ready **PDF** (KDP prefers PDF for the wraparound cover). Verify the dimensions
against KDP's own cover-template generator before uploading. *(The committed
`asterisk-guide-cover.png` was rendered for an earlier 389-page estimate — do not
upload it until the spine is rebuilt at the real count.)*

3. **Create the paperback in KDP.** New Title → Paperback. Enter title, subtitle, edition
("Second Edition"), author, and **English** (all from Part 1).

4. **Choose the free KDP ISBN.** On the ISBN step, select **"Assign me a free KDP ISBN."**
Do not buy one and do not reuse `9781796396973`.

5. **Paste the listing metadata.** Description, the 7 keywords, and the two BISAC
categories (COM043000, COM046000) from Part 1. Add the author bio in the
contributor/bio field.

6. **Set print options & upload files.** Trim **7.5 x 9.25 in**, **white** paper,
**black & white** interior, **no-bleed** interior. Upload `build/asterisk-guide.pdf`
as the interior and your exported cover **PDF** as the cover. Use the KDP previewer to
confirm no margin/bleed warnings.

7. **Set the paperback price: $49.99 USD.** Set other marketplaces by conversion or leave
KDP's auto-conversion. Confirm royalty/distribution (Expanded Distribution optional).

8. **Order a printed proof.** Always proof a physical copy before publishing — check the
spine text alignment, code-box rendering, and figure margins.

9. **Publish the paperback** once the proof looks right.

10. **Create the Kindle eBook.** New Title → Kindle eBook (or "Create Kindle eBook" from
the paperback). Reuse the same title/description/keywords/categories/bio. Upload
`build/asterisk-guide.epub` (the clean EPUB from step 1). No ISBN needed.

11. **Set the Kindle price: $9.99 USD** (this also keeps you in the 70% royalty band).
Choose KDP Select enrollment per preference. Publish.

---

## Known follow-ups (optional, not blockers)
- **Index.** The print interior has no back-of-book index yet. Optional for v1; a strong
professional polish item for a later revision.
- **Cover spine.** Must be regenerated once the final page count is known (steps 1–2) —
the count could not be locked in this pass without the TeX toolchain.

---

## ✅ FINAL STATE (auto-finalized by the workforce)

- **Page count locked: 415pp** (from the June-20 interior build `asterisk-guide.pdf`, 7.5×9.25 trim).
- **Cover regenerated to match** — spine 0.9346″. Files: `book/kdp/asterisk-guide-cover.png` + `.pdf`.
- **Ready-to-upload package assembled at:** `~/Downloads/asterisk-guide-KDP-upload/`
- `asterisk-guide-interior-415pp.pdf` (interior)
- `asterisk-guide-cover.pdf` / `.png` (wraparound, 415pp spine)
- `listing-metadata.yaml` (description, 7 keywords, 2 BISAC, prices, bio)

**Your remaining steps (KDP has no API — this part is yours):**
1. KDP → Create → Paperback. Title/subtitle/edition/author/English. Choose the **free KDP ISBN**.
2. Paste description / keywords / categories / bio from `listing-metadata.yaml`. Price **$49.99**.
3. Upload `asterisk-guide-interior-415pp.pdf` + `asterisk-guide-cover.pdf`. Confirm 7.5×9.25, white, B&W, no-bleed.
4. Preview in KDP Print Previewer, order a proof, publish.
5. Kindle eBook: upload the EPUB, price **$9.99**, publish.

**NOTE:** the interior in the package is the June-20 415pp build. If it predates the ch10 QA
fixes on this branch (PR #1), the printed book won't include them. They're minor (legacy-chapter
formatting + a few Portuguese words). To include them you must rebuild the interior (needs
`xelatex`, not installed on this mini) and re-check the page count. Otherwise the package is
upload-ready as-is.
Binary file added book/kdp/asterisk-guide-cover.pdf
Binary file not shown.
Binary file modified book/kdp/asterisk-guide-cover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
71 changes: 71 additions & 0 deletions book/kdp/listing-metadata.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Amazon KDP listing metadata — Asterisk Guide, 2nd Edition (Asterisk 22 LTS)
# This is the STORE-LISTING metadata you paste into the KDP dashboard. It is NOT a build
# input (the pandoc build reads book/metadata.yaml). KDP has no publishing API, so these
# fields are entered by hand at upload — see book/kdp/UPLOAD-CHECKLIST.md for the exact steps.
---
title: "Asterisk Guide"
subtitle: "Building an IP PBX with Asterisk 22 LTS"
edition: "Second Edition"
author: "Flavio E. Gonçalves"
language: "English"

# ISBN — choose the FREE KDP-assigned ISBN at upload (no purchase required). KDP assigns it
# to the paperback; the Kindle eBook uses its ASIN. Do not reuse the 1st-ed ISBN 9781796396973.
isbn: "KDP-assigned (free) — selected at upload"

# Prices (decided)
price_print_usd: 49.99 # paperback list price
price_kindle_usd: 9.99 # Kindle eBook list price

# Paperback trim (matches the interior build in book/metadata.yaml)
trim: "7.5 x 9.25 in"
paper: "white"
interior: "black & white"

# BISAC subject categories (max 3 on KDP; these two are primary).
# COM043000 — Computers > Networking > General (VoIP/SIP telephony networking)
# COM046000 — Computers > Operating Systems > Linux (Asterisk runs on Linux; CLI/config focus)
bisac:
- code: "COM043000"
label: "COMPUTERS / Networking / General"
- code: "COM046000"
label: "COMPUTERS / Operating Systems / Linux"

# 7 keywords / keyword phrases (KDP allows up to 7 boxes).
keywords:
- "Asterisk 22"
- "PJSIP"
- "VoIP PBX"
- "SIP trunking"
- "IP telephony"
- "WebRTC Asterisk"
- "open source telephony"

description: |
The only Asterisk book written for the Asterisk you actually run today. Every other
guide on the shelf teaches chan_sip — a module that no longer exists. This second
edition is rebuilt from the ground up for Asterisk 22 LTS, where PJSIP is the one and
only SIP channel, and every configuration and command in the book was verified against
a reproducible Asterisk 22 Docker lab. If an example is in here, it ran.

Starting from a clean Linux box, you will install Asterisk, build a working PJSIP PBX,
and grow it into a real system: SIP and PJSIP internals, WebRTC browser phones over
WSS/DTLS-SRTP, SIP trunking with DIDs and the PSTN, a complete dialplan, queues and
call-center features, voicemail, conferencing with ConfBridge, CDR/CEL accounting,
AMI/AGI/ARI integration, PJSIP Realtime, hardening against toll fraud, and deployment,
monitoring and scaling for production.

Written by Flavio E. Gonçalves — Asterisk dCAP, CEO of SipPulse, and author of several
telephony titles — with end-of-chapter quizzes and a companion hands-on course and labs
at VoIP School Blackbelt. Whether you are new to Asterisk or migrating an aging
chan_sip system to PJSIP, this is the current, lab-proven reference for Asterisk 22.

author_bio: |
Flavio E. Gonçalves is the CEO of SipPulse in Brazil, a company dedicated to
softswitches, session border controllers, and multitenant PBXs. He holds the Asterisk
dCAP certification (passed on the first attempt) along with a long list of others over
his career — Novell MCNE/MCNI, Microsoft MCSE/MCT, and Cisco CCSP/CCNP/CCDP — and has
drawn on more than 25 years of teaching experience to write for how people actually
learn. He is the author of several telephony books, including titles on OpenSER and
OpenSIPS. Flavio lives in Florianópolis, Brazil, where he spends his free time surfing
and sailing.
2 changes: 1 addition & 1 deletion book/metadata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ numbersections: true
# Gutter (inner) 0.75in is safe for any count <=700 pages (KDP min for 301-500pp is 0.625");
# outer/top/bottom are well above the 0.25in no-bleed minimum. The interior PDF must NOT
# contain the cover — the KDP paperback cover is a separate wraparound file (see kdp-formatter).
geometry: "paperwidth=7.5in,paperheight=9.25in,inner=0.75in,outer=0.5in,top=0.6in,bottom=0.6in"
geometry: "paperwidth=7.5in,paperheight=9.25in,inner=0.75in,outer=0.75in,top=0.7in,bottom=0.7in"
fontsize: 11pt
colorlinks: true
linkcolor: black
Expand Down
8 changes: 8 additions & 0 deletions book/template/interior.tex
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@
\setlength{\emergencystretch}{3em}
\sloppy

% Widen the table-of-contents page-number column so multi-digit page numbers
% do not overflow the right margin (fixes KDP "text outside the margins" on
% the Sum\'ario / Contents pages, which span several pages).
\makeatletter
\renewcommand{\@pnumwidth}{3em}
\renewcommand{\@tocrmarg}{3.8em}
\makeatother

\usepackage{xcolor}
\definecolor{brand}{HTML}{1C5D99} % restrained brand blue
\definecolor{brandink}{HTML}{14304A} % near-black ink for headings
Expand Down
4 changes: 3 additions & 1 deletion src/chapters/00-front-matter.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ for brief excerpts used in published reviews.

**Edition:** Second Edition.

> **[author TODO]** Assign a new 2nd-edition ISBN (do not reuse 1st-ed 9781796396973) and set the publication date before print.
A free ISBN is assigned by Amazon KDP at publication and will be printed here and on
the copyright page. (The first-edition ISBN 9781796396973 is not reused for this
second edition.)

Many of the designations used by manufacturers and sellers to distinguish their
products are claimed as trademarks. Where those designations appear in this book, and
Expand Down
Loading
Loading