Thursday

19-06-2025 Vol 19

I created a code search tool made in Flask.

Membuat Alat Pencarian Kode yang Tangguh dengan Flask: Panduan Langkah Demi Langkah

Pencarian kode adalah tulang punggung produktivitas pengembang. Kemampuan untuk dengan cepat menemukan potongan kode tertentu, definisi fungsi, atau bahkan hanya variabel yang digunakan dapat menghemat waktu yang tak terhitung jumlahnya dan mencegah frustrasi. Dalam posting blog ini, kita akan menjelajahi bagaimana membangun alat pencarian kode Anda sendiri menggunakan Flask, kerangka kerja web Python yang ringan dan fleksibel. Kami akan membahas setiap langkah secara rinci, dari menyiapkan lingkungan pengembangan hingga mengimplementasikan logika pencarian dan menampilkan hasilnya dengan indah. Siapkan diri Anda untuk perjalanan yang menarik ke dunia pencarian kode!

Mengapa Membangun Alat Pencarian Kode Sendiri?

Mungkin Anda bertanya-tanya, mengapa repot-repot membangun alat pencarian kode sendiri ketika ada solusi yang sudah ada seperti GitHub code search, Sourcegraph, atau bahkan hanya menggunakan grep? Berikut adalah beberapa alasan:

  • Kustomisasi: Anda memiliki kendali penuh atas fungsionalitas dan tampilan alat tersebut. Anda dapat menyesuaikannya dengan kebutuhan spesifik tim atau proyek Anda.
  • Integrasi: Anda dapat dengan mudah mengintegrasikannya dengan alur kerja dan sistem yang ada. Misalnya, Anda dapat menghubungkannya ke sistem pelaporan bug atau alat analisis kode Anda.
  • Privasi: Jika Anda bekerja dengan kode kepemilikan, Anda mungkin tidak ingin mengunggahnya ke layanan pihak ketiga. Membangun alat Anda sendiri memungkinkan Anda menjaga kode Anda tetap aman dan privat.
  • Pembelajaran: Ini adalah proyek yang bagus untuk belajar lebih banyak tentang Flask, pencarian teks, dan prinsip-prinsip desain perangkat lunak.
  • Performa: Anda dapat mengoptimalkan alat Anda untuk repositori kode khusus Anda, berpotensi menghasilkan kinerja yang lebih baik daripada solusi umum.

Kerangka Artikel

  1. Pengantar
    • Pentingnya pencarian kode
    • Mengapa membangun alat pencarian kode sendiri?
    • Gambaran umum teknologi yang digunakan (Flask, Python)
  2. Menyiapkan Lingkungan Pengembangan
    • Menginstal Python dan pip
    • Membuat lingkungan virtual
    • Menginstal Flask dan dependensi lainnya
    • Struktur proyek
  3. Merancang Antarmuka Pengguna (UI)
    • Membuat template HTML (menggunakan Jinja2)
    • Formulir pencarian
    • Menampilkan hasil pencarian
    • Gaya dasar (CSS)
  4. Mengimplementasikan Logika Pencarian
    • Membaca file kode dari direktori
    • Algoritma pencarian dasar (pencocokan string)
    • Pencarian sensitif dan tidak sensitif huruf besar/kecil
    • Menyoroti hasil pencarian
  5. Meningkatkan Logika Pencarian (Opsional)
    • Menggunakan ekspresi reguler
    • Mengindeks kode untuk pencarian lebih cepat (misalnya, menggunakan Whoosh atau Bleve)
  6. Integrasi Backend Flask
    • Membuat rute Flask untuk menangani permintaan pencarian
    • Menerima kueri pencarian dari formulir
    • Memanggil logika pencarian
    • Mengirimkan hasil ke template
  7. Menangani Kasus Tepi dan Kesalahan
    • Menangani masukan pengguna yang buruk
    • Menangani kesalahan file
    • Menampilkan pesan kesalahan yang bermakna
  8. Menguji Alat Pencarian Kode
    • Membuat test case dasar
    • Menguji berbagai jenis kueri
    • Menguji penanganan kesalahan
  9. Penyebaran (Opsional)
    • Menyebarkan ke platform seperti Heroku atau AWS
    • Konfigurasi server web (misalnya, Gunicorn)
  10. Kesimpulan
    • Ringkasan proyek
    • Manfaat memiliki alat pencarian kode sendiri
    • Langkah selanjutnya dan kemungkinan peningkatan

