File size: 18,171 Bytes
dd2635a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
# -*- coding: utf-8 -*-
"""Fill and correct the URAAS IBR Proposal Presentation.pptx using verified facts
from the codebase and the IBR application document."""
import copy
from pptx import Presentation
from pptx.util import Emu, Pt
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN
from pptx.oxml.ns import qn

SRC = r"c:\Users\hp\Downloads\crawler-unilag-apa\URAAS IBR Proposal Presentation.pptx"
OUT = r"c:\Users\hp\Downloads\crawler-unilag-apa\URAAS IBR Proposal Presentation - Filled.pptx"

BLUE = RGBColor(0x00, 0x70, 0xC0)
GOLD = RGBColor(0xD4, 0xA8, 0x43)
DARKGOLD = RGBColor(0x9C, 0x77, 0x15)
BLACK = RGBColor(0x22, 0x22, 0x22)

prs = Presentation(SRC)

TITLE_LEFT = Emu(1524634)
TITLE_TOP = Emu(1136655)
TITLE_WIDTH = Emu(15773400)
TITLE_HEIGHT = Emu(1988345)
CONTENT_TOP = Emu(3200000)
CONTENT_HEIGHT = Emu(6700000)


def shape_by_id(slide, sid):
    for s in slide.shapes:
        if s.shape_id == sid:
            return s
    raise KeyError(sid)


def set_run_text_replace(slide, sid, old, new):
    shp = shape_by_id(slide, sid)
    for para in shp.text_frame.paragraphs:
        for run in para.runs:
            if old in run.text:
                run.text = run.text.replace(old, new)


def fill_content_placeholder(slide, items, left=TITLE_LEFT, top=CONTENT_TOP,
                              width=TITLE_WIDTH, height=CONTENT_HEIGHT):
    """items: list of (level, text, bold, color, size_pt)"""
    ph = None
    for shp in slide.placeholders:
        if shp.placeholder_format.idx == 1:
            ph = shp
            break
    ph.left, ph.top, ph.width, ph.height = left, top, width, height
    tf = ph.text_frame
    tf.word_wrap = True
    # clear existing paragraphs (keep first, then remove extras)
    tf.clear()
    first = True
    for level, text, bold, color, size in items:
        if first:
            p = tf.paragraphs[0]
            first = False
        else:
            p = tf.add_paragraph()
        p.level = level
        run = p.add_run()
        run.text = text
        run.font.bold = bold
        run.font.size = Pt(size)
        run.font.name = "Georgia"
        if color:
            run.font.color.rgb = color
        p.space_after = Pt(8 if level == 0 else 4)
    return ph


def new_content_slide(title_text):
    layout = [l for l in prs.slide_layouts if l.name == "Title and Content"][0]
    slide = prs.slides.add_slide(layout)
    title_ph = slide.shapes.title
    title_ph.left, title_ph.top, title_ph.width, title_ph.height = (
        TITLE_LEFT, TITLE_TOP, TITLE_WIDTH, TITLE_HEIGHT)
    title_ph.text_frame.clear()
    p = title_ph.text_frame.paragraphs[0]
    run = p.add_run()
    run.text = title_text
    run.font.bold = True
    run.font.name = "Times New Roman"
    run.font.color.rgb = BLUE
    run.font.size = Pt(40)
    return slide


def clone_shape(slide, sid, dx, dy, new_text=None):
    src = shape_by_id(slide, sid)
    new_el = copy.deepcopy(src._element)
    # assign a fresh unique shape id
    max_id = max(s.shape_id for s in slide.shapes)
    cNvPr = new_el.find(qn('p:nvSpPr') + '/' + qn('p:cNvPr'))
    if cNvPr is None:
        cNvPr = new_el.find(qn('p:nvSpPr'))
        cNvPr = cNvPr.find(qn('p:cNvPr'))
    cNvPr.set('id', str(max_id + 1))
    slide.shapes._spTree.append(new_el)
    new_shape = slide.shapes[-1]
    new_shape.left = Emu(src.left + dx)
    new_shape.top = Emu(src.top + dy)
    if new_text is not None and new_shape.has_text_frame:
        paras = new_shape.text_frame.paragraphs
        if paras and paras[0].runs:
            paras[0].runs[0].text = new_text
    return new_shape


