HEX
Server: Apache
System: Linux pdx1-shared-a1-38 6.6.104-grsec-jammy+ #3 SMP Tue Sep 16 00:28:11 UTC 2025 x86_64
User: mmickelson (3396398)
PHP: 8.1.31
Disabled: NONE
Upload Files
File: //usr/local/bin/dhwp/dhwp/controllers/metrics.py
import json
from cement import App, Controller, ex
from cement import shell
from dhwp.core.wordpress import Wordpress
from yaml import safe_load
from multiprocessing import Pipe


class Metrics(Controller):

    class Meta:
        label = 'metrics'

    @ex(
        help='Gather metrics',

        arguments=[
            (['-o', '--output'],
             {'help': 'where to put metric output',
                'action': 'store',
                'dest': 'output', }),
            (['-b', '--batch'],
             {'help': 'config file for handling metrics from multiple sites',
                'action': 'store',
                'dest': 'batch_file', }),
        ]
    )
    def metrics(self):
        if self.app.pargs.batch_file:
            with open(self.app.pargs.batch_file) as f:
                cnf = safe_load(f)
                print(cnf)
            i = 0
            processes = []
            pipe_list = []
            while i < len(cnf['Installs']):
                if len(processes) < 2:
                    print(cnf['Installs'][i])
                    install = cnf['Installs'][i]
                    recv_end, send_end = Pipe(False)
                    new_process = shell.spawn(self.generate_metrics, args=(install['Path'], install['User'], install['Install Id'], send_end))
                    processes.append(new_process)
                    pipe_list.append(recv_end)
                    i += 1
                for num, process in enumerate(processes):
                    if process.is_alive() is False:
                        print(processes[num])
                        del processes[num]

            data = []
            for x in pipe_list:
                try:
                    data.append(x.recv())
                except EOFError as e:
                    pass

            json_out = json.dumps(data, ensure_ascii=False)
            self.app.log.debug("metric output : %s" % json_out)
            if (cnf['Output']):
                print(cnf['Output'])
                self.app.log.debug("writing output to : %s" % cnf['Output'])
                f = open(cnf['Output'], "w")
                f.write(json_out)
                f.close()
        else:
            data = self.generate_metrics(self.app.pargs.path)
            json_out = json.dumps(data, ensure_ascii=False)
            self.app.log.debug("metric output : %s" % json_out)
            if (self.app.pargs.output):
                self.app.log.debug("writing output to : %s" % self.app.pargs.output)
                f = open(self.app.pargs.output, "w")
                f.write(json_out)
                f.close()

    def generate_metrics(self, path, user=None, install_id=None, send_end=None):
        try:
            data = {
                'counts': {
                },
                'raw': {
                }
            }
            wp = Wordpress(path, user)
            metric_raw = {
                    'plugins': 'plugin list',
                    'themes': 'theme list',
            }
            metric_counts = {
                    'users': 'user list',
                    'posts_published': 'post list --post_type=post,page --post_status=publish',
                    'media_uploaded': 'post list --post_type=attachment',
            }

            for key in metric_raw:
                out = wp.cli(metric_raw[key] + ' --skip-plugins --skip-themes --skip-packages --format=json')
                json_dict = json.loads(out)
                if json_dict:
                    data['raw'][key] = json_dict

            for key in metric_counts:
                out = wp.cli(metric_counts[key] + ' --skip-plugins --skip-themes --skip-packages --format=count')
                data['counts'][key] = out
        except Exception:
            data['error'] = True
            pass
        finally:
            if send_end:
                send_end.send({install_id: data})
                send_end.close()

        return data