pyproc 0.2__py3-none-any.whl

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.
pyproc/text.py ADDED
@@ -0,0 +1,43 @@
1
+ from pyproc import __version__
2
+
3
+ ##########################
4
+ # downloader header logo #
5
+ ##########################
6
+ INFO = r''' ____ ____
7
+ / __ \__ __/ __ \_________ _____
8
+ / /_/ / / / / /_/ / ___/ __ \/ ___/
9
+ / ____/ /_/ / ____/ / / /_/ / /__
10
+ /_/ \__, /_/ /_/ \____/\___/
11
+ /____/
12
+ SPSE4 Downloader, PyProc v{}
13
+ '''.format(__version__)
14
+
15
+ ##############################
16
+ # argument help text #
17
+ ##############################
18
+ HELP_KEYWORD = "filter pencarian index paket berdasarkan kata kunci tertentu"
19
+ HELP_TAHUN_ANGGARAN = "filter download detail berdasarkan tahun anggaran. Format tahun anggaran bisa " \
20
+ "dilihat di dokumentasi"
21
+ HELP_CHUNK_SIZE = "jumlah daftar index per-halaman yang diunduh dalam satu iterasi"
22
+ HELP_WORKERS = "jumlah workers untuk mengunduh detil paket secara paralel"
23
+ HELP_TIMEOUT = "besaran waktu timeout untuk menunggu respon dari server"
24
+ HELP_NONTENDER = "flag untuk mengunduh data paket pengadaan langsung"
25
+ HELP_INDEX_DOWNLOAD_DELAY = "waktu delay untuk setiap iterasi halaman index dalam detik"
26
+ HELP_KEEP = "tidak menghapus working direktori dari downloader"
27
+ HELP_LPSE_HOST = "host LPSE atau file teks berisi daftar host LPSE. Format dapat dilihat di dokumentasi"
28
+ HELP_LOG_LEVEL = "Set log level"
29
+ HELP_KATEGORI = "filter pencarian index paket berdasarkan kategori"
30
+ HELP_PENYEDIA = "filter pencarian index paket berdasarkan nama penyedia"
31
+ HELP_OUTPUT = "format output hasil download"
32
+ HELP_RESUME = "melanjutkan proses sebelumnya"
33
+ HELP_CSV_SEPARATOR = "set custom csv separator, default koma"
34
+ HELP_DAFTARHOST = "unduh daftar host LPSE dalam format JSON dari GitHub Gist"
35
+
36
+ #####################
37
+ # Error Information #
38
+ #####################
39
+
40
+ ERROR_CTX_TAHUN_ANGGARAN = "Gagal parsing tahun anggaran, format yang diperbolehkan X-Y atau X;Y;Z"
41
+ ERROR_CTX_RANGE_TAHUN = "Nilai tahun harus di antara 2000 dan {}"
42
+ ERROR_CTX_HOST_SKEMA = "Skema URL tidak ditemukan. URL harus diawali http/https"
43
+ ERROR_CTX_HOST_FORMAT = "Argumen host `{}` tidak sesuai format"
pyproc/utils.py ADDED
@@ -0,0 +1,90 @@
1
+ import csv
2
+ import json
3
+ import os
4
+ import re
5
+ import requests
6
+ from bs4 import BeautifulSoup
7
+ from urllib.parse import urlparse
8
+
9
+ TOKEN_FORMAT = re.compile(r"d\.authenticityToken[\s+]=[\s+]['\"]([0-9a-zA-Z]+)['\"];", re.DOTALL)
10
+
11
+ GIST_HOST_URL = 'https://gist.githubusercontent.com/wakataw/54d206da0e6238253d364b04bb149cdd/raw'
12
+
13
+
14
+ def parse_token(page):
15
+ token = TOKEN_FORMAT.findall(page)
16
+
17
+ if token:
18
+ return token[0]
19
+
20
+ return
21
+
22
+
23
+ def get_all_host():
24
+ resp = requests.get('https://satudata.inaproc.id/service/daftarLPSE', timeout=10)
25
+ data = json.loads(resp.content)
26
+
27
+ return data
28
+
29
+
30
+ def download_host(logging, name='daftarlpse.csv'):
31
+ data = get_all_host()
32
+ hosts = dict()
33
+ invalid_host = 0
34
+
35
+ for item in data:
36
+ try:
37
+ url = item['repo_url4']
38
+ except KeyError:
39
+ url = item['repo_url']
40
+
41
+ parsed_url = urlparse(url)
42
+
43
+ if not parsed_url.scheme.startswith('http'):
44
+ invalid_host += 1
45
+ continue
46
+
47
+ hosts[url] = str(item['repo_id']) + '-' + \
48
+ ' '.join([i for i in re.sub(r'[^a-zA-Z\d\s]', ' ', item['repo_nama']).split() if i.strip() != ''])
49
+
50
+ logging.info(
51
+ "{} alamat LPSE ditemukan. {} alamat valid, {} alamat tidak valid, {} alamat terduplikasi.".format(
52
+ len(data), len(hosts), invalid_host, len(data) - len(hosts) - invalid_host
53
+ )
54
+ )
55
+ logging.debug(hosts)
56
+
57
+ with open(name, 'w', newline='', encoding='utf-8') as f:
58
+ writer = csv.writer(f, delimiter=';')
59
+ for k, v in hosts.items():
60
+ writer.writerow([k, v])
61
+
62
+ logging.info("Export daftar lpse ke {}".format(name))
63
+
64
+
65
+ def download_host_json(logging, name='host.json', directory='.'):
66
+ """
67
+ Download host.json dari GitHub Gist
68
+ :param logging: logging module
69
+ :param name: nama file output
70
+ :param directory: direktori output
71
+ :return: data host dalam format list
72
+ """
73
+ resp = requests.get(GIST_HOST_URL, timeout=30)
74
+ resp.raise_for_status()
75
+
76
+ data = resp.json()
77
+
78
+ filepath = os.path.join(directory, name)
79
+
80
+ with open(filepath, 'w', encoding='utf-8') as f:
81
+ json.dump(data, f, indent=2, ensure_ascii=False)
82
+
83
+ logging.info("Export host.json ke {}".format(filepath))
84
+
85
+ return data
86
+
87
+
88
+ def parse_version(version):
89
+ version = tuple(map(int, re.findall(r'(?P<major>\d+).(?P<minor>\d+)u(?P<patch>\d{8})', version)[0]))
90
+ return version
@@ -0,0 +1,210 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyproc
3
+ Version: 0.2
4
+ Summary: Python Inaproc SPSE SDK
5
+ Project-URL: Homepage, https://github.com/wakataw/pyproc
6
+ Project-URL: Issues, https://github.com/wakataw/pyproc/issues
7
+ Author-email: Agung Pratama <workwithagung@gmail.com>
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Natural Language :: English
14
+ Classifier: Natural Language :: Indonesian
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3.7
17
+ Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content :: CGI Tools/Libraries
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Classifier: Topic :: Utilities
20
+ Requires-Python: >=3.9
21
+ Requires-Dist: backoff
22
+ Requires-Dist: beautifulsoup4
23
+ Requires-Dist: html5lib
24
+ Requires-Dist: requests
25
+ Description-Content-Type: text/markdown
26
+
27
+ # PyProc
28
+
29
+ ![Build Status](https://github.com/wakataw/pyproc/actions/workflows/pyproc-pypi.yml/badge.svg) [![Version](https://img.shields.io/badge/version-v0.2a-red)](https://pypi.org/project/pyproc/) [![Python >=3.9](https://img.shields.io/badge/python->=3.9-yellow.svg)](https://www.python.org/downloads/) [![Open Source Love](https://badges.frapsoft.com/os/v1/open-source.svg?v=102)](https://github.com/wakataw/pyproc)
30
+
31
+ PyProc (Python Procurement) merupakan wrapper untuk API SPSE yang ditulis dalam bahasa Python. Sistem Pengadaan Secara Elektronik (SPSE) SPSE merupakan aplikasi e-Procurement yang dikembangkan oleh LKPP untuk digunakan oleh LPSE di instansi pemerintah seluruh Indonesia.
32
+
33
+ > DISCLAIMER:
34
+ >
35
+ > Penulis tidak terafiliasi dengan pengembang SPSE atau pemilik aplikasi SPSE. Software ini dikembangkan dengan tujuan akademis, bentuk pengawasan oleh masyarakat, dan membantu pengusaha untuk mempermudah otomasi perolehan informasi pengadaan dari pemerintah.
36
+ >
37
+ > Penggunaan yang tidak wajar dan mengganggu sebagian atau seluruh fungsi aplikasi SPSE pada satuan kerja menjadi tanggung jawab masing-masing pengguna.
38
+ >
39
+ > PyProc ada karena SPSE ada, jadi gunakanlah dengan bijak dan secukupnya.
40
+
41
+ ## Pemasangan
42
+
43
+ Pemasangan PyProc via `pip`:
44
+ ```bash
45
+ $ pip install pyproc
46
+ ```
47
+
48
+ Upgrade PyProc via `pip`:
49
+ ```bash
50
+ $ pip install pyproc --upgrade
51
+ ```
52
+
53
+ Instalasi versi unstable:
54
+ ```bash
55
+ $ pip install git+https://github.com/wakataw/pyproc.git
56
+ ```
57
+
58
+ ## Penggunaan Command Line Interface
59
+
60
+ ### Download Data LPSE
61
+ Format Command
62
+ ```bash
63
+ $ pyproc [ARGUMENT] DAFTAR_LPSE
64
+ ```
65
+ **Arguments**
66
+
67
+ | argumen | contoh | diperlukan | default | keterangan |
68
+ |-----------------------------|---------------------------------------------|------------|----------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
69
+ | `DAFTAR_LPSE` | `pyproc pu` | Ya | - | Daftar alamat LPSE yang akan diunduh. <br>[Format Daftar LPSE](#format-daftar-lpse-lanjutan) |
70
+ | `-h --help` | `pyproc --help` | optional | - | menampilkan keterangan dan bantuan |
71
+ | `-k --keyword` | `pyproc --keyword "mobil dinas" ...` | optional | - | filter pencarian index paket berdasarkan kata kunci tertentu |
72
+ | `-t --tahun-anggaran` | `pyproc --tahun-anggaran 2021 ...` | optional | Tahun Berjalan | Filter pencarian index paket berdasarkan tahun anggaran tertentu. Fungsi ini hanya berlaku mulai dari SPSE 4.4. <br><br>Format Penulisan: <br>**ALL**: mengunduh seluruh data <br>**2021**: mengunduh data untuk tahun 2021 <br>**2015,2018,2019**: mengunduh data untuk tahun 2015, 2018, dan 2019<br>**2011-2020** mengunduh data untuk tahun 2011 s.d. 2020 |
73
+ | `--kategori` | `pyproc --kategori PENGADAAN_BARANG ...` | optional | - | Filter pencarian berdasarkan kategori pengadaan. <br>Daftar kategori: `PENGADAAN_BARANG`, `JASA_KONSULTANSI_BADAN_USAHA_NON_KONSTRUKSI`, `PEKERJAAN_KONSTRUKSI`, `JASA_LAINNYA`, `JASA_KONSULTANSI_PERORANGAN`, `JASA_KONSULTANSI_BADAN_USAHA_KONSTRUKSI` |
74
+ | `--nama-penyedia` | `pyproc --nama-penyedia "PT SUKA MAJU" ...` | optional | - | Filter pencarian index paket berdasarkan nama penyedia |
75
+ | `-c --chunk-size` | `pyproc --chunk-size 25 ...` | optional | 25 | Jumlah daftar paket per halaman yang diunduh. Semakin besar jumlah tidak menjamin proses download semakin cepat. Gunakanlah jumlah data yang wajar sehingga tidak membebani server SPSE. |
76
+ | `-w --workers` | `pyproc --workers 4 ...` | optional | 8 | Jumlah koneksi yang berjalan secara bersamaan saat mengunduh detil paket dengan maksimal 10 worker. |
77
+ | `-x --timeout` | `pyproc --timeout 60 ...` | optional | 30 | Waktu tunggu jika koneksi lambat (dalam detik) |
78
+ | `-n --non-tender` | `pyproc --non-tender ...` | optional | FALSE | Tambahkan argumen ini untuk mengunduh data non-tender/pengadaan langsung |
79
+ | `-d --index-download-delay` | `pyproc --index-download-delay 5 ...` | optional | 1 | Waktu jeda download index paket untuk setiap halaman/batch |
80
+ | `-o --output` | `pyproc --ouput csv ...` | optional | csv | Jenis data keluaran/hasil dari download. Format yang didukung csv dan json. Karena keterbatasan format, tidak semua data ditampilkan pada format csv. Jika memerlukan data detil yang komprehensif, gunakan format json karena mencangkup semua data detail. |
81
+ | `--keep-index` | `pyproc --keep-index ...` | optinal | FALSE | pyproc akan membentuk file idx (sqlite3 database) saat proses download dan akan dihapus ketika proses selesai. Tambahkan argumen ini jika tidak ingin menghapus database tersebut. |
82
+ | `-r --resume` | `pyproc --resume ...` | optinal | FALSE | Tambahkan argument ini untuk melanjutkan proses yang gagal (karena internet putus atau gangguan koneksi lainnya). Namun pastikan bahwa seluruh index sudah berhasil diunduh karena argumen --resume akan melewati proses download index. |
83
+ | `-s --sep` | `pyproc --sep ";" kemenkeu` | optional | `;` titik koma | Set custom separator untuk output format csv |
84
+ | `--log` | `pyproc --log INFO ...` | optional | INFO | Argumen untuk setting informasi yang ditampilkan pyproc pada terminal. Daftar nilai yang didukung: <br>`DEBUG`: menampilkan informasi sedetil mungkin<br>`INFO`: menampilkan informasi penting saja <br>`WARNING`: hanya menampilkan informasi yang bersifat warning <br>`ERROR`: hanya menampilkan error <br>`CRITICAL`: hanya menampilkan permasalahan yang bersifat kritis saja |
85
+
86
+ ### Format Daftar LPSE (lanjutan)
87
+ PyProc dapat mengunduh data dari 1 atau lebih LPSE. Proses tersebut akan berjalan sesuai dengan nilai `DAFTAR_LPSE` yang diberikan user. Beberapa format yang didukung oleh PyProc adalah sebagai berikut:
88
+ - Download data dengan menyertakan nama file hasil download
89
+
90
+ Untuk set nama file secara manual, gunakan format `"alamatlpse[titik_koma]namafile"`.
91
+
92
+ ```bash
93
+ $ pyproc "kemenkeu;namafileouputkemenkeu" --output json
94
+ ```
95
+
96
+ perintah ini akan mengunduh data LPSE PU dan mengekspor data ke file `namafileouputkemenkeu.json`
97
+
98
+ - Download data lebih dari 1 LPSE
99
+
100
+ Untuk mengunduh lebih dari 1 lpse secara bersamaan, gunakan format `"alamat1[koma]alamat2[koma]alamat3"`
101
+
102
+ ```bash
103
+ $ pyproc jakarta,pu,kemenkeu,sumbarprov
104
+ ```
105
+
106
+ atau dengan menyertakan namafile dengan format `"alamat1[titikkoma]nama1[koma]alamat2[titikkoma]nama2"`
107
+
108
+ ```bash
109
+ $ pyproc "jakarta;filejakarta,pu:filepu,kemenkeu:filekemenkeu,sumbarprov:filesumbarprov"
110
+ ```
111
+
112
+ - Download data berdasrakan daftar lpse pada file csv
113
+ Download paket LPSE dengan sumber alamat dari file
114
+ ```bash
115
+ $ pyproc daftarlpse.csv
116
+
117
+ # konten daftarlpse.csv
118
+ sumbarprov
119
+ pu
120
+ kemenkeu
121
+
122
+ # konten daftarlpse.csv dengan nama hasil download
123
+ sumbarprov;lpse-sumbar
124
+ pu;lpse-pu.csv
125
+ kemenkeu;lpse-kemenkeu
126
+ ```
127
+
128
+ ## Penggunaan PyProc Sebagai Package
129
+
130
+ Untuk dapat menggunakan PyProc, anda harus mengimpornya terlebih dahulu dan menginisiasi objek `Lpse`
131
+
132
+ ```python
133
+ from pyproc import Lpse
134
+
135
+ # Inisiasi objek lpse kementerian pu
136
+ lpse = Lpse('kemenkeu')
137
+ ```
138
+
139
+ ### Pencarian Daftar Paket Lelang
140
+
141
+ ```python
142
+ from pyproc import Lpse
143
+
144
+ # Inisiasi objek lpse kementerian pu
145
+ lpse = Lpse('pu')
146
+
147
+ # mendapatkan daftar paket lelang
148
+ daftar_lelang = lpse.get_paket_tender(start=0, length=2)
149
+ print(daftar_lelang)
150
+
151
+ # pencarian paket non tender (penunjukkan langsung)
152
+ daftar_pl = lpse.get_paket_non_tender(start=0, length=30)
153
+ ```
154
+
155
+ Pencarian Paket dengan mengurutkan berdasarkan kolom tertentu
156
+ ```python
157
+ from pyproc import Lpse
158
+ from pyproc.lpse import By
159
+
160
+ lpse = Lpse('sumbarprov')
161
+
162
+ # pencarian daftar lelang, urutkan berdasarkan Harga Perkiraan Sendiri
163
+ daftar_lelang = lpse.get_paket_tender(start=0, length=30, order=By.HPS)
164
+ ```
165
+
166
+ Filter pencarian paket berdasarkan kategori pengadaan
167
+ ```python
168
+ from pyproc import Lpse
169
+ from pyproc import JenisPengadaan
170
+
171
+ # Inisiasi objek lpse kementerian padang
172
+ lpse = Lpse('padang')
173
+
174
+ # Kategori Pengadaan Barang
175
+ paket_pengadaan_barang = lpse.get_paket_tender(start=0, length=30, kategori=JenisPengadaan.PENGADAAN_BARANG)
176
+ paket_konstruksi = lpse.get_paket_tender(start=0, length=30, kategori=JenisPengadaan.PEKERJAAN_KONSTRUKSI)
177
+
178
+ # dst untuk kategori lainnya
179
+ ```
180
+
181
+ ### Pencarian Detil Paket Lelang
182
+
183
+ ```python
184
+ from pyproc import Lpse
185
+
186
+ lpse = Lpse('jakarta')
187
+
188
+ # mendapatkan semua detil paket lelang
189
+ detil = lpse.detil_paket_tender(id_paket='48658064')
190
+ detil.get_all_detil()
191
+ print(detil)
192
+
193
+ # mendapatkan hanya pemenang lelang
194
+ pemenang = detil.get_pemenang()
195
+ print(pemenang)
196
+ ```
197
+
198
+ ## Uninstall
199
+
200
+ Untuk uninstall package jalankan perintah berikut:
201
+ ```bash
202
+ $ pip uninstall pyproc
203
+ ```
204
+
205
+ ## License
206
+ Paket ini di-release di bawah lisensi MIT.
207
+
208
+ ## Donatur ☕️
209
+ Orang-orang yang berjasa menyediakan kopi sehingga pengembangan paket tetap berjalan
210
+ - Angga Rinaldi Rizal (50 cangkir ☕️)
@@ -0,0 +1,11 @@
1
+ pyproc/__init__.py,sha256=oUNs1ROR3mZLwROgZpd5GOHweJ2IJHwG8qTQGeoXJ2w,166
2
+ pyproc/cli.py,sha256=tOoF0tkpDmLOwhCZnCYu3WZ-otZ2r_xwOYgBUdz_Dho,29461
3
+ pyproc/exceptions.py,sha256=oHyyaMOHgcXpp8LVNBaA8aaPQ_4oQSdDjAJCJ2Q_ya8,253
4
+ pyproc/lpse.py,sha256=nuYF1SJCpz978pDJTMCBasa0OFiATDPbUTF62zb377k,26699
5
+ pyproc/text.py,sha256=9yXb2-bQP9-leRH53auDfzw-_gmpyn68xZR0gwOdzKw,2072
6
+ pyproc/utils.py,sha256=UytDEWFysNLrUVf4vVqPArf--9XNZjO981fjMpGUlHQ,2411
7
+ pyproc-0.2.dist-info/METADATA,sha256=pW-zbKwm52XmzsqkTmHKvxY9byTDDy8LKMwZOPGs384,14509
8
+ pyproc-0.2.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
9
+ pyproc-0.2.dist-info/entry_points.txt,sha256=_6NwgkmldADRsms3o0g0N37UyT9YSnMC3t36dhqKCjc,43
10
+ pyproc-0.2.dist-info/licenses/LICENSE,sha256=I5Vk0AXqGRx6u6rKxBqX0Fku8T-qFo5evTgLAwdBsjc,1070
11
+ pyproc-0.2.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ pyproc = pyproc.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Agung Pratama
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.