# ============================================================
# SLIDE 1 β€” BACKGROUND
# ============================================================
slide = prs.slides[1]
items = [
    (0, "Indigenous Knowledge is a foundational African intellectual asset", True, BLUE, 22),
    (1, "Oral traditions, ecological practice, medicine and cultural heritage accumulated across generations (Berkes, 2009; Battiste, 2002)", False, BLACK, 18),
    (0, "That knowledge is disappearing faster than it can be documented", True, BLUE, 22),
    (1, "Globalization, urban migration and the loss of elder custodians erode oral-only transmission systems (UNESCO, 2017; Ngulube, 2002)", False, BLACK, 18),
    (0, "Nigerian scholarly and cultural output is scattered and unindexed", True, BLUE, 22),
    (1, "Departmental drives, personal pages and print-only archives β€” undiscoverable, duplicated, at risk of permanent loss", False, BLACK, 18),
    (0, "Conventional repositories were not built for African epistemologies", True, BLUE, 22),
    (1, "DSpace-style tools reflect linear, Western archival norms; Mukurtu CMS was built for Pacific Indigenous communities β€” neither natively supports Yoruba, Igbo, Hausa, oral-source attribution or community-ownership flags", False, BLACK, 18),
    (0, "Directly aligned to TETFund NRF 2026 priorities", True, GOLD, 22),
    (1, "Thematic area: ICT in Education & Library and Information Science β€” identified by the UNILAG Research Management Office as a strategic digital-preservation gap", False, BLACK, 18),
    (0, "Our response: URAAS", True, DARKGOLD, 24),
    (1, "A self-archiving, analytics-driven digital repository purpose-built to harvest, classify, preserve and analyse African research, indigenous knowledge and cultural heritage", False, BLACK, 18),
]
fill_content_placeholder(slide, items)

# ============================================================
# SLIDE 3 β€” AIM & OBJECTIVES
# ============================================================
slide = prs.slides[3]
items = [
    (0, "Aim", True, BLUE, 22),
    (1, "Design and deploy a self-archiving, analytics-driven digital asset management system to curate, preserve and evaluate the impact of Indigenous Knowledge, cultural heritage and African innovation.", False, BLACK, 18),
    (0, "Specific Objectives", True, BLUE, 22),
    (1, "1.  Deploy URAAS as an enterprise-level, automated web crawler to centralize scattered institutional research assets", False, BLACK, 18),
    (1, "2.  Safeguard institutional scholarly output against data loss through robust digital preservation architecture", False, BLACK, 18),
    (1, "3.  Enable large-scale processing of discovery logs and metadata to reveal actionable patterns for university administrators and library leadership", False, BLACK, 18),
    (1, "4.  Undertake analytics to review trends and produce data-guided reports for institutional decision-making and impact", False, BLACK, 18),
    (0, "Guiding Research Questions", True, GOLD, 22),
    (1, "Does automated archival improve preservation speed & coverage vs. manual workflows?", False, BLACK, 17),
    (1, "Can automated metadata extraction reduce fragmentation and raise the visibility of Nigerian IK output?", False, BLACK, 17),
    (1, "Does curation and archival meaningfully facilitate preservation of IK for posterity?", False, BLACK, 17),
    (1, "How should cultural sensitivity, IP and data sovereignty be encoded into a digital preservation system?", False, BLACK, 17),
]
fill_content_placeholder(slide, items)

# ============================================================
# SLIDE 4 β€” LITERATURE REVIEW (also fix title typo)
# ============================================================
slide = prs.slides[4]
for shp in slide.shapes:
    if shp.has_text_frame and "RIVIEW" in shp.text_frame.text:
        for para in shp.text_frame.paragraphs:
            for run in para.runs:
                run.text = run.text.replace("LITERATURE RIVIEW", "LITERATURE REVIEW")