1. Pengantar

Pencarian kode adalah keterampilan penting bagi setiap pengembang. Bayangkan sebuah proyek besar dengan ribuan baris kode. Mencari fungsi, variabel, atau bahkan hanya komentar tertentu secara manual akan menjadi mimpi buruk. Di sinilah alat pencarian kode berperan. Mereka memungkinkan Anda untuk dengan cepat dan efisien menemukan informasi yang Anda butuhkan dalam basis kode Anda.

Dalam artikel ini, kita akan membangun alat pencarian kode sederhana namun kuat menggunakan Flask dan Python. Flask adalah kerangka kerja web mikro yang populer yang mudah dipelajari dan digunakan. Python adalah bahasa pemrograman serbaguna yang sangat cocok untuk tugas-tugas seperti manipulasi teks dan pemrosesan file.

Kita akan menggunakan HTML dan CSS untuk membangun antarmuka pengguna, dan Jinja2, mesin template Flask, untuk merender hasil pencarian.

2. Menyiapkan Lingkungan Pengembangan

Sebelum kita mulai menulis kode, kita perlu menyiapkan lingkungan pengembangan kita. Ini melibatkan penginstalan Python, pip (pengelola paket untuk Python), membuat lingkungan virtual, dan menginstal Flask dan dependensi yang diperlukan.

2.1 Menginstal Python dan pip

Jika Anda belum memiliki Python dan pip yang diinstal, Anda dapat mengunduhnya dari situs web resmi Python: https://www.python.org/downloads/. Pastikan untuk memilih versi Python 3.x. pip biasanya disertakan secara default saat menginstal Python versi 3.4 ke atas.

Setelah menginstal Python dan pip, Anda dapat memverifikasi instalasi dengan membuka terminal atau command prompt dan menjalankan perintah berikut:

python --version
pip --version

Ini akan menampilkan versi Python dan pip yang diinstal pada sistem Anda.

2.2 Membuat Lingkungan Virtual

Lingkungan virtual adalah cara yang bagus untuk mengisolasi dependensi proyek Anda. Ini mencegah konflik antara dependensi proyek yang berbeda. Untuk membuat lingkungan virtual, Anda dapat menggunakan modul venv, yang disertakan dengan Python 3.3 dan yang lebih baru.

Di terminal atau command prompt Anda, navigasikan ke direktori tempat Anda ingin membuat proyek Anda dan jalankan perintah berikut:

python -m venv venv

Ini akan membuat direktori baru bernama venv yang berisi lingkungan virtual. Untuk mengaktifkan lingkungan virtual, jalankan perintah berikut:

  • Windows: venv\Scripts\activate
  • macOS dan Linux: source venv/bin/activate

Setelah lingkungan virtual diaktifkan, Anda akan melihat nama lingkungan virtual (venv) di awal baris perintah Anda.

2.3 Menginstal Flask dan Dependensi Lainnya

Sekarang setelah lingkungan virtual Anda diaktifkan, Anda dapat menginstal Flask dan dependensi lain yang Anda butuhkan menggunakan pip. Untuk menginstal Flask, jalankan perintah berikut:

pip install Flask

Selain Flask, kita juga akan menginstal Werkzeug, yang merupakan toolkit WSGI komprehensif untuk Python. Flask bergantung pada Werkzeug. Anda mungkin sudah menginstalnya sebagai dependensi dari Flask, tetapi ada baiknya untuk secara eksplisit menginstalnya untuk memastikan Anda memiliki versi terbaru:

pip install Werkzeug

Anda mungkin juga ingin menginstal beberapa paket lain, tergantung pada kebutuhan proyek Anda. Misalnya, jika Anda berencana untuk menggunakan ekspresi reguler untuk pencarian Anda, Anda mungkin ingin menginstal modul re (yang biasanya merupakan bagian dari pustaka standar Python dan tidak perlu diinstal secara terpisah).

2.4 Struktur Proyek

Sebelum kita mulai menulis kode, mari kita buat struktur proyek yang sederhana. Struktur proyek kami akan terlihat seperti ini:

