stanley-king 2 tahun lalu
induk
melakukan
c36daa547b
4 mengubah file dengan 160 tambahan dan 67 penghapusan
  1. 53 27
      plot/plot_control.py
  2. 68 40
      plot/refill/ChannelPainter.py
  3. 35 0
      plot/refill/DataStream.py
  4. 4 0
      plot/testPlot.py

+ 53 - 27
plot/plot_control.py

@@ -10,52 +10,78 @@ import logging
 import time
 import signal as sig
 import sys, getopt
+import re
 
 from refill import ChannelPainter
 from refill import day_stamp,time_border
 
+
 logging.basicConfig(filename='/var/www/html/data/log/flask.log',
                     format='%(levelname)10s  %(asctime)s  %(name)10s %(thread)d %(message)s',
                     level=logging.DEBUG)
 logger = logging.getLogger('plot')
 
+def filter_chname(chnames):
+    if chnames is not None:
+        chnames = chnames.strip()
+
+    if chnames is None or len(chnames) == 0:
+        chnames = set()
+    else:
+        items = re.split(r',', chnames)
+        names = [name.strip() for name in items]
+        namelist = []
+        for name in names:
+            if len(name) > 0:
+                namelist.append(name)
+        chnames = set(namelist)
+    return chnames
+
+def filter_cardtype(card_types):
+    if card_types is not None:
+        card_types = card_types.strip()
+
+    if card_types is None or len(card_types) == 0:
+        result = {4, 5, 6} #默认话费类型
+    else:
+        items = re.split(r',', card_types)
+        stypes = [type.strip() for type in items]
+        types = []
+        for stype in stypes:
+            try:
+                type = int(stype)
+                types.append(type)
+            except Exception as ex:
+                logger.error(ex)
+
+        result = set(types)
+    return result
+
 @app.route('/plot/ch_ratio')
 def ch_ratio():
     try:
         logger.debug('start chratio')
-        # cur_time = int(time.time())
-        # interval = request.args.get('interval') or 300
-        # start_time = request.args.get('start_time') or (cur_time - 7200)
-        # end_time = request.args.get('end_time') or cur_time
-        #
-        # start_time = time_border(start_time,interval,True)
-        # end_time = time_border(cur_time,interval,False)
-        #
-        # chnames = request.args.get('chnames') or list()
-        # card_types = request.args.get('card_types') or set()
-        # spec = request.args.get('spec') or None
-        #
-        # painter = ChannelPainter(start_time=start_time, end_time=end_time, interval=interval, chnames=chnames, card_types=card_types, spec=spec)
-        # data = painter.paint()
-
-        from refill import ChannelPainter
-
-        start_time = int(time.time()) - 4 * 86400
-        end_time =   int(time.time()) - 3 * 86400
-
-        # painter = ChannelPainter(start_time=start_time, end_time=end_time, interval=300, chnames={'chizeng', 'ainika'}, card_types={4, 5, 6})
-        painter = ChannelPainter(start_time=start_time, end_time=end_time, interval=7200, chnames=set(), card_types={4},spec=100)
+        cur_time = int(time.time())
+        start_time = int(request.args.get('start_time') or (cur_time - 7200))
+        end_time = int(request.args.get('end_time') or cur_time)
+
+        chnames = request.args.get('chnames') or None
+        chnames = filter_chname(chnames)
+
+        card_types = request.args.get('card_types') or None
+        card_types = filter_cardtype(card_types)
+
+        spec = request.args.get('spec') or None
+        if spec is not None:
+            spec = int(spec.strip())
+        painter = ChannelPainter(start_time=start_time, end_time=end_time, chnames=chnames, card_types=card_types, spec=spec)
         buf = painter.paint()
 
         data = base64.b64encode(buf.getbuffer()).decode("ascii")
         return f"<img src='data:image/png;base64,{data}'/>"
-
-        # logger.debug('start_time=%s end_time=%s interval= %s chnames=%s quality=%s card_type=%s amount=%s',
-        #              start_time, interval, chnames, card_types,spec)
     except Exception as ex:
         logger.error(ex)
