Update data/data.py
Browse files- data/data.py +207 -205
data/data.py
CHANGED
@@ -1,206 +1,208 @@
|
|
1 |
-
import os
|
2 |
-
import requests
|
3 |
-
import pandas as pd
|
4 |
-
from plotly.subplots import make_subplots
|
5 |
-
import threading
|
6 |
-
import plotly
|
7 |
-
import plotly.graph_objects as go
|
8 |
-
from tqdm import tqdm
|
9 |
-
from datetime import datetime
|
10 |
-
import pytz
|
11 |
-
import json
|
12 |
-
import base64
|
13 |
-
|
14 |
-
plotly.io.defaults.default_height = 720
|
15 |
-
plotly.io.defaults.default_width = 1440
|
16 |
-
|
17 |
-
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN")
|
18 |
-
OWNER = os.getenv("OWNER")
|
19 |
-
REPO = os.getenv("REPO")
|
20 |
-
|
21 |
-
HEADERS = {
|
22 |
-
"Authorization": f"token {GITHUB_TOKEN}",
|
23 |
-
}
|
24 |
-
|
25 |
-
FILEPATH = "data/data.json"
|
26 |
-
FILEURL = f"https://api.github.com/repos/{OWNER}/{REPO}/contents/{FILEPATH}"
|
27 |
-
|
28 |
-
def puf(filepath, content):
|
29 |
-
fileurl = f"https://api.github.com/repos/{OWNER}/{REPO}/contents/{filepath}"
|
30 |
-
|
31 |
-
response = requests.get(fileurl, headers=HEADERS)
|
32 |
-
is_update = response.status_code == 200
|
33 |
-
res = response.json()
|
34 |
-
sha = res["sha"] if is_update else None
|
35 |
-
|
36 |
-
if is_update and content == res: return
|
37 |
-
|
38 |
-
data = {
|
39 |
-
"message": "Update" if is_update else "Upload",
|
40 |
-
"content": base64.b64encode(
|
41 |
-
content.encode() if isinstance(content, str) else content
|
42 |
-
).decode()
|
43 |
-
}
|
44 |
-
if is_update: data["sha"] = sha
|
45 |
-
|
46 |
-
resp = requests.put(fileurl, headers=HEADERS, json=data)
|
47 |
-
print("β
Upload success" if resp.ok else f"β Error: {resp.text}")
|
48 |
-
|
49 |
-
uf = lambda filepath, content: threading.Thread(target=puf, args=(filepath, content)).start()
|
50 |
-
|
51 |
-
rf = lambda: json.loads(base64.b64decode(response.json()['content']).decode() if (response := requests.get(FILEURL, headers=HEADERS)).status_code == 200 else "{}")
|
52 |
-
ir = lambda d=None: (d or rf() != {})
|
53 |
-
|
54 |
-
lhs = [7, 15, 30, 60, 90, 120, 240, 365, 1000, 1440]
|
55 |
-
|
56 |
-
header_fill_color = [
|
57 |
-
"#d9d9d9", # No - abu netral
|
58 |
-
"#add8e6", # Tgl Beli - biru muda (tanggal = waktu)
|
59 |
-
"#9be7a3", # Harga Beli/g - hijau terang (uang masuk)
|
60 |
-
"#fdd9a0", # Berat - oranye terang (fisik)
|
61 |
-
"#f4b6c2", # Modal - merah muda (biaya awal)
|
62 |
-
"#87cefa", # Tgl Jual - biru langit (tanggal = waktu)
|
63 |
-
"#b2fab4", # Harga Jual/g - hijau pastel (uang keluar / potensi untung)
|
64 |
-
"#fff5ba", # Nilai Jual - kuning pastel (nilai total)
|
65 |
-
"#ffadc1", # Profit/Loss - merah muda (untung/rugi)
|
66 |
-
]
|
67 |
-
|
68 |
-
cells_fill_color = [
|
69 |
-
"#eeeeee", # No - abu netral lebih lembut
|
70 |
-
"#e6f2ff", # Tgl Beli
|
71 |
-
"#d5fbe3", # Harga Beli/g
|
72 |
-
"#ffecd9", # Berat
|
73 |
-
"#ffe0e8", # Modal
|
74 |
-
"#e0f2ff", # Tgl Jual
|
75 |
-
"#dcfce7", # Harga Jual/g
|
76 |
-
"#fff9db", # Nilai Jual
|
77 |
-
"#ffe6ef", # Profit/Loss
|
78 |
-
]
|
79 |
-
|
80 |
-
data = None
|
81 |
-
data_dir = "data"
|
82 |
-
data_path = os.path.join(data_dir, "data.json")
|
83 |
-
os.makedirs(data_dir, exist_ok=True)
|
84 |
-
|
85 |
-
makeslcy = lambda x: -0.575 - (7 - x) * (0.575 / 7) * 5
|
86 |
-
|
87 |
-
data = None
|
88 |
-
|
89 |
-
def ambil_data_emas():
|
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 |
-
"2025-
|
164 |
-
"2025-
|
165 |
-
"2025-06-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
1
|
172 |
-
0.
|
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 |
timestamp_lokal = dt_wib.strftime("%d %B %Y, %H:%M WIB")
|
|
|
1 |
+
import os
|
2 |
+
import requests
|
3 |
+
import pandas as pd
|
4 |
+
from plotly.subplots import make_subplots
|
5 |
+
import threading
|
6 |
+
import plotly
|
7 |
+
import plotly.graph_objects as go
|
8 |
+
from tqdm import tqdm
|
9 |
+
from datetime import datetime
|
10 |
+
import pytz
|
11 |
+
import json
|
12 |
+
import base64
|
13 |
+
|
14 |
+
plotly.io.defaults.default_height = 720
|
15 |
+
plotly.io.defaults.default_width = 1440
|
16 |
+
|
17 |
+
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN")
|
18 |
+
OWNER = os.getenv("OWNER")
|
19 |
+
REPO = os.getenv("REPO")
|
20 |
+
|
21 |
+
HEADERS = {
|
22 |
+
"Authorization": f"token {GITHUB_TOKEN}",
|
23 |
+
}
|
24 |
+
|
25 |
+
FILEPATH = "data/data.json"
|
26 |
+
FILEURL = f"https://api.github.com/repos/{OWNER}/{REPO}/contents/{FILEPATH}"
|
27 |
+
|
28 |
+
def puf(filepath, content):
|
29 |
+
fileurl = f"https://api.github.com/repos/{OWNER}/{REPO}/contents/{filepath}"
|
30 |
+
|
31 |
+
response = requests.get(fileurl, headers=HEADERS)
|
32 |
+
is_update = response.status_code == 200
|
33 |
+
res = response.json()
|
34 |
+
sha = res["sha"] if is_update else None
|
35 |
+
|
36 |
+
if is_update and content == res: return
|
37 |
+
|
38 |
+
data = {
|
39 |
+
"message": "Update" if is_update else "Upload",
|
40 |
+
"content": base64.b64encode(
|
41 |
+
content.encode() if isinstance(content, str) else content
|
42 |
+
).decode()
|
43 |
+
}
|
44 |
+
if is_update: data["sha"] = sha
|
45 |
+
|
46 |
+
resp = requests.put(fileurl, headers=HEADERS, json=data)
|
47 |
+
print("β
Upload success" if resp.ok else f"β Error: {resp.text}")
|
48 |
+
|
49 |
+
uf = lambda filepath, content: threading.Thread(target=puf, args=(filepath, content)).start()
|
50 |
+
|
51 |
+
rf = lambda: json.loads(base64.b64decode(response.json()['content']).decode() if (response := requests.get(FILEURL, headers=HEADERS)).status_code == 200 else "{}")
|
52 |
+
ir = lambda d=None: (d or rf() != {})
|
53 |
+
|
54 |
+
lhs = [7, 15, 30, 60, 90, 120, 240, 365, 1000, 1440]
|
55 |
+
|
56 |
+
header_fill_color = [
|
57 |
+
"#d9d9d9", # No - abu netral
|
58 |
+
"#add8e6", # Tgl Beli - biru muda (tanggal = waktu)
|
59 |
+
"#9be7a3", # Harga Beli/g - hijau terang (uang masuk)
|
60 |
+
"#fdd9a0", # Berat - oranye terang (fisik)
|
61 |
+
"#f4b6c2", # Modal - merah muda (biaya awal)
|
62 |
+
"#87cefa", # Tgl Jual - biru langit (tanggal = waktu)
|
63 |
+
"#b2fab4", # Harga Jual/g - hijau pastel (uang keluar / potensi untung)
|
64 |
+
"#fff5ba", # Nilai Jual - kuning pastel (nilai total)
|
65 |
+
"#ffadc1", # Profit/Loss - merah muda (untung/rugi)
|
66 |
+
]
|
67 |
+
|
68 |
+
cells_fill_color = [
|
69 |
+
"#eeeeee", # No - abu netral lebih lembut
|
70 |
+
"#e6f2ff", # Tgl Beli
|
71 |
+
"#d5fbe3", # Harga Beli/g
|
72 |
+
"#ffecd9", # Berat
|
73 |
+
"#ffe0e8", # Modal
|
74 |
+
"#e0f2ff", # Tgl Jual
|
75 |
+
"#dcfce7", # Harga Jual/g
|
76 |
+
"#fff9db", # Nilai Jual
|
77 |
+
"#ffe6ef", # Profit/Loss
|
78 |
+
]
|
79 |
+
|
80 |
+
data = None
|
81 |
+
data_dir = "data"
|
82 |
+
data_path = os.path.join(data_dir, "data.json")
|
83 |
+
os.makedirs(data_dir, exist_ok=True)
|
84 |
+
|
85 |
+
makeslcy = lambda x: -0.575 - (7 - x) * (0.575 / 7) * 5
|
86 |
+
|
87 |
+
data = None
|
88 |
+
|
89 |
+
def ambil_data_emas():
|
90 |
+
global data
|
91 |
+
|
92 |
+
later_day = False
|
93 |
+
jam_sudah_cukup = False
|
94 |
+
|
95 |
+
data = data or rf()
|
96 |
+
data_is_ready = ir(data) # os.path.exists(data_path)
|
97 |
+
|
98 |
+
if data_is_ready:
|
99 |
+
# with open(data_path, "r") as f: data = json.load(f)
|
100 |
+
|
101 |
+
# Ambil tanggal terakhir dari lastUpdate
|
102 |
+
last_updates = [pd.to_datetime(d["lastUpdate"]) for d in data["data"]["priceList"]]
|
103 |
+
last_update_date = max(last_updates)
|
104 |
+
|
105 |
+
# Waktu sekarang
|
106 |
+
now = datetime.now()
|
107 |
+
|
108 |
+
# Periksa apakah tanggal hari ini lebih baru dari tanggal terakhir
|
109 |
+
later_day = now.date() > last_update_date.date()
|
110 |
+
|
111 |
+
# Periksa apakah jam sudah lewat dari jam 11 pagi
|
112 |
+
jam_sudah_cukup = now.hour >= 11
|
113 |
+
|
114 |
+
data_is_change = (later_day and jam_sudah_cukup) or not data_is_ready
|
115 |
+
print("data_is_change", data_is_change)
|
116 |
+
|
117 |
+
# Jika belum ada data, atau sudah lewat tanggal dan cukup jam
|
118 |
+
if data_is_change:
|
119 |
+
url = f"https://sahabat.pegadaian.co.id/gold/prices/chart?interval={max(lhs)}&isRequest=true"
|
120 |
+
response = requests.get(url)
|
121 |
+
if response.status_code != 200:
|
122 |
+
raise Exception("Gagal mengambil data harga dari Pegadaian.")
|
123 |
+
|
124 |
+
data = response.json()
|
125 |
+
|
126 |
+
uf(FILEPATH, json.dumps(data, indent=4))
|
127 |
+
with open(data_path, "w") as f:
|
128 |
+
json.dump(data, f, indent=4)
|
129 |
+
|
130 |
+
return data
|
131 |
+
|
132 |
+
fred = {
|
133 |
+
60: "D",
|
134 |
+
90: "2D",
|
135 |
+
180: "3D",
|
136 |
+
360: "4D",
|
137 |
+
480: "5D",
|
138 |
+
1000: "3W",
|
139 |
+
2500: "6W",
|
140 |
+
"Default": "9W"
|
141 |
+
}
|
142 |
+
|
143 |
+
frek = list(fred.keys())
|
144 |
+
frev = list(fred.values())
|
145 |
+
|
146 |
+
default_hari = 90
|
147 |
+
|
148 |
+
def get_freq(lama_hari):
|
149 |
+
if len(frek) !=len(frev):
|
150 |
+
raise Exception("Len Frek !=Len Frev")
|
151 |
+
|
152 |
+
freq = frev[-1]
|
153 |
+
for i in range(len(frek)):
|
154 |
+
if frek[i] !=frek[-1] and lama_hari <=int(frek[i]) and lama_hari >=int(frek[i-1] if frek[i-1] !=frek[-1] else 0):
|
155 |
+
freq = frev[i]
|
156 |
+
break
|
157 |
+
|
158 |
+
return freq
|
159 |
+
|
160 |
+
# Data pembelian
|
161 |
+
tanggal_beli = [
|
162 |
+
pd.Timestamp(d) for d in [
|
163 |
+
# "2025-04-10",
|
164 |
+
"2025-04-14",
|
165 |
+
"2025-06-04",
|
166 |
+
"2025-06-08",
|
167 |
+
"2025-06-10"
|
168 |
+
]
|
169 |
+
]
|
170 |
+
berat_gram = [
|
171 |
+
# 1,
|
172 |
+
0.0101,
|
173 |
+
1.0817,
|
174 |
+
0.2182,
|
175 |
+
0.0816,
|
176 |
+
]
|
177 |
+
uang_awal = [
|
178 |
+
# 1_671_000,
|
179 |
+
18_648,
|
180 |
+
2_000_000,
|
181 |
+
400_000,
|
182 |
+
150_000,
|
183 |
+
]
|
184 |
+
harga_beli_dan_jual_pada_saat_membeli = [
|
185 |
+
[1_863_000, 1_797_000], [1_834_000, 1_769_000], [1_840_000, 1_775_000]
|
186 |
+
]
|
187 |
+
harga_beli_dan_jual_saat_ini = [1_840_000, 1_775_000]
|
188 |
+
|
189 |
+
tglf = lambda tgl: pd.to_datetime(tgl, format='%Y-%m-%d %H:%M:%S')
|
190 |
+
|
191 |
+
cwta = [2.5, 6.6, 11.75, 7, 10, 6.6, 12.5, 16.6, 11]
|
192 |
+
|
193 |
+
misy = "-"
|
194 |
+
|
195 |
+
data = ambil_data_emas()
|
196 |
+
|
197 |
+
# Ambil timestamp string dari data
|
198 |
+
timestamp_utc = data["timestamp"]
|
199 |
+
|
200 |
+
# Parsing ISO format ke datetime object (timezone-aware UTC)
|
201 |
+
dt_utc = datetime.fromisoformat(timestamp_utc.replace("Z", "+00:00"))
|
202 |
+
|
203 |
+
# Konversi ke zona waktu WIB (UTC+7)
|
204 |
+
wib = pytz.timezone("Asia/Jakarta")
|
205 |
+
dt_wib = dt_utc.astimezone(wib)
|
206 |
+
|
207 |
+
# Format menjadi string lokal
|
208 |
timestamp_lokal = dt_wib.strftime("%d %B %Y, %H:%M WIB")
|