code_search/
├── venv/
├── app.py
├── templates/
│   └── index.html
└── static/
    └── style.css

Berikut adalah penjelasan dari setiap file dan direktori:

  • code_search/: Direktori root proyek.
  • venv/: Direktori lingkungan virtual.
  • app.py: File Python utama yang berisi aplikasi Flask.
  • templates/: Direktori yang berisi template HTML.
  • index.html: Template HTML untuk halaman pencarian.
  • static/: Direktori yang berisi file statis seperti CSS dan JavaScript.
  • style.css: File CSS untuk gaya halaman pencarian.

3. Merancang Antarmuka Pengguna (UI)

Antarmuka pengguna untuk alat pencarian kode kita akan sederhana. Ini akan terdiri dari formulir pencarian tempat pengguna dapat memasukkan kueri pencarian mereka dan area untuk menampilkan hasil pencarian.

3.1 Membuat Template HTML (menggunakan Jinja2)

Buat file baru bernama index.html di direktori templates Anda. File ini akan berisi template HTML untuk halaman pencarian kita. Gunakan kode berikut:

<!DOCTYPE html>
<html>
<head>
    <title>Pencarian Kode</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
    <h1>Pencarian Kode</h1>

    <form method="POST">
        <input type="text" name="query" placeholder="Masukkan kueri pencarian Anda">
        <button type="submit">Cari</button>
    </form>

    <div id="results">
        {% if results %}
            <h2>Hasil:</h2>
            <ul>
                {% for result in results %}
                    <li>
                        <strong>File:</strong> {{ result.filename }}<br>
                        <strong>Baris:</strong> {{ result.line_number }}<br>
                        <pre><code>{{ result.line }}</code></pre>
                    </li>
                {% endfor %}
            </ul>
        {% endif %}
    </div>
</body>
</html>

Template ini menggunakan Jinja2, mesin template Flask, untuk menampilkan hasil pencarian. Tag {{ url_for('static', filename='style.css') }} menghasilkan URL untuk file CSS kita. Loop {% for result in results %} mengulangi hasil pencarian dan menampilkan setiap hasil sebagai item daftar.

3.2 Formulir Pencarian

Formulir pencarian adalah bagian penting dari antarmuka pengguna kami. Ini memungkinkan pengguna untuk memasukkan kueri pencarian mereka. Formulir ini dibuat menggunakan tag <form> HTML. Atribut method diatur ke POST, yang berarti bahwa data formulir akan dikirim ke server menggunakan metode POST. Atribut action diatur ke URL tempat formulir akan dikirimkan. Dalam kasus ini, kita tidak secara eksplisit menentukan atribut `action`, yang berarti formulir akan dikirim ke URL yang sama tempat formulir ditampilkan.

Formulir ini berisi input teks tempat pengguna dapat memasukkan kueri pencarian mereka. Atribut name dari input teks diatur ke query. Ini adalah nama yang akan kita gunakan untuk mengakses nilai input di kode Flask kita.

Formulir ini juga berisi tombol pengiriman yang mengirimkan formulir ke server ketika diklik.

3.3 Menampilkan Hasil Pencarian

Hasil pencarian ditampilkan dalam elemen <div> dengan ID results. Jika ada hasil, kita menampilkan judul <h2> dan daftar hasil yang tidak berurutan (<ul>). Setiap hasil ditampilkan sebagai item daftar (<li>). Setiap item daftar berisi nama file, nomor baris, dan baris kode tempat kecocokan ditemukan.

Kita menggunakan tag <pre> dan <code> untuk menampilkan kode. Ini memastikan bahwa kode diformat dengan benar dan bahwa spasi putih dipertahankan.

3.4 Gaya Dasar (CSS)

Buat file baru bernama style.css di direktori static Anda. File ini akan berisi gaya CSS untuk halaman pencarian kita. Gunakan kode berikut:

body {
    font-family: sans-serif;
    margin: 20px;
}

h1 {
    text-align: center;
}

form {
    text-align: center;
    margin-bottom: 20px;
}

input[type="text"] {
    padding: 10px;
    width: 300px;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
}

button[type="submit"] {
    padding: 10px 20px;
    background-color: #4CAF50;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

#results {
    margin-top: 20px;
}