-        print(ex)
-    return None
+        return f"<img src='data:image/png;base64,{[]}'/>"
 
 
 if __name__ == "__main__":

+ 68 - 40
plot/refill/ChannelPainter.py

@@ -1,4 +1,4 @@
-from .DataStream import EChPosmap as pos_map,day_stamp,span_days,time_border
+from .DataStream import EChPosmap as pos_map, day_stamp, span_days, time_border, calc_interval
 from .ChannelReader import ChannelReader
 from collections import defaultdict
 from matplotlib.figure import Figure
@@ -8,23 +8,71 @@ import numpy as np
 from .algorithm import calc_chratios
 import time as time
 
+
+def allpathes(reader: ChannelReader, tuple_pathes: dict, days: list, spec=None):
+    count = len(days)
+    show_detail = True if len(list(tuple_pathes.keys())) == 1 else False
+    if show_detail == False:
+        all_datas = reader.init_data(count)
+    else:
+        all_datas = None
+
+    for name, tup in tuple_pathes.items():
+        ch_datas = reader.init_data(count)
+        for _card_type, _spec in tup:
+            if spec is not None and _spec != spec:
+                continue
+
+            if show_detail:
+                detail_datas = reader.init_data(count)
+            else:
+                detail_datas = None
+
+            for i, day in enumerate(days):
+                data = reader.read(day, name, _card_type, _spec)
+                if data is not None:
+                    column_pos = i * 86400
+                    view = ch_datas[:, column_pos:column_pos + 86400]
+                    view += data
+
+                    if show_detail:
+                        view = detail_datas[:, column_pos:column_pos + 86400]
+                        view += data
+            if show_detail:
+                yield name, _card_type, _spec, detail_datas
+        if all_datas is not None:
+            all_datas += ch_datas
+        yield name, None, None, ch_datas
+
+    if show_detail == False:
+        yield 'all', None, None, all_datas
+
+
 class ChannelPainter(object):
-    def __init__(self, start_time: int, end_time: int, interval: int, chnames: set = None, card_types: set = None, spec: int = None):
-        start_time = time_border(interval,start_time,True)
-        end_time = time_border(interval,end_time,False)
-        self._start_time, self._end_time, self._interval, self._chnames, self._card_types, self._spec = start_time, end_time, interval, chnames, card_types, spec
-        self._days = span_days(start_time,end_time)
+    def __init__(self, start_time: int, end_time: int, chnames: set = None, card_types: set = None, spec: int = None):
         self._reader = ChannelReader()
+        _start_time, _end_time, self._chnames, self._card_types, self._spec = start_time, end_time, chnames, card_types, spec
+
+        start_time = self._reader.near_stamp(_start_time,True)
+        end_time = self._reader.near_stamp(_end_time,False)
+
+        interval = calc_interval(start_time, end_time)
+        start_time = time_border(interval, start_time, True)
+        end_time = time_border(interval, end_time, False)
+        self._days = span_days(start_time, end_time)
+        self._start_time = start_time
+        self._end_time = end_time
+        self._interval = interval
 
         pass
 
     def _fig_funs(self):
         def create():
-            fig = Figure(figsize=(20, 10))
+            fig = Figure(figsize=(19, 8))
             ax = fig.subplots()
             ax.set_title('success ratio')
             ax.set(xlabel='time', ylabel='ratio')
-            return ax,fig
+            return ax, fig
 
         def flush(ax, fig, ticks, lables):
             ax.yaxis.set_major_formatter(ticker.PercentFormatter(xmax=1, decimals=4))
@@ -41,45 +89,29 @@ class ChannelPainter(object):
 
         return create, flush
 
-
     def paint(self):
-        def allpathes(reader: ChannelReader, tuple_pathes: dict, days: list):
-            count = len(days)
-            all_datas = reader.init_data(count)
-            for name,tup in tuple_pathes.items():
-                ch_datas = reader.init_data(count)
-                for i, day in enumerate(days):
-                    for _card_type,_spec in tup:
-                        data = reader.read(day, name, _card_type, _spec)
-                        if data is not None:
-                            column_pos = i * 86400
-                            view = ch_datas[:, column_pos:column_pos + 86400]
-                            view += data
-                all_datas += ch_datas
-                yield name, ch_datas
-            yield 'all',all_datas
-
         reader = ChannelReader()
