| 211 | self.ph = None |
| 212 | |
| 213 | def event(self, event_name, main_model=None, **kwargs): |
| 214 | if not self.mp and not self.ph and not self.logfile: |
| 215 | return |
| 216 | |
| 217 | properties = {} |
| 218 | |
| 219 | if main_model: |
| 220 | properties["main_model"] = self._redact_model_name(main_model) |
| 221 | properties["weak_model"] = self._redact_model_name(main_model.weak_model) |
| 222 | properties["editor_model"] = self._redact_model_name(main_model.editor_model) |
| 223 | |
| 224 | properties.update(kwargs) |
| 225 | |
| 226 | # Handle numeric values |
| 227 | for key, value in properties.items(): |
| 228 | if isinstance(value, (int, float)): |
| 229 | properties[key] = value |
| 230 | else: |
| 231 | properties[key] = str(value) |
| 232 | |
| 233 | if self.mp: |
| 234 | try: |
| 235 | self.mp.track(self.user_id, event_name, dict(properties)) |
| 236 | except MixpanelException: |
| 237 | self.mp = None # Disable mixpanel on connection errors |
| 238 | |
| 239 | if self.ph: |
| 240 | self.ph.capture(event_name, distinct_id=self.user_id, properties=dict(properties)) |
| 241 | |
| 242 | if self.logfile: |
| 243 | log_entry = { |
| 244 | "event": event_name, |
| 245 | "properties": properties, |
| 246 | "user_id": self.user_id, |
| 247 | "time": int(time.time()), |
| 248 | } |
| 249 | try: |
| 250 | with open(self.logfile, "a") as f: |
| 251 | json.dump(log_entry, f) |
| 252 | f.write("\n") |
| 253 | except OSError: |
| 254 | pass # Ignore OS errors when writing to logfile |
| 255 | |
| 256 | |
| 257 | if __name__ == "__main__": |