ul {
    list-style: none;
    padding: 0;
}

li {
    margin-bottom: 20px;
    border: 1px solid #ccc;
    padding: 10px;
    border-radius: 4px;
}

pre {
    background-color: #f0f0f0;
    padding: 10px;
    border-radius: 4px;
    overflow-x: auto;
}

Gaya ini memberikan tampilan dasar ke halaman pencarian kita. Anda dapat menyesuaikan gaya ini untuk menyesuaikan dengan preferensi Anda.

4. Mengimplementasikan Logika Pencarian

Sekarang setelah kita memiliki antarmuka pengguna, kita perlu mengimplementasikan logika pencarian. Ini melibatkan membaca file kode dari direktori, mencari kueri pencarian, dan menyoroti hasil pencarian.

4.1 Membaca File Kode dari Direktori

Langkah pertama adalah membaca file kode dari direktori. Kita dapat melakukan ini menggunakan modul os di Python. Modul os menyediakan cara untuk berinteraksi dengan sistem operasi, termasuk menjelajahi direktori dan membaca file.

Buat fungsi bernama read_files yang mengambil direktori sebagai argumen dan mengembalikan daftar file kode.

import os

def read_files(directory):
    """Membaca semua file dari direktori dan mengembalikan daftar file."""
    file_list = []
    for root, _, files in os.walk(directory):
        for file in files:
            file_path = os.path.join(root, file)
            try:
                with open(file_path, 'r', encoding='utf-8') as f:
                    file_list.append({'filename': file_path, 'content': f.read()})
            except Exception as e:
                print(f"Gagal membaca file {file_path}: {e}")
    return file_list

Fungsi ini menggunakan fungsi os.walk untuk menjelajahi direktori dan semua subdirektorinya. Untuk setiap file, fungsi ini membuka file dan membaca kontennya. Fungsi ini kemudian menambahkan nama file dan konten ke daftar file. Kita menggunakan blok `try…except` untuk menangani potensi kesalahan saat membaca file. Hal ini penting, karena kita tidak ingin aplikasi kita gagal jika kita menemukan file yang tidak dapat kita baca (misalnya, file biner).

4.2 Algoritma Pencarian Dasar (Pencocokan String)

Algoritma pencarian dasar adalah pencocokan string. Ini melibatkan pencarian kueri pencarian dalam konten setiap file. Kita dapat melakukan ini menggunakan metode find string Python.

Buat fungsi bernama search yang mengambil daftar file dan kueri pencarian sebagai argumen dan mengembalikan daftar hasil pencarian.

def search(file_list, query):
    """Mencari kueri dalam daftar file dan mengembalikan daftar hasil."""
    results = []
    for file_data in file_list:
        filename = file_data['filename']
        content = file_data['content']
        lines = content.splitlines()
        for i, line in enumerate(lines):
            if query in line:
                results.append({
                    'filename': filename,
                    'line_number': i + 1,
                    'line': line
                })
    return results

Fungsi ini mengulangi daftar file. Untuk setiap file, fungsi ini memecah konten menjadi beberapa baris. Fungsi ini kemudian mengulangi baris dan mencari kueri pencarian di setiap baris. Jika kueri pencarian ditemukan di baris, fungsi ini menambahkan hasil pencarian ke daftar hasil.

4.3 Pencarian Sensitif dan Tidak Sensitif Huruf Besar/Kecil

Saat ini, pencarian kita sensitif terhadap huruf besar/kecil. Ini berarti bahwa pencarian untuk “halo” tidak akan cocok dengan “Halo”. Untuk membuat pencarian kita tidak sensitif terhadap huruf besar/kecil, kita dapat mengonversi kueri pencarian dan konten file menjadi huruf kecil sebelum melakukan pencarian.

Ubah fungsi search untuk melakukan pencarian tidak sensitif huruf besar/kecil.

def search(file_list, query, case_sensitive=False):
    """Mencari kueri dalam daftar file dan mengembalikan daftar hasil."""
    results = []
    for file_data in file_list:
        filename = file_data['filename']
        content = file_data['content']
        lines = content.splitlines()
        for i, line in enumerate(lines):
            if case_sensitive:
                if query in line:
                    results.append({
                        'filename': filename,
                        'line_number': i + 1,
                        'line': line
                    })
            else:
                if query.lower() in line.lower():
                    results.append({
                        'filename': filename,
                        'line_number': i + 1,
                        'line': line
                    })
    return results