items = [
    (0, "Analytics-driven institutional decision-making", True, BLUE, 21),
    (1, "Predictive analytics and scenario simulation replace reactive, anecdotal library planning (Davenport & Harris, 2007; Witten et al., 2011)", False, BLACK, 17),
    (0, "NLP-enabled metadata enrichment", True, BLUE, 21),
    (1, "Automated extraction reduces fragmentation and improves discoverability of dispersed IK sources (Bird et al., 2009; Grishman, 1997)", False, BLACK, 17),
    (0, "Curation as active cultural continuity, not passive storage", True, BLUE, 21),
    (1, "Community-participatory archival frameworks preserve authenticity and IP sovereignty (Smith, 2012; Christen, 2012)", False, BLACK, 17),
    (0, "The gap this project fills", True, GOLD, 21),
    (1, "No enterprise-grade system exists for Nigerian multilingual, orally-transmitted, non-linear knowledge β€” existing tools (DSpace, Mukurtu) were not designed for this context", False, BLACK, 17),
    (0, "Theoretical Framework", True, DARKGOLD, 21),
    (1, "Data-Driven Decision-Making (DDDM) & Intelligence-Driven Leadership β€” centralized, evidence-based systems improve strategic outputs and institutional rankings", False, BLACK, 17),
    (1, "Knowledge Management Theory (Nonaka & Takeuchi, 1995) β€” converting tacit indigenous knowledge into explicit, archivable form", False, BLACK, 17),
    (1, "Digital Heritage Theory (UNESCO, 2017) β€” authenticity, accessibility and sustainability of digital cultural artefacts", False, BLACK, 17),
]
fill_content_placeholder(slide, items)

# ============================================================
# SLIDE 5 β€” METHODOLOGY
# ============================================================
slide = prs.slides[5]
items = [
    (0, "Modular microservices architecture", True, BLUE, 21),
    (1, "Django REST Framework Β· Elasticsearch 8.x Β· PostgreSQL Β· React.js PWA Β· Celery task queue", False, BLACK, 17),
    (0, "Six delivery phases", True, BLUE, 21),
    (1, "1. Framework Development β€” architecture & environment setup", False, BLACK, 16),
    (1, "2. Identification, Classification & Coding β€” URAAS Taxonomy & Metadata Standard (UTMS): MARC 21 + Dublin Core + IK-specific fields", False, BLACK, 16),
    (1, "3. Crawling & Curating β€” automated ingestion, NLP enrichment, MinHash duplicate detection", False, BLACK, 16),
    (1, "4. Validation β€” technical (SHA-256, PRONOM, ClamAV/PII) and cultural-compliance auditing", False, BLACK, 16),
    (1, "5. Preservation β€” three-site distributed storage, 25-year sustainability horizon", False, BLACK, 16),
    (1, "6. Analytics for Impact β€” Apache Superset dashboard over Elasticsearch + PostgreSQL", False, BLACK, 16),
    (0, "Already in build β€” not just on paper", True, GOLD, 21),
    (1, "14 live harvesting spiders already running (OpenAlex, Crossref, DOAJ, AJOL, OAI-PMH, PubMed, DataCite, ISNI and more)", False, BLACK, 17),
    (1, "3-gate attribution filter (ROR + staff fuzzy-match + affiliation regex) already validating live UNILAG output", False, BLACK, 17),
    (1, "DocID + ARK persistent identifiers minted per record; direct DSpace 9.1 institutional-repository deposit pipeline", False, BLACK, 17),
    (1, "Working analytics engine β€” TK Vitality Score, Linguistic Diversity Index, Intra-African Collaboration, SDG alignment", False, BLACK, 17),
    (1, "See System Architecture & Live Demo, next β†’", False, DARKGOLD, 17),
]
fill_content_placeholder(slide, items)

# ============================================================
# CORRECTIONS on existing system-architecture slides (6,7,8,9,10)
# ============================================================
s6 = prs.slides[6]
set_run_text_replace(s6, 7, "11", "14")
set_run_text_replace(s6, 12, "133", "346")
set_run_text_replace(s6, 22, "IR, with ", "IR β€” ")
set_run_text_replace(s6, 22, "approval workflow", "direct deposit (no manual gate)")