-        tuple_pathes = reader.many_tuple_path(self._days,self._chnames,self._card_types,self._spec)
-        gen = allpathes(self._reader,tuple_pathes,self._days)
+        tuple_pathes = reader.many_tuple_path(self._days, self._chnames, self._card_types, self._spec)
+        gen = allpathes(self._reader, tuple_pathes, self._days, self._spec)
 
         day_stamp = self._days[0]
-        fig_create,fig_flush = self._fig_funs()
-        ax,fig = fig_create()
-        x = np.array([d - self._start_time for d in range(self._start_time,self._end_time)])
+        fig_create, fig_flush = self._fig_funs()
+        ax, fig = fig_create()
+        x = np.array([d - self._start_time for d in range(self._start_time, self._end_time)])
 
-        window = np.ones(300) / 300
-        for _chname,_data in gen:
+        window = np.ones(10) / 10
+        for _chname, _card_type, _spec, _data in gen:
             succ, count, y = calc_chratios(_data, pos_map, self._start_time - day_stamp, self._end_time - day_stamp)
-            # y = np.convolve(y, window, 'same')
-            ax.plot(x, y, ls='-', label=self._label(chname=_chname,succ=succ,count=count))
+            print(_chname)
+            y = np.convolve(y, window, 'same')
+            ax.plot(x, y, ls='-', label=self._label(chname=_chname, succ=succ, count=count, card_type=_card_type, spec=_spec))
 
         ticks = [d - self._start_time for d in range(self._start_time, self._end_time + 1, self._interval)]
-        xlables = [time.strftime('%d-%H:%M', time.localtime(d + self._start_time)) for d in ticks]
+        xlables = [time.strftime('%d-%H:%M:%S', time.localtime(d + self._start_time)) for d in ticks]
 
         return fig_flush(ax, fig, ticks, xlables)
 
-    def _label(self, chname, succ, count, card_type=None,spec=None):
+    def _label(self, chname, succ, count, card_type=None, spec=None):
         _card_type = None
         if card_type == 1:
             _card_type = 'SY'
@@ -108,7 +140,3 @@ class ChannelPainter(object):
         lable += f":{ratio}%={succ}/{count}"
 
         return lable
-
-
-
-

+ 35 - 0
plot/refill/DataStream.py

@@ -40,6 +40,19 @@ def time_border(interval, time_stamp, lt):
 
     return pos + day
 
+def calc_interval(start,end):
+    period = end - start
+    segment = int(period / 24)
+    if segment == 0:
+        return 1
+    else:
+        intervals = [30, 60, 300, 600, 900, 1800, 3600, 7200, 14400, 21600, 28800, 36000, 43200, 86400, 172800]
+        for i in intervals:
+            if segment < i:
+                return i
+    pass
+
+
 def span_days(start_time,end_time):
     start_day = day_stamp(start_time)
     end_day = day_stamp(end_time)
@@ -159,6 +172,28 @@ class DataReadStream(metaclass=ABCMeta):
             logger.error(ex)
             return []
 
+    def near_stamp(self,time_stamp,left = True):
+        if len(self._days) == 0:
+            return None
+
+        day = day_stamp(time_stamp)
+        pos = time_stamp - day
+        if left:
+            while True:
+                if day >= self._days[0]:
+                    break
+                else:
+                    day += 86400
+        else:
+            while True:
+                if day <= self._days[-1]:
+                    break
+                else:
+                    day -= 86400
+
+        return pos + day
+
+
 
 class EMchPosmap(IntEnum):
     submit_count = 0

+ 4 - 0
plot/testPlot.py

@@ -107,6 +107,10 @@ class MyTestCase(unittest.TestCase):
         x = matplotlib.__version__
         print(x)
 
+    def test_time(self):
+        x = int(time.time())
+        print(x)
+
 
 
 if __name__ == '__main__':