Kita menambahkan parameter baru ke fungsi search bernama case_sensitive. Parameter ini menentukan apakah pencarian harus sensitif terhadap huruf besar/kecil atau tidak. Jika parameter case_sensitive diatur ke False, kita mengonversi kueri pencarian dan konten file menjadi huruf kecil sebelum melakukan pencarian.

4.4 Menyoroti Hasil Pencarian

Untuk membuat hasil pencarian lebih mudah dibaca, kita dapat menyoroti kueri pencarian dalam baris kode tempat kecocokan ditemukan. Kita dapat melakukan ini menggunakan tag <mark> HTML.

Ubah fungsi search untuk menyoroti kueri pencarian dalam baris kode.

import re

def search(file_list, query, case_sensitive=False):
    """Mencari kueri dalam daftar file dan mengembalikan daftar hasil."""
    results = []
    for file_data in file_list:
        filename = file_data['filename']
        content = file_data['content']
        lines = content.splitlines()
        for i, line in enumerate(lines):
            if case_sensitive:
                if query in line:
                    highlighted_line = line.replace(query, f'<mark>{query}</mark>')
                    results.append({
                        'filename': filename,
                        'line_number': i + 1,
                        'line': highlighted_line
                    })
            else:
                if query.lower() in line.lower():
                    # Gunakan ekspresi reguler untuk penyorotan yang tidak sensitif huruf besar/kecil
                    highlighted_line = re.sub(re.compile(re.escape(query), re.IGNORECASE), r'<mark>\g<0></mark>', line)
                    results.append({
                        'filename': filename,
                        'line_number': i + 1,
                        'line': highlighted_line
                    })
    return results

Kita menggunakan metode replace string untuk menyoroti kueri pencarian. Kita membungkus kueri pencarian dengan tag <mark>. Kita juga menggunakan modul re (ekspresi reguler) untuk melakukan penggantian yang tidak sensitif huruf besar/kecil. Ini memastikan bahwa semua kemunculan kueri, terlepas dari huruf besar/kecil, disorot.

5. Meningkatkan Logika Pencarian (Opsional)

Logika pencarian dasar yang telah kita implementasikan sejauh ini berfungsi, tetapi dapat ditingkatkan. Misalnya, kita dapat menggunakan ekspresi reguler untuk pencarian yang lebih canggih atau mengindeks kode untuk pencarian yang lebih cepat.

5.1 Menggunakan Ekspresi Reguler

Ekspresi reguler adalah cara yang ampuh untuk mencocokkan pola dalam teks. Mereka dapat digunakan untuk mencari pola yang kompleks yang tidak dapat dicocokkan menggunakan pencocokan string dasar.

Misalnya, kita dapat menggunakan ekspresi reguler untuk mencari semua baris kode yang berisi nomor telepon. Untuk melakukan ini, kita dapat menggunakan ekspresi reguler berikut:

\d{3}-\d{3}-\d{4}

Ekspresi reguler ini cocok dengan string tiga digit, diikuti oleh tanda hubung, diikuti oleh tiga digit, diikuti oleh tanda hubung, diikuti oleh empat digit.

Untuk menggunakan ekspresi reguler dalam alat pencarian kode kita, kita perlu mengimpor modul re dan menggunakan fungsi re.search.

Berikut adalah contoh bagaimana menggunakan ekspresi reguler untuk mencari nomor telepon:

import re

def search(file_list, query, case_sensitive=False, use_regex=False):
    """Mencari kueri dalam daftar file dan mengembalikan daftar hasil."""
    results = []
    for file_data in file_list:
        filename = file_data['filename']
        content = file_data['content']
        lines = content.splitlines()
        for i, line in enumerate(lines):
            if use_regex:
                if re.search(query, line, re.IGNORECASE if not case_sensitive else 0):
                    highlighted_line = re.sub(re.compile(query, re.IGNORECASE if not case_sensitive else 0), r'<mark>\g<0></mark>', line)
                    results.append({
                        'filename': filename,
                        'line_number': i + 1,
                        'line': highlighted_line
                    })

            elif case_sensitive:
                if query in line:
                    highlighted_line = line.replace(query, f'<mark>{query}</mark>')
                    results.append({
                        'filename': filename,
                        'line_number': i + 1,
                        'line': highlighted_line
                    })
            else:
                if query.lower() in line.lower():
                    highlighted_line = re.sub(re.compile(re.escape(query), re.IGNORECASE), r'<mark>\g<0></mark>', line)
                    results.append({
                        'filename': filename,
                        'line_number': i + 1,
                        'line': highlighted_line
                    })
    return results