s7 = prs.slides[7]
set_run_text_replace(s7, 6, "11", "14")
set_run_text_replace(s7, 7, "+ 5 more", "+ 8 more")

s8 = prs.slides[8]
set_run_text_replace(
    s8, 14,
    "Institution-specific lists, 400+ researchers each.",
    "UNILAG staff registry: 500 named researchers (3,107 detailed records).",
)

s9 = prs.slides[9]
set_run_text_replace(s9, 3, "Eleven sources", "Fourteen sources")
_seed_shape = shape_by_id(s9, 30)
_seed_runs = _seed_shape.text_frame.paragraphs[0].runs
_seed_runs[0].text = "20 seed phrases "
_seed_runs[1].text = "across 8 Special Collections categories, injected as oversampling queries."
# add the 3 missing source badges: arXiv (row4 col3), DataCite (row5 col1), ISNI (row5 col2)
# row4: bg id22/label id23 = OpenAiRE (col1); bg id24/label id25 = ORCID (col2)
col3_dx = 7140972 - 1047750
row5_dy = 5616873 - 4854873
# arXiv: clone OpenAiRE pair shifted to col3, same row
clone_shape(s9, 22, col3_dx, 0)
clone_shape(s9, 23, col3_dx, 0, new_text="arXiv")
# DataCite: clone OpenAiRE pair shifted down one row (col1)
clone_shape(s9, 22, 0, row5_dy)
clone_shape(s9, 23, 0, row5_dy, new_text="DataCite")
# ISNI: clone ORCID pair shifted down one row (col2)
clone_shape(s9, 24, 0, row5_dy)
clone_shape(s9, 25, 0, row5_dy, new_text="ISNI")

s10 = prs.slides[10]
set_run_text_replace(s10, 12, "6.2% global baseline", "8.4% global baseline")
set_run_text_replace(s10, 14, "Citations Velocity", "Citation Velocity")
set_run_text_replace(s10, 15, "Lag between use of citations records", "Time lag between publication and first citation, tracked per record")

# ============================================================
# NEW CLOSING SLIDES
# ============================================================

# --- Expected Outcomes & Innovation ---
slide = new_content_slide("EXPECTED OUTCOMES & INNOVATION")
items = [
    (0, "Six outcomes, mapped to the six methodology phases", True, BLUE, 20),
    (1, "URAAS Indigenous Knowledge Taxonomy & Metadata Standard (UTMS) β€” openly published, reusable across Nigerian universities", False, BLACK, 16),
    (1, "Fully functional, deployable URAAS platform β€” self-archiving portal, role-based access, multilingual interface, documented API", False, BLACK, 16),
    (1, "Populated repository β€” minimum 5,000 indexed records (faculty outputs + community-sourced IK assets: audio, video, text, image)", False, BLACK, 16),
    (1, "Validation & Audit Report β€” integrity, cultural compliance, IP sovereignty; replicable Community Validation Protocol", False, BLACK, 16),
    (1, "Digital Preservation Policy β€” three-site redundancy, signed post-grant maintenance MoU, 25-year survival horizon", False, BLACK, 16),
    (1, "Quarterly Data-Guided Reports + final Impact Assessment Report, feeding UNILAG strategic planning", False, BLACK, 16),
    (0, "Innovation", True, GOLD, 20),
    (1, "First enterprise-grade digital asset management system purpose-built for African epistemologies (vs. Mukurtu, standard DSpace)", False, BLACK, 16),
    (1, "Single pipeline unifying crawling, curation and analytics β€” not three separate tools bolted together", False, BLACK, 16),
    (1, "100% open-source stack β€” zero recurring licence cost, sustainable by any Nigerian university with basic cloud infrastructure", False, BLACK, 16),
]
fill_content_placeholder(slide, items)