Kita menambahkan parameter baru ke fungsi search bernama use_regex. Jika parameter ini diatur ke True, kita menggunakan fungsi re.search untuk mencari kueri pencarian.

5.2 Mengindeks Kode untuk Pencarian Lebih Cepat (misalnya, menggunakan Whoosh atau Bleve)

Jika Anda memiliki basis kode yang besar, mencari kode dapat memakan waktu. Untuk mempercepat pencarian, Anda dapat mengindeks kode. Pengindeksan kode melibatkan pembuatan indeks yang berisi semua kata dalam kode. Indeks ini kemudian dapat digunakan untuk dengan cepat menemukan semua file yang berisi kata tertentu.

Ada beberapa pustaka yang dapat Anda gunakan untuk mengindeks kode, termasuk Whoosh dan Bleve. Whoosh adalah pustaka pencarian teks Python cepat dan murni. Bleve adalah pustaka pengindeksan dan pencarian teks lengkap Go.

Karena artikel ini terutama berfokus pada Flask, kita tidak akan membahas pengindeksan secara mendalam. Namun, konsep intinya adalah:

  1. Indeks Kode: Saat aplikasi dimulai, gunakan pustaka seperti Whoosh atau Bleve untuk memindai direktori kode Anda dan membuat indeks dari konten.
  2. Cari Indeks: Alih-alih mencari langsung file, cari indeks. Pustaka pencarian menyediakan cara efisien untuk menemukan dokumen yang sesuai dengan kueri Anda.
  3. Kembalikan Hasil: Gunakan hasil dari indeks untuk mengambil baris kode yang sesuai dari file sumber asli dan menampilkannya kepada pengguna.

Pengindeksan secara signifikan meningkatkan kinerja pencarian, terutama untuk basis kode yang besar, tetapi menambah kompleksitas pada aplikasi Anda.

6. Integrasi Backend Flask

Sekarang kita telah mengimplementasikan logika pencarian, kita perlu mengintegrasikannya dengan backend Flask. Ini melibatkan pembuatan rute Flask untuk menangani permintaan pencarian, menerima kueri pencarian dari formulir, memanggil logika pencarian, dan mengirimkan hasil ke template.

Buat file baru bernama app.py di direktori root proyek Anda. File ini akan berisi aplikasi Flask.

from flask import Flask, render_template, request
import os
import re

app = Flask(__name__)

# Konfigurasi: Tentukan direktori kode yang akan dicari
CODE_DIRECTORY = 'path/ke/direktori/kode/anda' # Ganti dengan path aktual

def read_files(directory):
    """Membaca semua file dari direktori dan mengembalikan daftar file."""
    file_list = []
    for root, _, files in os.walk(directory):
        for file in files:
            file_path = os.path.join(root, file)
            try:
                with open(file_path, 'r', encoding='utf-8') as f:
                    file_list.append({'filename': file_path, 'content': f.read()})
            except Exception as e:
                print(f"Gagal membaca file {file_path}: {e}")
    return file_list

def search(file_list, query, case_sensitive=False, use_regex=False):
    """Mencari kueri dalam daftar file dan mengembalikan daftar hasil."""
    results = []
    for file_data in file_list:
        filename = file_data['filename']
        content = file_data['content']
        lines = content.splitlines()
        for i, line in enumerate(lines):
            if use_regex:
                if re.search(query, line, re.IGNORECASE if not case_sensitive else 0):
                    highlighted_line = re.sub(re.compile(query, re.IGNORECASE if not case_sensitive else 0), r'<mark>\g<0></mark>', line)
                    results.append({
                        'filename': filename,
                        'line_number': i + 1,
                        'line': highlighted_line
                    })

            elif case_sensitive:
                if query in line:
                    highlighted_line = line.replace(query, f'<mark>{query}</mark>')
                    results.append({
                        'filename': filename,
                        'line_number': i + 1,
                        'line': highlighted_line
                    })
            else:
                if query.lower() in line.lower():
                    highlighted_line = re.sub(re.compile(re.escape(query), re.IGNORECASE), r'<mark>\g<0></mark>', line)
                    results.append({
                        'filename': filename,
                        'line_number': i + 1,
                        'line': highlighted_line
                    })
    return results