# --- Budget & Timeline ---
slide = new_content_slide("BUDGET & TIMELINE (9 MONTHS)")
items = [
    (0, "Total requested: ₦4,889,529.50", True, BLUE, 22),
    (1, "Personnel  12.5%   |   Equipment  27.6%   |   Data Collection & Analysis  31.0%", False, BLACK, 17),
    (1, "Dissemination  10.8%   |   Consumables  8.2%   |   Travel  5.1%   |   Miscellaneous  4.9%", False, BLACK, 17),
    (0, "9-month delivery timeline", True, BLUE, 22),
    (1, "M1–2   Framework & technical architecture setup", False, BLACK, 17),
    (1, "M2–3   Indigenous Knowledge Taxonomy & Metadata Standard (UTMS)", False, BLACK, 17),
    (1, "M3–6   Crawling, ingestion & NLP enrichment (target: 5,000+ records)", False, BLACK, 17),
    (1, "M5–7   Technical & cultural-compliance validation", False, BLACK, 17),
    (1, "M6–8   Three-site preservation infrastructure", False, BLACK, 17),
    (1, "M6–9   Analytics dashboard build & community engagement", False, BLACK, 17),
    (1, "M9      Final Impact Assessment Report", False, BLACK, 17),
]
fill_content_placeholder(slide, items)

# --- Team & Institutional Capacity ---
slide = new_content_slide("TEAM & INSTITUTIONAL CAPACITY")
items = [
    (0, "A cross-functional team already operating the working prototype", True, BLUE, 20),
    (1, "Dr Titilayo Adedokun β€” Principal Investigator, Senior Librarian, Ph.D Library Science", False, BLACK, 17),
    (1, "Prof. Olatokunbo Okiki β€” Ph.D Library Science", False, BLACK, 17),
    (1, "Prof. Luqman Adams β€” Ph.D, University Ranking Data Provider", False, BLACK, 17),
    (1, "Olufemi Agunbiade β€” B.Sc, Data Analytics", False, BLACK, 17),
    (1, "Giyath Lawal β€” Undergraduate Software Engineer, lead builder of the working URAAS prototype", False, BLACK, 17),
    (0, "Sustainability", True, GOLD, 20),
    (1, "Zero-markup, open-source stack (Scrapy, Django, Elasticsearch, PostgreSQL, Superset) β€” no recurring vendor dependency", False, BLACK, 17),
    (1, "Signed MoU secures post-grant institutional maintenance for a minimum of 25 years", False, BLACK, 17),
    (1, "Crawler already configured for 43 institutions beyond UNILAG β€” a foundation for pan-Nigerian scale-up", False, BLACK, 17),
]
fill_content_placeholder(slide, items)

# --- Thank You ---
layout = [l for l in prs.slide_layouts if l.name == "Title and Content"][0]
slide = prs.slides.add_slide(layout)
ph = None
for shp in slide.placeholders:
    if shp.placeholder_format.idx == 1:
        ph = shp
ph.left, ph.top, ph.width, ph.height = Emu(1257300), Emu(2500000), Emu(15773400), Emu(5500000)
tf = ph.text_frame
tf.word_wrap = True
tf.clear()
p = tf.paragraphs[0]
p.alignment = PP_ALIGN.CENTER
run = p.add_run()
run.text = "Thank You"
run.font.bold = True
run.font.name = "Times New Roman"
run.font.color.rgb = BLUE
run.font.size = Pt(54)

p2 = tf.add_paragraph()
p2.alignment = PP_ALIGN.CENTER
r2 = p2.add_run()
r2.text = "Questions & Discussion"
r2.font.name = "Georgia"
r2.font.color.rgb = GOLD
r2.font.size = Pt(28)
r2.font.bold = True

p3 = tf.add_paragraph()
p3.alignment = PP_ALIGN.CENTER
r3 = p3.add_run()
r3.text = "Requesting ₦4,889,529.50 over 9 months to take URAAS from working prototype to a validated, deployed institutional asset."
r3.font.name = "Georgia"
r3.font.size = Pt(20)

prs.save(OUT)
print("Saved:", OUT)