@app.route('/', methods=['GET', 'POST'])
def index():
    """Menangani permintaan pencarian dan menampilkan hasilnya."""
    results = []
    if request.method == 'POST':
        query = request.form['query']
        case_sensitive = request.form.get('case_sensitive') == 'on' # Mengambil checkbox value
        use_regex = request.form.get('use_regex') == 'on' # Mengambil checkbox value

        file_list = read_files(CODE_DIRECTORY)
        results = search(file_list, query, case_sensitive, use_regex)

    return render_template('index.html', results=results)

if __name__ == '__main__':
    app.run(debug=True)

Berikut adalah penjelasan dari kode:

  • from flask import Flask, render_template, request: Mengimpor kelas Flask, fungsi render_template, dan objek request dari modul flask.
  • app = Flask(__name__): Membuat instance baru dari kelas Flask.
  • CODE_DIRECTORY = 'path/ke/direktori/kode/anda': Menentukan direktori kode yang akan dicari. Ganti 'path/ke/direktori/kode/anda' dengan jalur aktual ke direktori kode Anda.
  • read_files(directory): Fungsi yang membaca semua file dari direktori dan mengembalikan daftar file.
  • search(file_list, query, case_sensitive=False): Fungsi yang mencari kueri dalam daftar file dan mengembalikan daftar hasil.
  • @app.route('/', methods=['GET', 'POST']): Mendekorasi fungsi index dengan dekorator @app.route. Ini menetapkan fungsi index ke rute /. Atribut methods menentukan bahwa fungsi index dapat menangani permintaan GET dan POST.
  • def index(): Fungsi yang menangani permintaan pencarian dan menampilkan hasilnya.
  • if request.method == 'POST': Memeriksa apakah metode permintaan adalah POST. Jika demikian, pengguna telah mengirimkan formulir pencarian.
  • query = request.form['query']: Mendapatkan kueri pencarian dari formulir.
  • file_list = read_files(CODE_DIRECTORY): Membaca file kode dari direktori.
  • results = search(file_list, query): Mencari kueri dalam file kode.
  • return render_template('index.html', results=results): Menampilkan template index.html dan meneruskan hasil pencarian ke template.
  • if __name__ == '__main__':: Memeriksa apakah file sedang dijalankan sebagai program utama. Jika demikian, jalankan aplikasi Flask.
  • app.run(debug=True): Menjalankan aplikasi Flask dalam mode debug.

Jangan lupa untuk mengganti 'path/ke/direktori/kode/anda' di variabel CODE_DIRECTORY dengan jalur aktual ke direktori kode Anda.

Selanjutnya, modifikasi `index.html` untuk menyertakan kotak centang untuk kontrol sensitif huruf besar/kecil dan ekspresi reguler:

<!DOCTYPE html>
<html>
<head>
<title>Pencarian Kode</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<h1>Pencarian Kode</h1>

<form method="POST">
<input type="text" name="query" placeholder="Masukkan kueri pencarian Anda">
<input type="checkbox" name="case_sensitive"> Sensitif Huruf Besar/Kecil<br>
<input type="checkbox" name="use_regex"> Ekspresi Reguler<br>
<button type="submit">Cari</button>
</form>

<div id="results">
{% if results %}
<h2>Hasil:</h2>
<ul>
{% for result in results %}
<li>
<strong>File:</strong> {{ result.filename }}<br>
<strong>Baris:</strong> {{ result.line_number }}<br>
<pre><code>{{ result.line }}</code></pre>
</li>
{% endfor %}
</ul>
{% endif %}
</div>
</body>
</html>

omcoding

Leave a Reply

Your email address will not be published. Required fields are marked *