import csv
import hashlib
import logging
import shutil
from datetime import datetime, timedelta
from ntpath import basename
from typing import Dict

from colorama import Fore
from dateutil import parser

from sauronx import append_log_to_submission_log, stamp

from .alive import SauronxAlive, StatusValue
from .configuration import config
from .submission import CompletedRunInfo

def make_dirs_perm(pathname):
    make_dirs(pathname)
    os.chmod(pathname, 0o777)

class Results:
    """
    Keeps track of frames and metadata in a SauronX submission.
    Also uploads the data and notifies if requested.
    The recommended usage is:
            with Results() as results:
                    # let the camera write
                    results.upload()
    """

    def __init__(
        self, sx_alive: SauronxAlive, keep_raw_frames: bool = False, assume_clean: bool = False
    ) -> None:
        self.coll = config.get_coll(sx_alive.submission_hash)
        self.sx_alive = sx_alive
        self.submission_hash = self.sx_alive.submission_hash
        self.upload_params = config["connection.upload"]
        self.notify_params = config["connection.notification"]
        self.output_dir = self.coll.output_dir()
        self.raw_frames_output_dir = self.coll.outer_frames_dir()
        self.fps = config["sauron.hardware.camera.frames_per_second"]
        plate_type_id = sx_alive.submission_obj.experiment.template_plate.plate_type.id
        roi = config.camera_roi(plate_type_id)
        self.frame_width = roi.x1 - roi.x0
        self.frame_height = roi.y1 - roi.y0
        # this gets uploaded to a 'pending' dir on valinor for notification
        self.video_file = self.coll.avi_file()
        self.qp = config["sauron.data.video.qp"]
        self.x265_params = None
        self.keyframe_interval = config["sauron.data.video.keyframe_interval"]
        self.extra_x265_options = config["sauron.data.video.extra_x265_params"]
        self.submission_log_file = append_log_to_submission_log(self.submission_hash)
        self.file_hasher = FileHasher(algorithm=hashlib.sha256, extension=".sha256")
        self.keep_raw_frames = keep_raw_frames
        self.assume_clean = assume_clean

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb) -> None:
        pass

    def initialize_dir(self) -> None:
        def change_perm(action, name, exc):
            os.chmod(name, 0o777)

        tmp_webcam_snap = ".{}.snap.tmp.jpg".format(self.submission_hash)
        if os.path.exists(self.output_dir):
            warn_user(
                "Refusing to initialize output directory:",
                self.output_dir,
                "The path already exists.",
            )
            print(Fore.RED + "Overwrite? [yes/no]", end="")
            if prompt_yes_no(""):
                # a little weird, but copy webcam file first
                # this is useful if --dark and --override are both set
                if pexists(self.coll.webcam_snapshot()):
                    shutil.copy(self.coll.webcam_snapshot(), tmp_webcam_snap)
                print("")
                shutil.rmtree(self.output_dir, onerror=change_perm)
                if os.path.exists(self.raw_frames_output_dir):
                    logging.info("Deleting raw frames at {}".format(self.raw_frames_output_dir))
                    if self.assume_clean:
                        logging.warning(
                            "Since --assume-clean is set, will not delete previous frames."
                        )
                    else:
                        shutil.rmtree(self.raw_frames_output_dir, onerror=change_perm)
            else:
                raise RefusingRequestException(
                    "The path {} already exists; refusing to proceed.".format(self.output_dir)
                )
            logging.info("Finished deleting")

        make_dirs_perm(self.output_dir)
        make_dirs_perm(self.raw_frames_output_dir)
        make_dirs_perm(pjoin(self.output_dir, "timing"))
        make_dirs_perm(pjoin(self.output_dir, "sensors"))
        if pexists(tmp_webcam_snap) and os.path.getsize(tmp_webcam_snap) > 0:
            logging.warning(
                "Keeping webcam snapshot from previous run. It will be overwritten if a new capture is taken."
            )
            shutil.move(tmp_webcam_snap, self.coll.webcam_snapshot())

        with open(pjoin(self.output_dir, "submission_hash.txt"), "w", encoding="utf8") as f:
            f.write(self.sx_alive.submission_hash)
        shutil.copyfile(os.environ["SAURONX_CONFIG_PATH"], self.coll.toml_file())

        # copy os info, git hash, etc.
        with open(self.coll.env_file(), "w", encoding="utf8") as f:
            for key, value in config.environment_info.items():
                f.write(key + "=" + value + "\n")

        logging.info("Prepared output directory {}".format(self.output_dir))

        if pexists(self.coll.log_file()):
            logging.warning("The log file at {} already exists".format(self.coll.log_file()))
        else:
            os.symlink(self.submission_log_file, self.coll.log_file())

    def finalize(self, run_info: CompletedRunInfo) -> None:
        import valarpy.model as model

        with open(self.coll.env_file(), "a", encoding="utf8") as f:

            def write(key: str, value: str) -> None:  # TODO strip control chars, etc, too
                f.write(key + "=" + escape_for_properties(value) + "\n")

            sub_obj = self.sx_alive.submission_obj
            exp = sub_obj.experiment
            # this is the critical start time, which is used to fill in runs.datetime_run
            write("datetime_started", stamp(run_info.datetime_acclimation_started))
            # and this end time is critical too
            write("datetime_capture_finished", stamp(run_info.datetime_capture_finished))
            write("original:experiment_id", exp.id)
            write("original:experiment_name", exp.name)
            write("original:description", sub_obj.description)
            write("original:continuing_id", sub_obj.continuing_id)
            write("original:datetime_plated", sub_obj.datetime_plated)
            write("original:datetime_dosed", sub_obj.datetime_dosed)
            write("original:notes", sub_obj.notes)
            write("original:person_submitted", sub_obj.user_id)
            write("original:battery", exp.battery_id)
            write("original:template_plate", exp.template_plate_id)
            for param in model.SubmissionParams.select(model.SubmissionParams).where(
                model.SubmissionParams.submission == sub_obj.id
            ):
                write("param:" + param.param_type + ":" + param.name, param.value)
            write("datetime_environment_written", stamp(datetime.now()))
            write("ffmpeg_version", self.find_ffmpeg_version())
        try:
            if os.path.exists(run_info.preview_path):
                shutil.copyfile(run_info.preview_path, self.coll.preview_snapshot())
            else:
                logging.error("Missing preview snapshot {}".format(run_info.preview_path))
        except:
            logging.exception("Failed to copy preview frame at {}".format(run_info.preview_path))
        success_to_user("Finalized run. All of the necessary data is now present.")

    def find_ffmpeg_version(self):
        out, err = wrap_cmd_call(["ffmpeg", "-version"])
        return out

    def upload(self) -> None:
        try:
            self.sx_alive.update_status(StatusValue.UPLOADING)
            # noinspection PyTypeChecker
            for i in range(0, int(self.upload_params["max_attempts"])):
                try:
                    self._attempt_upload()
                    break
                except (SCPException, ExternalCommandFailed) as e:
                    # noinspection PyTypeChecker
                    if i < int(self.upload_params["max_attempts"]) - 1:
                        logging.error("Upload failed (attempt {})".format(i), e)
                        warn_user("Upload failed (attempt {})".format(i))
                    else:
                        raise e
            self.sx_alive.update_status(StatusValue.UPLOADED)
        except Exception:
            self.sx_alive.update_status(StatusValue.FAILED_DURING_UPLOAD)
            raise

    def copy_raw_to(self, path: str) -> None:
        msg = "Moving raw frames to {}".format(path)
        logging.warning(msg)
        warn_user(msg, "==DO NOT INTERRUPT OR CANCEL==")
        try:
            shutil.move(self.raw_frames_output_dir, path)
        except:
            logging.fatal(
                "Moving raw frames stopped partway. They are split between {} and {}".format(
                    self.raw_frames_output_dir, path
                )
            )
            raise
        warn_user(
            "Moved raw frames to {}.".format(path, self.submission_hash),
            "You will need to copy them back and",
            "finish the submission with `sauronx continue {}`.",
        )

    def make_video(self) -> None:
        try:
            self._parse_frame_timing_file()
            self._trim_frames()
            logging.info(
                "Making primary video with ffmpeg. At high framerates, this should take about as long as the duration of the run"
            )
            self._run_ffmpeg(self.raw_frames_output_dir, self.video_file)
            logging.info("Compressing microphone recording.")
            self._convert_microphone()
        except Exception:
            self.sx_alive.update_status(StatusValue.FAILED_DURING_POSTPROCESSING)
            raise

    def _run_ffmpeg(self, path, output_video):
        make_dirs_perm(os.path.dirname(output_video))
        if not pdir(path):
            raise ValueError("Directory {} does not exist".format(path))
        first_real_frame = self._first_frame(path)
        # TODO change log level back to info
        stream_cmd_call(
            [
                "ffmpeg",
                "-loglevel",
                "warning",
                "-hwaccel",
                "qsv",
                "-f",
                "image2",
                "-nostdin",
                "-c:v",
                "rawvideo",
                "-framerate",
                str(self.fps),
                "-video_size",
                "{}x{}".format(self.frame_width, self.frame_height),
                "-pixel_format",
                "gray",
                "-start_number",
                str(first_real_frame),
                "-i",
                pjoin(path, "%08d.raw"),
                "-y",
                "-c:v",
                "hevc_qsv",
                "-g",
                str(self.keyframe_interval),
                "-q:v",
                str(self.qp),
                "-preset",
                config["sauron.data.video.preset"],
                "-load_plugin",
                "2",
                "-r",
                str(self.fps),
                output_video,
            ]
        )

        self.file_hasher.add_hash(output_video)
        if not self.keep_raw_frames:
            slow_delete(path, 3)

    def _first_frame(self, path: str):
        assert pexists(path), "The frame directory does not exist"
        prop_files = list(sorted(scan_for_proper_files(path)))
        if len(prop_files) == 0:
            warn_user("No frames were found in {}".format(path))
            raise ValueError("No frames were found in {}".format(path))
        return basename(prop_files[0].rstrip(".raw"))

    def _x265_params(self):
        if self.x265_params is not None:
            return self.x265_params
        self.x265_params = "qp={}:keyint={}:min-keyint={}".format(
            str(self.qp), self.keyframe_interval, self.keyframe_interval
        )
        if self.extra_x265_options is not None and len(self.extra_x265_options) > 0:
            self.x265_params += ":" + ":".join(
                [
                    str(k) + "=" + config.parse_path_format(v, self.output_dir)
                    for k, v in self.extra_x265_options.items()
                ]
            )
        logging.info(
            "Encoding with framerate {} and x265 params '{}'".format(self.fps, self.x265_params)
        )
        return self.x265_params

    def _convert_microphone(self) -> None:
        microphone_input = self.coll.microphone_wav_path()
        microphone_output = self.coll.microphone_flac_path()
        if pexists(microphone_input):
            logging.info("Compressing microphone data.")
            stream_cmd_call(
                [
                    "ffmpeg",
                    "-i",
                    microphone_input,
                    "-compression_level",
                    config["sauron.data.audio.flac_compression_level"],
                    "-c:a",
                    "flac",
                    microphone_output,
                ]
            )
            self.file_hasher.add_hash(microphone_output)
            os.remove(microphone_input)

    def _trim_frames(self) -> None:
        """Trims the frames that were captured before the first stimulus or after the last.
        This works because StimulusTimeLog is defined to have its head be the start of the run and its tail be the end of the run, regardless of the stimuli.
        To fulfill this definition, Board.run_scheduled_and_wait appends a stimulus for ID 0 at the beginning, and another at the end.
        """
        if not self.coll.stimulus_timing_exists():
            raise MissingResourceException(
                "Cannot proceed: the stimulus timing log at {} is missing".format(
                    self.coll.stimulus_timing_log_file()
                )
            )

        # first, check that we didn't fail partway through trimming
        # this could be bad; let's fix that before making the trimming videos or the main video
        def fixit(name: str):
            output_video = pjoin(self.coll.trimmed_dir(), name + ".mkv")
            hash_file = output_video + ".sha256"
            tmpdir = pjoin(self.output_dir, name + "-trimmings")
            if pexists(tmpdir) and not pexists(hash_file):
                warn_user("Moving {} trimmed frames back".format(name))
                logging.warning("Moving {} trimmed frames back".format(name))
                for f in os.listdir(tmpdir):
                    if os.path.isdir(
                        self.coll.outer_frames_dir()
                    ):  # If directory exists, copy overwrites existing files in directory, move does not.
                        shutil.copy(pjoin(tmpdir, f), self.coll.outer_frames_dir())
                        os.remove(pjoin(tmpdir, f))
                    else:
                        shutil.move(pjoin(tmpdir, f), self.coll.outer_frames_dir())
            elif pexists(tmpdir):
                pass

        fixit("start")
        fixit("end")

        stimulus_time_log = self._parse_stimulus_timing_file(self.coll.stimulus_timing_log_file())
        if len(stimulus_time_log) == 0:
            return  # ok; nothing to remove
        snapshots = [
            parse_local_iso_datetime(snap) for snap in lines(self.coll.snapshot_timing_log_file())
        ]
        first_stimulus = stimulus_time_log[0]  # type: datetime
        last_stimulus = stimulus_time_log[-1]  # type: datetime
        trimmings_start = []
        trimmings_end = []
        ran_off_end = 0
        my_files = enumerate(sorted(scan_for_proper_files(self.coll.outer_frames_dir())))
        for i, frame in my_files:
            if i >= len(snapshots):
                ran_off_end += 1
            elif snapshots[i] < first_stimulus:
                trimmings_start.append(frame)
            elif snapshots[i] > last_stimulus:
                trimmings_end.append(frame)
        if ran_off_end > 0:
            logging.error("{} stimuli occurred after the last snapshot!")
            warn_user("{} stimuli occurred after the last snapshot!")

        make_dirs_perm(self.coll.trimmed_dir())
        self._make_trimmings_video(trimmings_start, "start")
        self._make_trimmings_video(trimmings_end, "end")

    def _make_trimmings_video(self, trimmings, name):
        output_video = (
            self.coll.trimmed_start_video() if name == "start" else self.coll.trimmed_end_video()
        )
        hash_file = output_video + ".sha256"
        tmpdir = pjoin(self.output_dir, name + "-trimmings")
        if os.path.exists(hash_file):
            # TODO will fail if interrupted WHILE moving frames
            logging.warning(
                "{} trimmed frames video already exists at {}".format(name, output_video)
            )
            return
        if os.path.exists(output_video) or os.path.exists(tmpdir):
            warn_user(
                "Making {} trimmed frames video failed partway through.".format(name),
                "Deleting and remaking.",
            )
            logging.error(
                "Making {} trimmed frames video failed partway through. Deleting and remaking.".format(
                    name
                )
            )
        if len(trimmings) == 0:
            logging.error("No {} trimmed frames".format(name))
            warn_user(
                "No {} trimmed frames.".format(name),
                "Increase {} in {} to ensure that frames aren't lost.".format(
                    "padding_before_milliseconds"
                    if name == "start"
                    else "padding_after_milliseconds",
                    config.path,
                ),
            )
            return
        # moving to another disk is a little slower
        # but we don't want these deleted if sauronx fails
        # tmpdir = pjoin(config.temp_dir(), name + '-trimmings')
        logging.info("Trimmed {} {} frames. Compressing.".format(len(trimmings), name))
        make_dirs_perm(tmpdir)
        logging.debug("Created temp dir at {}".format(tmpdir))
        for frame in trimmings:
            if not pexists(pjoin(tmpdir, os.path.basename(frame))):
                shutil.move(
                    frame, tmpdir
                )  # we HAVE to move here so they're not seen when making the primary video
        self._run_ffmpeg(tmpdir, output_video)

    def _parse_stimulus_timing_file(self, path: str) -> List[datetime]:
        # datetime,id,intensity
        return [parse_local_iso_datetime(line.split(",")[0]) for line in list(lines(path))[1:]]

    def _parse_frame_timing_file(self):
        strftime_fmt = "%Y-%m-%dT%H:%M:%S.%f"
        raw_timing_file_path = self.coll.raw_snapshot_timing_log_file()
        proc_timing_file_path = self.coll.snapshot_timing_log_file()
        stream_cmd_call(["sudo", "chmod", "777", raw_timing_file_path])
        with open(raw_timing_file_path, "r+", encoding="utf8") as f:
            with open(proc_timing_file_path, "w", encoding="utf8") as o:
                reader = csv.reader(f)
                # get the two header lines?
                prev_datetime = parser.parse(next(reader)[0])
                # o.write("{}\n".format(prev_datetime.strftime(strftime_fmt))) # 20180920 added acquisition of an extra, unsaved frame before main acquisition loop
                prev_us = int(next(reader)[0]) / 1000
                for row in reader:
                    curr_us = int(row[0]) / 1000
                    diff_us = curr_us - prev_us
                    new_datetime = prev_datetime + timedelta(microseconds=diff_us)
                    o.write("{}\n".format(new_datetime.strftime(strftime_fmt)))
                    prev_datetime = new_datetime
                    prev_us = curr_us

    def _attempt_upload(self) -> None:
        logging.info("Uploading data via SSH...")
        self._scp_files()
        logging.info("Finished uploading data via SSH")

    def _scp_files(self) -> None:
        stream_cmd_call(
            [
                "scp",
                "-r",
                "-C",
                os.path.normpath(self.output_dir),
                str(self.upload_params["ssh_username"])
                + "@"
                + str(self.upload_params["hostname"])
                + ":"
                + self._remote_upload_dir(),
            ]
        )
        # noinspection PyBroadException
        try:
            self.sx_alive.notify_finished()
        except:
            warn_user("Failed to notify")
            logging.error("Failed to notify")

    def _remote_upload_dir(self) -> str:
        remote_dir = self.upload_params["remote_upload_path"]  # type: str
        return (
            str(self.upload_params["ssh_username"])
            + "@"
            + str(self.upload_params["hostname"])
            + ":"
            + remote_dir
            if remote_dir.endswith(os.sep)
            else remote_dir + os.sep
        )

__all__ = ["Results"]


#-*- encoding: UTF-8 -*-
import logging as log
from OpenGL.GL import *
import cyglfw3 as glfw
import numpy as np
from Shader import Shader
from scipy.misc import imread

class ComputeShader(object):

	def __init__(self):
		Shader.shaderFolder	= 'view/opengl/computeShader'
		self.setup()

		filename = '/home/dimitri/Desktop/resize_im4.jpg'
		img = np.flipud( imread(filename) )
		img = np.dstack( (img, np.ones(img.shape[:2], dtype=np.float32)) )
		h, w = img.shape[:2]
		self.h, self.w = h,w

		self.read_tex = self.setupTexture(0, w, h, img)
		self.write_tex = self.setupTexture(1, w, h, None)

		self.computeShader = Shader('simple.cs')
		self.renderShader = Shader('quad.vs', 'quad.frag')
		self.computeShader.compile()
		self.renderShader.compile()
		self.__previous_second = glfw.GetTime()
		self.__frame_count = 0.0
		self.__window_title = 'ComputeShader'

	def setup(self):
		if not glfw.Init():
			log.critical('GLFW initialization failed!')
			exit(-1)
		self.window = glfw.CreateWindow(224, 224, '', None)
		if not self.window:
			log.critical('Could not create window!')
			glfw.Terminate()
			exit(-1)
		glfw.MakeContextCurrent(self.window)
		glewExperimental = True
		glfw.SetFramebufferSizeCallback(self.window, self.__framebuffer_size_callback__)

	def __framebuffer_size_callback__(self, window, width, height):
		glViewport(0,0,width, height)

	def __update_fps_counter__(self):
		current_second = glfw.GetTime()
		elapsed_seconds = current_second - self.__previous_second
		if elapsed_seconds > 1.0:
			self.__previous_second = current_second
			fps = float(self.__frame_count) / float(elapsed_seconds)
			glfw.SetWindowTitle(self.window, 'FPS: %.2f' % (fps))
			self.__frame_count = 0.0
		self.__frame_count += 1.0

	def setupTexture(self, bind_point, w, h, img):
		tex = glGenTextures(1)
		glBindTexture(GL_TEXTURE_2D, tex)
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, img)
		if img is None:
			glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, 140*np.ones((h,w,4), dtype=np.uint8))
		access = GL_WRITE_ONLY if img is None else GL_READ_ONLY
		glBindImageTexture(bind_point, tex, 0, GL_FALSE, 0, access, GL_RGBA32F)
		glBindTexture(GL_TEXTURE_2D, 0)
		return tex

	def logComputeCapInfo(self):
		x = glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0)[0]
		y = glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1)[0]
		z = glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2)[0]
		log.info( 'Max global work group size x: %d, y: %d, z: %d' % (x,y,z))
		x = glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0)[0]
		y = glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1)[0]
		z = glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 2)[0]
		log.info( 'Max local work group size x: %d, y: %d, z: %d' % (x,y,z) )
		max_inv = glGetIntegerv(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS)
		log.info( 'Max local work group invocations: %d' % max_inv )
		shMemSize = glGetIntegerv(GL_MAX_COMPUTE_SHARED_MEMORY_SIZE)
		log.info( 'Max shared memory size: %d' % shMemSize )

	def loop(self):
		while not glfw.WindowShouldClose(self.window):
			self.computeShader.use()
			glDispatchCompute(7, 7, 1)
			#glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT)

			glBindTexture(GL_TEXTURE_2D, self.write_tex)
			self.renderShader.use()
			glDrawArrays(GL_TRIANGLES, 0, 6)
			glBindTexture(GL_TEXTURE_2D, 0)

			glfw.SwapBuffers(self.window)
			self.__update_fps_counter__()
			glfw.PollEvents()
			if glfw.GetKey(self.window, glfw.KEY_ESCAPE) == glfw.PRESS:
				glfw.SetWindowShouldClose(self.window, 1)

	def cleanup(self):
		glfw.Terminate()


# Exercise 1

"""
Write a procedure called oddTuples, which takes a tuple as input, and returns a new tuple as output,
where every other element of the input tuple is copied, starting with the first one.
So if test is the tuple ('I', 'am', 'a', 'test', 'tuple'), then evaluating oddTuples on this input would return the tuple ('I', 'a', 'tuple').
"""
# Solution 1

def oddTuples(aTup):
    '''
    aTup: a tuple

    returns: tuple, every other element of aTup.
    '''

    t = []
    for tup in aTup:
        if len(tup) % 2 != 0:
            t.append(tup)
    return tuple(t)

aTup = ('I', 'am', 'a', 'test', 'tuple')

print(oddTuples(aTup))

# Solution 2

def oddTuples(aTup):
    return aTup[::2]

aTup = ('I', 'am', 'a', 'test', 'tuple')
print(oddTuples(aTup))

########################################################################

edX MITx_6_00_1x Introduction to Computer Science and Programming Using Python/week_3.py


# Copyright 2017 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import tensorflow as tf
from tensorflow.contrib import learn
from tensorflow.contrib import layers
from tensorflow.contrib import metrics
from tensorflow.contrib.learn.python.learn.estimators import model_fn as model_fn_lib

tf.logging.set_verbosity(tf.logging.INFO)

def read_and_decode(filename_queue):
  reader = tf.TFRecordReader()
  _, serialized_example = reader.read(filename_queue)

  features = tf.parse_single_example(
      serialized_example,
      features={
          'image_raw': tf.FixedLenFeature([], tf.string),
          'label': tf.FixedLenFeature([], tf.int64),
      })

  image = tf.decode_raw(features['image_raw'], tf.uint8)
  image.set_shape([784])
  image = tf.cast(image, tf.float32) * (1. / 255)
  label = tf.cast(features['label'], tf.int32)

  return image, label

def input_fn(filename, batch_size=100, num_epochs=None):
  filename_queue = tf.train.string_input_producer(
      [filename], num_epochs=num_epochs)

  image, label = read_and_decode(filename_queue)
  images, labels = tf.train.batch(
      [image, label], batch_size=batch_size,
      capacity=1000 + 3 * batch_size)

  return {'inputs': images}, labels

def get_input_fn(filename, num_epochs=None, batch_size=100):
  return lambda: input_fn(filename, batch_size)

def _cnn_model_fn(features, labels, mode):
  # Input Layer
  input_layer = tf.reshape(features['inputs'], [-1, 28, 28, 1])

  # Convolutional Layer #1
  conv1 = tf.layers.conv2d(
      inputs=input_layer,
      filters=32,
      kernel_size=[5, 5],
      padding="same",
      activation=tf.nn.relu)

  # Pooling Layer #1
  pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)

  # Convolutional Layer #2 and Pooling Layer #2
  conv2 = tf.layers.conv2d(
      inputs=pool1,
      filters=64,
      kernel_size=[5, 5],
      padding="same",
      activation=tf.nn.relu)
  pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)

  # Dense Layer
  pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 64])
  dense = tf.layers.dense(inputs=pool2_flat, units=1024, activation=tf.nn.relu)
  dropout = tf.layers.dropout(
      inputs=dense, rate=0.4, training=(mode == learn.ModeKeys.TRAIN))

  # Logits Layer
  logits = tf.layers.dense(inputs=dropout, units=10)

  loss = None
  train_op = None

  # Calculate Loss (for both TRAIN and EVAL modes)
  if mode != learn.ModeKeys.INFER:
    onehot_labels = tf.one_hot(indices=tf.cast(labels, tf.int32), depth=10)
    loss = tf.losses.softmax_cross_entropy(
        onehot_labels=onehot_labels, logits=logits)

  # Configure the Training Op (for TRAIN mode)
  if mode == learn.ModeKeys.TRAIN:
    train_op = tf.contrib.layers.optimize_loss(
        loss=loss,
        global_step=tf.contrib.framework.get_global_step(),
        learning_rate=0.001, optimizer="Adam")

  # Generate Predictions
  predictions = {
      "classes": tf.argmax(input=logits, axis=1),
      "probabilities": tf.nn.softmax(logits, name="softmax_tensor")
  }

  # Return a ModelFnOps object
  return model_fn_lib.ModelFnOps(mode=mode, loss=loss, train_op=train_op,
                                 predictions=predictions)

def build_estimator(model_dir):
  return learn.Estimator(
           model_fn=_cnn_model_fn,
           model_dir=model_dir,
           config=tf.contrib.learn.RunConfig(save_checkpoints_secs=180))

def get_eval_metrics():
  return {"accuracy": learn.MetricSpec(metric_fn=tf.metrics.accuracy,
                                       prediction_key="classes")
  }

def serving_input_fn():
  feature_placeholders = {'inputs': tf.placeholder(tf.float32, [None, 784])}
  features = {
    key: tensor
    for key, tensor in feature_placeholders.items()
  }
  return learn.utils.input_fn_utils.InputFnOps(
    features,
    None,
    feature_placeholders
  )


#Stripping Lines for DY->MuMu
#Electroweak Group (Convenor: Tara Shears)
#Adaptation of lines (to use line builders) originally written by James Keaveney by Will Barter

# 8 Lines - 4 standard lines cover different mass ranges. The additional 4 place HLT requirements, in an attempt to reduce the level of prescale needed at low mass.

from Gaudi.Configuration import *
from GaudiConfUtils.ConfigurableGenerators import FilterDesktop, CombineParticles
from PhysSelPython.Wrappers import Selection
from StrippingConf.StrippingLine import StrippingLine
from StrippingUtils.Utils import LineBuilder
from StandardParticles import StdLooseMuons

confdict_DY2MuMu={
    'DY2MuMu1Line_psPrescale'    : .02
    ,  'DY2MuMu1Line_HltPrescale': .2
    ,  'DY2MuMu1Line_HltaPrescale': 1.0
    ,  'DY2MuMu1LinePostscale'   : 1.0
    ,  'DY2MuMu2LinePrescale'    : .05
    ,  'DY2MuMu2Line_HltPrescale': .4
    ,  'DY2MuMu2Line_HltaPrescale': 1.0
    ,  'DY2MuMu2LinePostscale'   : 1.0
    ,  'DY2MuMu3LinePrescale'    : 1.0
    ,  'DY2MuMu3LinePostscale'   : 1.0
    ,  'DY2MuMu4LinePrescale'    : 1.0
    ,  'DY2MuMu4LinePostscale'   : 1.0
    ,  'DY1MinMass' : 2.5
    ,  'DY1jpsiexclow' : 3.0
    ,  'DY1jpsiexchigh' : 3.2
    ,  'DY1MaxMass' : 5.
    ,  'DY2MinMass' : 5.
    ,  'DY2MaxMass' : 10.
    ,  'DY3MinMass' : 10.
    ,  'DY3MaxMass' : 20.
    ,  'DY4MinMass' : 20.
    ,  'DY4MaxMass' : 40.
    ,  'mupt1' : 800.
    ,  'mupt2' : 1.
    ,  'mutrkpchi2' : 0.001
    ,  'muipdvchi2ratio' : 5.
    ,  'mupidreq' : -3.
 }

name = "DY2MuMu"

class DY2MuMuConf(LineBuilder) :

    __configuration_keys__ = ('DY1MinMass',
                              'DY1jpsiexclow',
                              'DY1jpsiexchigh',
                              'DY1MaxMass',
                              'DY2MinMass',
                              'DY2MaxMass',
                              'DY3MinMass',
                              'DY3MaxMass',
                              'DY4MinMass',
                              'DY4MaxMass',
                              'mupt1',
                              'mupt2',
                              'mutrkpchi2',
                              'muipdvchi2ratio',
                              'mupidreq',
                              'DY2MuMu1Line_psPrescale',
                              'DY2MuMu1Line_HltPrescale',
                              'DY2MuMu1Line_HltaPrescale',
                              'DY2MuMu1LinePostscale',
                              'DY2MuMu2LinePrescale',
                              'DY2MuMu2Line_HltPrescale',
                              'DY2MuMu2Line_HltaPrescale',
                              'DY2MuMu2LinePostscale',
                              'DY2MuMu3LinePrescale',
                              'DY2MuMu3LinePostscale',
                              'DY2MuMu4LinePrescale',
                              'DY2MuMu4LinePostscale',
                              )

    def __init__(self, name, config) :
        LineBuilder.__init__(self, name, config)

        self._myname = name

        #Define the cuts
        _mucut1= '(PT>%(mupt1)s*MeV)&(TRPCHI2>%(mutrkpchi2)s)&(MIPDV(PRIMARY)/MIPCHI2DV(PRIMARY)<%(muipdvchi2ratio)s)&((PIDmu-PIDpi)>%(mupidreq)s)'%config
        _mucut2= '(PT>%(mupt2)s*GeV)&(TRPCHI2>%(mutrkpchi2)s)&(MIPDV(PRIMARY)/MIPCHI2DV(PRIMARY)<%(muipdvchi2ratio)s)'%config

        _DY1MassCut = '((MM>%(DY1MinMass)s*GeV)&(MM<%(DY1jpsiexclow)s*GeV))|((MM>%(DY1jpsiexchigh)s*GeV)&(MM<%(DY1MaxMass)s*GeV))'%config
        _DY1MassCutHlt = '((MM>%(DY1MinMass)s*GeV)&(MM<%(DY1jpsiexclow)s*GeV))|((MM>%(DY1jpsiexchigh)s*GeV))'%config
        _DY2MassCut = '(MM>%(DY2MinMass)s*GeV)&(MM<%(DY2MaxMass)s*GeV)'%config
        _DY2MassCutHlt = '(MM>%(DY2MinMass)s*GeV)'%config
        _DY3MassCut = '(MM>%(DY3MinMass)s*GeV)&(MM<%(DY3MaxMass)s*GeV)'%config
        _DY4MassCut = '(MM>%(DY4MinMass)s*GeV)&(MM<%(DY4MaxMass)s*GeV)'%config

        self.selDY2MuMu1 = makeDY2MuMu1(self._myname+'DYDecay1_ps',
                                     _DY1MassCut,
                                     _mucut1)

        self.selDY2MuMu1_Hlt = makeDY2MuMu1(self._myname+'DYDecay1_Hlt',
                                     _DY1MassCutHlt,
                                     _mucut1)

        self.DY2MuMu_line1_ps = StrippingLine(self._myname+"Line1_ps",
                                            prescale = config['DY2MuMu1Line_psPrescale'],
                                            postscale = config['DY2MuMu1LinePostscale'],
                                            selection = self.selDY2MuMu1
                                            )

        self.DY2MuMu_line1_Hlt = StrippingLine(self._myname+"Line1_Hlt",
                                            prescale = config['DY2MuMu1Line_HltPrescale'],
                                            postscale = config['DY2MuMu1LinePostscale'],
                                            HLT = "HLT_PASS_RE('Hlt2DiMuonDY.*Decision')",
                                            selection = self.selDY2MuMu1_Hlt
                                            )

        self.DY2MuMu_line1_Hlta = StrippingLine(self._myname+"Line1_Hlta",
                                            prescale = config['DY2MuMu1Line_HltaPrescale'],
                                            postscale = config['DY2MuMu1LinePostscale'],
                                            HLT = "HLT_PASS_RE('Hlt2(MuonFromHLT1|PassThrough).*Decision')",
                                            selection = self.selDY2MuMu1_Hlt
                                            )

        self.registerLine(self.DY2MuMu_line1_ps)

        self.registerLine(self.DY2MuMu_line1_Hlt)

        self.registerLine(self.DY2MuMu_line1_Hlta)

        self.selDY2MuMu2 = makeDY2MuMu2(self._myname+'DYDecay2',
                                     _DY2MassCut,
                                     _mucut2)

        self.selDY2MuMu2_Hlt = makeDY2MuMu2(self._myname+'DYDecay2_Hlt',
                                     _DY2MassCutHlt,
                                     _mucut1)

        self.DY2MuMu_line2 = StrippingLine(self._myname+"Line2",
                                            prescale = config['DY2MuMu2LinePrescale'],
                                            postscale = config['DY2MuMu2LinePostscale'],
                                            selection = self.selDY2MuMu2
                                            )

        self.DY2MuMu_line2_Hlt = StrippingLine(self._myname+"Line2_Hlt",
                                            prescale = config['DY2MuMu2Line_HltPrescale'],
                                            postscale = config['DY2MuMu2LinePostscale'],
                                            HLT = "HLT_PASS_RE('Hlt2DiMuonDY.*Decision')",
                                            selection = self.selDY2MuMu2_Hlt
                                            )

        self.DY2MuMu_line2_Hlta = StrippingLine(self._myname+"Line2_Hlta",
                                            prescale = config['DY2MuMu2Line_HltaPrescale'],
                                            postscale = config['DY2MuMu2LinePostscale'],
                                            HLT = "HLT_PASS_RE('Hlt2(MuonFromHLT1|PassThrough).*Decision')",
                                            selection = self.selDY2MuMu2_Hlt
                                            )

        self.registerLine(self.DY2MuMu_line2)

        self.registerLine(self.DY2MuMu_line2_Hlt)

        self.registerLine(self.DY2MuMu_line2_Hlta)

        self.selDY2MuMu3 = makeDY2MuMu3(self._myname+'DY2MuMuDecay3',
                                     _DY3MassCut,
                                     _mucut2)

        self.DY2MuMu_line3 = StrippingLine(self._myname+"Line3",
                                            prescale = config['DY2MuMu3LinePrescale'],
                                            postscale = config['DY2MuMu3LinePostscale'],
                                            selection = self.selDY2MuMu3
                                            )

        self.registerLine(self.DY2MuMu_line3)

        self.selDY2MuMu4 = makeDY2MuMu4(self._myname+'DY2MuMuDecay4',
                                     _DY4MassCut,
                                     _mucut2)

        self.DY2MuMu_line4 = StrippingLine(self._myname+"Line4",
                                            prescale = config['DY2MuMu4LinePrescale'],
                                            postscale = config['DY2MuMu4LinePostscale'],
                                            selection = self.selDY2MuMu4
                                            )

        self.registerLine(self.DY2MuMu_line4)

def makeDY2MuMu1(name, _DY1MassCut, _mucut1) :
    _DY1= CombineParticles(DecayDescriptor = 'Z0 -> mu+ mu-',
                           DaughtersCuts = { 'mu+' : _mucut1 ,
                                             'mu-' : _mucut1 },
                           MotherCut = _DY1MassCut,
                           WriteP2PVRelations = False
                           )
    _stdloosemuons = StdLooseMuons
    return Selection ( name,
                       Algorithm = _DY1,
                       RequiredSelections = [_stdloosemuons])

def makeDY2MuMu2(name, _DY2MassCut, _mucut2) :
    _DY2 = CombineParticles(DecayDescriptor = 'Z0 -> mu+ mu-',
                           DaughtersCuts = { 'mu+' : _mucut2 ,
                                             'mu-' : _mucut2 },
                           MotherCut = _DY2MassCut,
                           WriteP2PVRelations = False
                           )
    _stdloosemuons = StdLooseMuons
    return Selection ( name,
                       Algorithm = _DY2,
                       RequiredSelections = [_stdloosemuons])

def makeDY2MuMu3(name, _DY3MassCut, _mucut2) :
    _DY3 = CombineParticles(DecayDescriptor = 'Z0 -> mu+ mu-',
                           DaughtersCuts = { 'mu+' : _mucut2 ,
                                             'mu-' : _mucut2 },
                           MotherCut = _DY3MassCut,
                           WriteP2PVRelations = False
                           )
    _stdloosemuons = StdLooseMuons
    return Selection ( name,
                       Algorithm = _DY3,
                       RequiredSelections = [_stdloosemuons])

def makeDY2MuMu4(name, _DY4MassCut, _mucut2) :
    _DY4 = CombineParticles(DecayDescriptor = 'Z0 -> mu+ mu-',
                           DaughtersCuts = { 'mu+' : _mucut2 ,
                                             'mu-' : _mucut2 },
                           MotherCut = _DY4MassCut,
                           WriteP2PVRelations = False
                           )
    _stdloosemuons = StdLooseMuons
    return Selection ( name,
                       Algorithm = _DY4,
                       RequiredSelections = [_stdloosemuons])


import struct
import time

class InvalidPacketError(Exception):
    __name__ = 'InvalidPacketError'
    pass

class BootloaderError(Exception):
    pass

class TimeoutError(BootloaderError):
    __name__ = 'TimeoutError'
    pass

class IncorrectLength(BootloaderError):
    __name__ = 'IncorrectLength'
    STATUS = 0x03

class InvalidData(BootloaderError):
    __name__ = 'InvalidData'
    STATUS = 0x04

class InvalidCommand(BootloaderError):
    __name__ = 'InvalidCommand'
    STATUS = 0x05

class InvalidChecksum(BootloaderError):
    __name__ = 'InvalidChecksum'
    STATUS = 0x08

class InvalidArray(BootloaderError):
    __name__ = 'InvalidArray'
    STATUS = 0x09

class InvalidFlashRow(BootloaderError):
    __name__ = 'InvalidFlashRow'
    STATUS = 0x0A

class InvalidApp(BootloaderError):
    __name__ = 'InvalidApp'
    STATUS = 0x0C

class UnknownError(BootloaderError):
    __name__ = 'UnknownError'
    STATUS = 0x0F

class BootloaderResponse(object):
    FORMAT = ""
    ARGS = ()

    ERRORS = {klass.STATUS: klass for klass in [
        IncorrectLength,
        InvalidData,
        InvalidCommand,
        InvalidChecksum,
        InvalidArray,
        InvalidFlashRow,
        InvalidApp,
        UnknownError
    ]}

    def __init__(self, data):
        for arg, value in zip(self.ARGS, struct.unpack(self.FORMAT, data)):
            if arg:
                setattr(self, arg, value)

    @classmethod
    def decode(cls, data, checksum_func):
        start, status, length = struct.unpack("<BBH", data[:4])
        if start != 0x01:
            raise InvalidPacketError()
        if length != len(data) - 7:
            raise InvalidPacketError()
        checksum, end = struct.unpack("<HB", data[-3:])
        data = data[:length+4]

        if end != 0x17:
            raise InvalidPacketError()

        if checksum != checksum_func(data):
            raise InvalidPacketError()
        data = data[4:]
        if status == 0x00:
            return cls(data)
        else:
            response_class = cls.ERRORS.get(status)
            if response_class:
                raise response_class()
            else:
                raise InvalidPacketError()

class BootloaderCommand(object):
    COMMAND = None
    FORMAT = ""
    ARGS = ()
    RESPONSE = None

    def __init__(self, **kwargs):
        for arg in kwargs:
            if arg not in self.ARGS:
                raise TypeError("Argument %d not in command arguments" % (arg,))
        self.args = [kwargs[arg] for arg in self.ARGS]

    @property
    def data(self):
        return struct.pack(self.FORMAT, *self.args)

class BooleanResponse(BootloaderResponse):
    FORMAT = "B"
    ARGS = ("status",)

class VerifyChecksumCommand(BootloaderCommand):
    COMMAND = 0x31
    RESPONSE = BooleanResponse

class GetFlashSizeResponse(BootloaderResponse):
    FORMAT = "<HH"
    ARGS = ("first_row", "last_row")

class GetFlashSizeCommand(BootloaderCommand):
    COMMAND = 0x32
    FORMAT = "B"
    ARGS = ("array_id",)
    RESPONSE = GetFlashSizeResponse

class EmptyResponse(BootloaderResponse):
    pass

class EraseRowCommand(BootloaderCommand):
    COMMAND = 0x34
    FORMAT = "<BH"
    ARGS = ("array_id", "row_id")
    RESPONSE = EmptyResponse

class SyncBootloaderCommand(BootloaderCommand):
    COMMAND = 0x35
    RESPONSE = EmptyResponse

class SendDataCommand(BootloaderCommand):
    COMMAND = 0x37
    RESPONSE = EmptyResponse

    def __init__(self, data):
        self._data = data
        super(SendDataCommand, self).__init__()

    @property
    def data(self):
        return self._data

class EnterBootloaderResponse(BootloaderResponse):
    FORMAT = "<IBHB"
    ARGS = ("silicon_id", "silicon_rev", "bl_version", "bl_version_2")

class EnterBootloaderCommand(BootloaderCommand):
    COMMAND = 0x38
    RESPONSE = EnterBootloaderResponse

class ProgramRowCommand(BootloaderCommand):
    COMMAND = 0x39
    FORMAT = "<BH"
    ARGS = ("array_id", "row_id")
    RESPONSE = EmptyResponse

    def __init__(self, data, **kwargs):
        self._data = data
        super(ProgramRowCommand, self).__init__(**kwargs)

    @property
    def data(self):
        return super(ProgramRowCommand, self).data + self._data

class ChecksumResponse(BootloaderResponse):
    FORMAT = "<B"
    ARGS = ("checksum",)

class VerifyRowCommand(BootloaderCommand):
    COMMAND = 0x3A
    FORMAT = "<BH"
    ARGS = ("array_id", "row_id")
    RESPONSE = ChecksumResponse

class ExitBootloaderCommand(BootloaderCommand):
    COMMAND = 0x3B
    RESPONSE = EmptyResponse

class GetMetadataResponse(BootloaderResponse):
    FORMAT = "<BIIIxxxxxxxBBHHHxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    ARGS = (
        "checksum",
        "bootloadable_addr",
        "bootloader_last_row",
        "bootloadable_len",
        "active",
        "verified",
        "app_version",
        "app_id",
        "custom_id",
    )

class GetMetadataCommand(BootloaderCommand):
    COMMAND = 0x3C
    FORMAT = "<B"
    ARGS = ("application_id", )
    RESPONSE = GetMetadataResponse

class BootloaderSession(object):
    def __init__(self, transport, checksum_func, chunksize):
        self.transport = transport
        self.checksum_func = checksum_func
        self.chunksize = chunksize
        self.errors = 0

    def send(self, command, read=True):
        tries = 5
        data = command.data
        packet = "\x01" + struct.pack("<BH", command.COMMAND, len(data)) + data
        packet = packet + struct.pack('<H', self.checksum_func(packet)) + "\x17"

        while tries:
            try:
                self.transport.send(packet)

                if read:
                    response = self.transport.recv()
                    r = command.RESPONSE.decode(response, self.checksum_func)
                    return r
                else:
                    return None
            except InvalidPacketError:
                tries = tries-1
                self.errors = self.errors+1
                if tries == 0:
                    raise BootloaderError("Too many invalid packet errors, high error rate in data link! Please check parity, cable length, etc.")

    def enter_bootloader(self, repinits):
        savedtimeout = self.transport.f.timeout
        if repinits:
            self.transport.f.timeout = 0.1

        repinits = repinits*10
        while repinits:
            try:
                self.send(EnterBootloaderCommand())
                repinits = 0
            except:
                repinits = repinits - 1

        # Looks like its useful when a previous wasnt complete but the bootloader wasnt reset.
        self.send(SyncBootloaderCommand(), read=False)
        time.sleep(0.1)
        response = self.send(EnterBootloaderCommand())

        self.transport.f.timeout = savedtimeout
        self.errors = 0

        return response.silicon_id, response.silicon_rev, response.bl_version | (response.bl_version_2 << 16)

    def exit_bootloader(self):
        self.send(ExitBootloaderCommand(), read=False)

    def get_flash_size(self, array_id):
        response = self.send(GetFlashSizeCommand(array_id=array_id))
        return response.first_row, response.last_row

    def verify_checksum(self):
        return bool(self.send(VerifyChecksumCommand()).status)

    def get_metadata(self, application_id=0):
        return self.send(GetMetadataCommand(application_id=application_id))

    def program_row(self, array_id, row_id, rowdata):
        if (len(rowdata) % self.chunksize) != 0:
            raise BootloaderError("row is not divisible into integer chunks!")

        r = range(0, len(rowdata)+1, self.chunksize)
        for i in range(0, len(r)):
            s = slice(r[i], r[i+1])
            if (r[i+1] == len(rowdata)):
                self.send(ProgramRowCommand(
                    rowdata[s],
                    array_id=array_id,
                    row_id=row_id))
                break
            else:
                self.send(SendDataCommand(rowdata[s]))

    def erase_row (self, array_id, row):
        self.send(EraseRowCommand(
            array_id=array_id,
            row_id=row))

    def get_row_checksum(self, array_id, row_id):
        return self.send(VerifyRowCommand(array_id=array_id, row_id=row_id)).checksum

class SerialTransport(object):
    def __init__(self, f):
        self.f = f

    def send(self, data):
        self.f.write(data)

    def recv(self):
        data = self.f.read(4)
        if len(data) < 4:
            raise TimeoutError("Timed out waiting for Bootloader response.")
        size = struct.unpack("<H", data[-2:])[0]
        data += self.f.read(size + 3)
        if len(data) < size + 7:
            raise TimeoutError("Timed out waiting for Bootloader response.")
        return data

def sum_checksum(data):
    sum = 0

    for b in data:
        b = ord(b)
        sum = sum+b

    sum = 0x10000 - sum
    return sum & 0xFFFF

def crc16_checksum(data):
    crc = 0xffff

    for b in data:
        b = ord(b)
        for i in range(8):
            if (crc & 1) ^ (b & 1):
                crc = (crc >> 1) ^ 0x8408
            else:
                crc >>= 1
            b >>= 1

    crc = (crc << 8) | (crc >> 8)
    return ~crc & 0xffff


#!/usr/bin/env python
#coding=utf-8
# File Name: mysqldump.py
# Author: ZhouPan / github:dreamer2018
# Mail: zhoupans_mail@163.com
# Blog: blog.csdn.net/it_dream_er
# Function:分别在每天的 6，12，18，24 点进行数据库的备份
# Created Time: 2016年02月28日 星期日 15时35分59秒
import os
import time
from conf import *
def mysqldump():
    filename=str(time.strftime("%Y%m%d%H%M%S",time.localtime(time.time())))
    filename='dump/'+filename
    dump_commond="mysqldump -u "+username+" -p"+passwd+" "+database+" > "+filename+".sql"
    os.system(dump_commond)
def gettime():
    now_hour= int(time.strftime("%H",time.localtime(time.time())))
    now_min = int(time.strftime("%M",time.localtime(time.time())))
    now_sec = int(time.strftime("%S",time.localtime(time.time())))
    return now_hour,now_min,now_sec
def timeer():
    hour,minute,second=gettime()
    if hour < 6:
        sleeptime=(6-hour)*3600-minute*60-second
        time.sleep(sleeptime)
        mysqldump()
    elif hour < 12:
        sleeptime=(12-hour)*3600-minute*60-second
        time.sleep(sleeptime)
        mysqldump()
    elif hour<18:
        sleeptime=(18-hour)*3600-minute*60-second
        time.sleep(sleeptime)
        mysqldump()
    else:
        sleeptime=(24-hour)*3600-minute*60-second
        time.sleep(sleeptime)
        mysqldump()
def main():
    while True:
        timeer()
main()


##
#
# nwpsTrkngCG0GYX - Joe Maloney  2016-07-08
#
#   Smart Init for nwpsTrkngCG0GYX model.
#
##

from Init import *
from nwpsTrkngCG0 import *

##--------------------------------------------------------------------------
## Module that calculates surface weather elements from nwpsTrkngCG0 model
## output.
##--------------------------------------------------------------------------
class nwpsTrkngCG0GYXForecaster(nwpsTrkngCG0Forecaster):
    def __init__(self):
        nwpsTrkngCG0Forecaster.__init__(self, "nwpsTrkngCG0GYX", "nwpsTrkngCG0GYX")

def main():
    forecaster = nwpsTrkngCG0GYXForecaster()
    forecaster.run()
    forecaster.notifyGFE('GYX')

if __name__ == "__main__":
    main()


import pandas as pd
import numpy as np
import time
import datetime as dt
import os
from tqdm import tqdm
from sklearn.cluster import KMeans
from sklearn.cluster import AgglomerativeClustering
from sklearn.cluster import DBSCAN
from dtw import dtw
from sklearn.metrics import pairwise_distances
PRE_NAME = "onemin_ohlc_"
BEGIN_TIME = "09:00:00"
END_TIME = "11:00:00"
def load_data():
    X = []
    Y = []
    # df = pd.read_csv(os.path.join('dataset', '2327', PRE_NAME+"20180612.csv"))
    # mask = (df.loc[:, "time"] >= BEGIN_TIME) & (df.loc[:, "time"] <= END_TIME)
    # front_df = df[mask].loc[:, "return"]
    # end_df = df[~mask].loc[:, "return"]
    # X.append(np.array(front_df))
    # Y.append(np.array(end_df))
    # """我是分隔線^^~"""
    # df = pd.read_csv(os.path.join('dataset', '2327', PRE_NAME+"20180613.csv"))
    # mask = (df.loc[:, "time"] >= BEGIN_TIME) & (df.loc[:, "time"] <= END_TIME)
    # front_df = df[mask].loc[:, "return"]
    # end_df = df[~mask].loc[:, "return"]
    # X.append(np.array(front_df))
    # Y.append(np.array(end_df))

    sid = '2327'
    for file in os.listdir(os.path.join('dataset', sid)):
        # print(file)
        df = pd.read_csv(os.path.join('dataset', sid, file))
        mask = (df.loc[:, "time"] >= BEGIN_TIME) & (df.loc[:, "time"] <= END_TIME)
        front_df = df[mask].loc[:, "return"]
        # print(front_df)
        # exit()
        end_df = df[~mask].loc[:, "return"]
        if len(front_df) == 121:
        #     print(df.to_string())
        #     exit()
        # print(np.array(front_df).shape)
            X.append(np.array(front_df))
            Y.append(np.array(end_df))
    # print(end_df)
    # df = pd.read_csv(os.path.join('dataset', '2327', PRE_NAME+"20180612.csv"))
    # print(len(X))
    # print(len(X[0]))
    # X = np.array(X)
    # print(X.shape)

    # exit()
    return np.array(X), np.array(Y)

def dtw_d(X, Y):
    manhattan_distance = lambda x, y: np.abs(x - y)
    d, cost_matrix, acc_cost_matrix, path = dtw(X, Y, dist=manhattan_distance)
    return d

def dtw_affinity(X):
    return pairwise_distances(X, metric=dtw_d)

if __name__ == "__main__":
    X, Y = load_data()
    # print(X.shape)
    # print(X.shape)
    # print(np.array)
    # print(dtw_d(X[0], X[1]))
    # exit()
    # print(d)
    db = DBSCAN(metric=dtw_d, n_jobs=5)
    X_label = db.fit_predict(X)
    print(X_label)
    print(X.shape)


import io
from typing import BinaryIO, ClassVar

from ._fastobo import FastoboSerializer
from .base import BaseSerializer

class OboSerializer(FastoboSerializer, BaseSerializer):

    format = "obo"

    def dump(self, file):
        writer = io.TextIOWrapper(file)
        try:
            # dump the header
            if self.ont.metadata:
                header = self._to_header_frame(self.ont.metadata)
                file.write(str(header).encode("utf-8"))
                if self.ont._terms or self.ont._relationships:
                    file.write(b"\n")
            # dump terms
            if self.ont._terms:
                for i, (id, data) in enumerate(self.ont._terms.items()):
                    frame = self._to_term_frame(data)
                    file.write(str(frame).encode("utf-8"))
                    if i < len(self.ont._terms) - 1 or self.ont._relationships:
                        file.write(b"\n")
            # dump typedefs
            if self.ont._relationships:
                for i, (id, data) in enumerate(self.ont._relationships.items()):
                    frame = self._to_typedef_frame(data)
                    file.write(str(frame).encode("utf-8"))
                    if i < len(self.ont._relationships) - 1:
                        file.write(b"\n")
        finally:
            writer.detach()


from utilities import PrintException, removeNS, addPrefixes
from config import namespaces, profileWelcome, profileDefinitions, sparql, ignore
import json
import sys
import os
from SPARQLWrapper import JSON, SPARQLWrapper
from datetime import datetime, timedelta
import re

sparqlData = "http://206.167.181.124:7200/repositories/era-dd"
sparqlData = SPARQLWrapper(sparqlData)
sparqlData.setReturnFormat(JSON)
with open ('modifyDD.txt' , 'w+') as out:
	for subgraph in ['community', 'collection', 'generic', 'thesis', 'oai_pmh', 'oai_etdms', 'instances']:
		#out.write("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> prefix ual: <http://terms.library.ualberta.ca/> prefix ualid: <http://terms.library.ualberta.ca/id>" + "\n")
		sparqlData.setQuery("prefix ual: <http://terms.library.ualberta.ca/> select  * where {graph ual:%s  {?s ?p ?o} }" %(subgraph))
		r = sparqlData.query().convert()['results']['bindings']
		for triple in r:
			subject = triple['s']['value'].lower()
			predicate = triple['p']['value']
			objectt = triple['o']['value']
			print (objectt)
			sparql = "http://206.167.181.124:7200/repositories/test/statements"
			sparql = SPARQLWrapper(sparql)
			sparql.setMethod('POST')
			if triple['o']['type'] == "uri":
				print ("uri")
				query = "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> prefix ual: <http://terms.library.ualberta.ca/> prefix ualid: <http://terms.library.ualberta.ca/id> INSERT DATA {GRAPH ual:%s {<%s> <%s> <%s>} } " % (subgraph, subject, predicate, objectt)
			if triple['o']['type'] == "literal":
				print (subject, " is a literal")
				query = 'PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> prefix ual: <http://terms.library.ualberta.ca/> prefix ualid: <http://terms.library.ualberta.ca/id> INSERT DATA {GRAPH ual:%s {<%s> <%s> "%s"} } ; ' % (subgraph, subject, predicate, objectt)
			#out.write(query + "\n")
			sparql.setQuery(query)
			sparql.query()
			#query = "INSERT DATA {GRAPH ual:%s {<%s> <http://terms.library.ualberta.ca/dataDictionaryLabel> <%s>} } ; " % (subgraph, subject, triple['s']['value'])
			#out.write(query + "\n")


import cv2

image = cv2.imread("images/shapes_d.png")
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# Get the thresholds
thresh = cv2.Canny(gray_image, 200, 255)

# Get the contours
contours, _ = cv2.findContours(thresh.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
print("Contours found", len(contours))

# Get approximate polygons -> in a loop
for (index, contour) in enumerate(contours):
    # The cv2 function used to approximate the number of sides in a contour
    poly_count = cv2.approxPolyDP(contour, .01 * cv2.arcLength(contour, True), True)
    # Compute the centers of the contour
    x, y, h, w = cv2.boundingRect(contour)
    center = cv2.moments(contour)
    cx = int(center['m10'] / center['m00']) - int(w / 4)
    cy = int(center['m01'] / center['m00']) - int(w / 4)
    print("Index {} -> polygon count -> {}", index, len(poly_count))

    # Calculate the dimensions

    cv2.putText(image, "{}".format(index), (cx, cy + 100), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0))

    if len(poly_count) == 3:
        shape_name = "Triangle"
        cv2.putText(image, shape_name, (cx, cy), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0))
    if len(poly_count) == 4:
        if w / h == 1:
            shape_name = "Square"
            cv2.putText(image, shape_name, (cx, cy), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 1, 0), 1)
        else:
            shape_name = "Rectangle"
            cv2.putText(image, shape_name, (cx, cy), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 100, 0), 1)
    if len(poly_count) > 20:
        shape_name = "Circle"
        cv2.putText(image, shape_name, (cx, cy), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 100, 0), 1)

cv2.imshow("Image", image)
cv2.waitKey(0)
cv2.destroyAllWindows()


import pandas as pd
import numpy as np
##判断缺失值位置：用NaN和None表示缺失值，isnull函数返回布尔型数组判断哪个元素是缺失值
string_data=pd.Series(['Allan','Sminit','adkao',np.nan,None])
string_data
string_data.isnull()
##过滤缺失值：dropna(axis=0,how='any',thresh=None),返回的是一个处理缺失值之后的DataFrame(Series)类型
string_data.dropna()     #返回的是一个Series类型
data=pd.DataFrame([[1.,6.5,3.],[1.,np.NaN,np.NaN],[3.,np.NaN,np.NaN],[np.NaN,6.5,4.]])
cleaned=data.dropna()
data
cleaned
data.dropna(thresh=3,axis=1)  ##表示返回 其中至少有3个非NAN值的列
##填充缺失值fillna(value,method=None,asis=0,inplace=False,limit=None)，参数inplace=True时表示不返回一个新的DataFrame类型，即改变原数组
data.fillna({'1':0,'2':1,'3':2},limit=2)  ##字典只能在列方向上填充，每列最大填充个数为2个
data.fillna(method='ffill',axis=1)  ##设置以行方向进行填充，填充方法设置为前一个值替代NAN值，不能同时设置方法和填充数值

##数据转换duplicated(subset=['col1','col2'],'first')  ##subset为进行比较的列标签first参数表示在所有的重复项中第一个出现的数据标记为False，其余为True
#对Series类型重复数据进行的处理
s = pd.Series(['one', 'one','two', 'two', 'two', 'three', 'four'] ,index= ['a', 'a', 'b', 'c', 'b', 'a','c'],name='sname')
s.duplicated()
s.duplicated('last')    ##参数'last'将重复项的最后一个标记为False,其余的重复项全部标记为True
s.duplicated(False)
##对于DataFrame数据进行重复项的处理
df = pd.DataFrame({'col1':['one', 'one', 'two', 'two', 'two', 'three', 'four'], 'col2': [1, 2, 1, 2, 1, 1, 1],
                   'col3':['AA','BB','CC','DD','EE','FF','GG']},index=['a', 'a', 'b', 'c', 'b', 'a','c'])
df.index.duplicated(keep='last')   ##根据索引标记重复#第一、二、三、四被标记为重复
df.duplicated(['col1','col2'],keep=False) #在col1和col2列上出现相同的，都被标记为重复(False表示标记所有的重复项)
df.duplicated('col1','last')#第一、三、四行被标记重复

##返回标记为Fals的子集(行) df.drop_duplicates(),参数可以设置和duplicated相同
df.drop_duplicates()

##计算指标和虚拟变量
mnames=['movie_id','title','genres']
movies = pd.read_table('movies.dat',sep='::',header=None,engine='python',names=mnames)
#movies.head()
all_genres=[]
for x in movies.genres:
    all_genres.extend(x.split('|'))
genres = pd.unique(all_genres)
genres
zero_matrix = np.zeros((len(movies),len(genres)))    ##len(df),返回df的行数
dummies = pd.DataFrame(zero_matrix,columns=genres)   ##dummies.shape=3883*18
# =============================================================================
# gen = movies.genres[0]
# gen.split('|')
# dummies.columns.get_indexer(gen.split('|'))          #返回索引目标在列标签索引中的位置，得到数组对象，如果搜素的索引对象不在索引标签里则返回-1
# =============================================================================
for i,gen in enumerate(movies.genres):
    indices = dummies.columns.get_indexer(gen.split('|'))      ##得到每个索引在列标签中数组的位置
    dummies.iloc[i,indices] = 1                                ##提取出第i行，第indices的数据
movies_windic = movies.join(dummies.add_prefix('Genre_'))
movies_windic.iloc[7]     ##返回第8行的数据信息
# =============================================================================
# loc,iloc的用法：两个函数通常都是对象于DataFrame和Series类型的数据，其中loc的参数是索引名称，iloc是索引的行号，是数字
# =============================================================================

#将get_dummies与cut等离散化函数结合使用
np.random.seed(12345)
values = np.random.rand(10)
values
bins=[0,0.2,0.4,0.6,0.8,1]
pd.get_dummies(pd.cut(values, bins))        ##类似独热码的编码

# =============================================================================
# 正则表达式：正则表达式是由普通字符（例如字符 a 到 z）以及特殊字符（称为"元字符"）组成的文字模式。模式描述在搜索文本时要匹配的一个或多个字符串。正则表达式作为一个模板，将某个字符模式与所搜索的字符串进行匹配。
# =============================================================================
import re
text = """Dave dave@google.com
steve steve@gmail.com
rob rob@gmail.com
ryan ryan@yahoo.com
1234@12306\.com
"""
pattern = r'[A-Z0-9.+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}' # %与-无特殊含义，单独出现(r表示后面输入的否是字符，\.表示字符.)
regex = re.compile(pattern,flags=re.IGNORECASE)
#m=regex.match(text)  空值
m=regex.search(text)
text[m.start():m.end()]
regex.findall(text)
regex
print(regex.sub('All Study',text))    ##将tet中所有符合正则式的表达式用All Study代替

data = {'Dava':'dava@google.com','Steven':'stven@gmail.com','WES':np.nan}
data = pd.Series(data)
##对Series类型的数据进行信量化，可以有效地处理缺失值
data.str.findall(pattern , flags = re.IGNORECASE)
pattern= r'([A-Z0-9.+-]+)@([A-Z0-9.-]+)\.([A-Z]{2,4})'
matches = data.str.match(pattern,flags=re.IGNORECASE)
data.str.get[0]       #从列表、字符串、元组中索引返回索引值，data的元素是标量，返回NAN


#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Copyright © 2012 Johannes S. Mueller-Roemer. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
   derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""

import re
import datetime
import os
import urllib.request as urllib
import codecs
import subprocess

if not os.path.exists('gl3.h'):
    print('Downloading gl3.h...')
    web = urllib.urlopen('http://www.opengl.org/registry/api/gl3.h')
    with open('gl3.h', 'wb') as f:
        f.writelines(web.readlines())
else:
    print('Using existing gl3.h...')

gl3hf = open('gl3.h', 'r')
gl3h = gl3hf.read()
gl3hf.close()

print('Parsing gl3.h...')
defReg = re.compile(r'#define\s+GL_([A-Z0-9_]+)\s+([0-9a-fA-Fx]+)')
verReg = re.compile(r'VERSION_(\d)_(\d)')
procReg = re.compile(r'GLAPI\s+(\w+)\s+APIENTRY\s+gl(\w+)\s*\((.*)\)')

vers = []
defs = []

for defn in defReg.finditer(gl3h):
    ver = verReg.match(defn.group(1))
    if ver:
        vers.append([int(defn.start()), int(ver.group(1)), int(ver.group(2))])
    else:
        defs.append([defn.group(1), defn.group(2)])

for i in range(len(vers)-1):
    vers[i][0] = vers[i+1][0]
vers[-1][0] = len(gl3h)

procs = []

for proc in procReg.finditer(gl3h):
    procs.append([proc.start(), proc.group(1), proc.group(2), proc.group(3)])

print('Writing gl3.go...')
gl3go = codecs.open('gl3.go', 'w', 'utf-8')

gl3go.write(r'''/******************************************************************************
 * Copyright © %s Johannes S. Mueller-Roemer. All rights reserved.          *
 *                                                                            *
 * Redistribution and use in source and binary forms, with or without         *
 * modification, are permitted provided that the following conditions         *
 * are met:                                                                   *
 * 1. Redistributions of source code must retain the above copyright          *
 *    notice, this list of conditions and the following disclaimer.           *
 * 2. Redistributions in binary form must reproduce the above copyright       *
 *    notice, this list of conditions and the following disclaimer in the     *
 *    documentation and/or other materials provided with the distribution.    *
 * 3. The names of the authors may not be used to endorse or promote products *
 *    derived from this software without specific prior written permission.   *
 *                                                                            *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR      *
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES  *
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.    *
 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,          *
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT   *
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,  *
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY      *
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT        *
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF   *
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.          *
 ******************************************************************************/

package gl

import (
    "github.com/lxn/go-winapi"
    "syscall"
    "unsafe"
)

const (
''' % (datetime.date.today().year))

for defn in defs:
    gl3go.write('%s = %s\n' % tuple(defn))

gl3go.write(r''')

var (
''')

for proc in procs:
    gl3go.write('gl%s uintptr\n' % (proc[2]))

gl3go.write(r''')

func Init() {
    lib := syscall.Handle(winapi.MustLoadLibrary("opengl32.dll"))

    var err error
    supported := true
    var _ = supported
''')

ver = 0
gl3go.write('// GL %d.%d\n' % tuple(vers[ver][1::]))
for proc in procs:
    if proc[0] >= vers[ver][0]:
        ver += 1
        gl3go.write('// GL %d.%d\n' % tuple(vers[ver][1::]))
    gl3go.write('''gl%(1)s = winapi.WglGetProcAddress(syscall.StringToUTF16Ptr("gl%(1)s"))
if gl%(1)s == 0 {
    gl%(1)s, err = syscall.GetProcAddress(lib, "gl%(1)s")
    if err != nil {
        supported = false
    }
}

''' % { '1' : proc[2] })

gl3go.write(r'''}
''')

typemap = {
    'GLenum' : 'uint32',
    'GLboolean' : 'uint8',
    'GLbitfield' : 'uint32',
    'GLbyte' : 'int8',
    'GLshort' : 'int16',
    'GLint' : 'int32',
    'GLsizei' : 'int32',
    'GLubyte' : 'uint8',
    'GLushort' : 'uint16',
    'GLuint' : 'uint32',
    'GLuint64' : 'uint64',
    'GLhalf' : 'uint16',
    'GLfloat' : 'float32',
    'GLclampf' : 'float32',
    'GLdouble' : 'float64',
    'GLclampd' : 'float64',
    'GLintptr' : 'uintptr',
    'GLsizeiptr' : 'uintptr',

    'GLenum *' : '[]uint32',
    'const GLenum *' : '[]uint32',
    'GLboolean *' : '[]uint8',
    'const GLboolean *' : '[]uint8',
    'GLbyte *' : '[]int8',
    'const GLbyte *' : '[]int8',
    'GLshort *' : '[]int16',
    'const GLshort *' : '[]int16',
    'GLint *' : '[]int32',
    'const GLint *' : '[]int32',
    'GLint64 *' : '[]int64',
    'const GLint64 *' : '[]int64',
    'GLuint64 *' : '[]uint64',
    'GLsizei *' : '[]int32',
    'const GLsizei *' : '[]int32',
    'GLubyte *' : '[]uint8',
    'const GLubyte *' : '[]uint8',
    'GLushort *' : '[]uint16',
    'const GLushort *' : '[]uint16',
    'GLuint *' : '[]uint32',
    'const GLuint *' : '[]uint32',
    'GLfloat *' : '[]float32',
    'const GLfloat *' : '[]float32',
    'GLdouble *' : '[]float64',
    'const GLdouble *' : '[]float64',
    'GLchar *' : '[]uint8',
    'const GLchar *' : '[]uint8',
    'const GLchar* *' : '[][]uint8',
    'const GLchar* const *' : '[][]uint8',

    'GLDEBUGPROCARB' : 'uintptr',
    'GLsync' : 'uintptr',
    'struct _cl_context *' : 'uintptr',
    'struct _cl_event *' : 'uintptr',
    'GLvoid *' : 'uintptr',
    'const void *' : 'uintptr',
    'const GLvoid *' : 'uintptr',

    'const GLvoid* const *' : '[]uintptr',
    'GLvoid* *' : '*uintptr'
}

keywords = {
    'type' : 'type_',
    'func' : 'func_',
    'range' : 'range_',
    'map' : 'map_'
}

for proc in procs:
    ret = proc[1]
    params = []
    if proc[3] != 'void':
        for param in proc[3].split(','):
            p = re.match('(.*?)(\w+)$', param.strip())
            params.append([typemap.get(p.group(1).strip(), None), keywords.get(p.group(2).strip(), p.group(2).strip())])
            if not params[-1][0]:
                print("Unknown type: '%s' (gl%s)" % (p.group(1).strip(), proc[2]))
    gl3go.write('\nfunc %s(\n' % proc[2])
    for param in params:
        gl3go.write('%s %s,\n' % (param[1], param[0]))
    if ret != 'void':
        ret_ = ret
        ret = typemap.get(ret_, None)
        if not ret:
            print("Unknown type: '%s' (gl%s)" % (ret_, proc[2]))
            ret = 'void'
        gl3go.write(') %s {\nret, _, _ := ' % (ret))
    else:
        gl3go.write(') {\n')
    nRound = ((len(params)+2)//3)*3
    nRound = 3 if nRound < 3 else nRound
    gl3go.write('syscall.Syscall%s(\ngl%s,\n%d,\n' % ('' if nRound == 3 else nRound, proc[2], len(params)))
    for p in params:
        if re.match('\[\]', p[0]):
            gl3go.write('uintptr(unsafe.Pointer(&%s[0])),\n' % (p[1]))
        elif re.match('\*', p[0]):
            gl3go.write('uintptr(unsafe.Pointer(%s)),\n' % (p[1]))
        else:
            gl3go.write('uintptr(%s),\n' % (p[1]))
    for i in range(nRound-len(params)):
        gl3go.write('0,\n')
    if ret != 'void':
        gl3go.write(')\nreturn %s(ret)\n}\n\n' % (ret))
    else:
        gl3go.write(')\n}\n\n')

#for proc in procs:
#    """
#    match = re.match(r'(.*?)u?[bsifd]v?(?:ARB)?$', proc[1])
#    if match:
#        print(match.group(1))
#    """
#    print("%s gl%s(%s)" % proc)

gl3go.close()

print('Formatting gl3.go...')
subprocess.call(['gofmt', '-w=true', 'gl3.go'])


"""
Copyright (c) 2020 1-2.dev
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""

import hashlib
import os
import re
import tempfile
from typing import Dict

import requests

__author__ = "Sascha Greuel"
__copyright__ = "Copyright 2020, Sascha Greuel"
__license__ = "MIT"
__maintainer__ = "Sascha Greuel"
__email__ = "hello@1-2.dev"
__status__ = "Production"

root = os.getcwd() + os.path.sep

def get_versions() -> Dict[str, str]:
    """ Returns a list of version numbers for imagemagick, libaom & libheif """
    api_base = "https://api.github.com/repos"
    file_base = "https://github.com"

    if "GITHUB_TOKEN" in os.environ:
        headers = {"Authorization": "Bearer " + os.environ['GITHUB_TOKEN']}
    else:
        headers = {}

    # Get version information for ImageMagick and write it to file
    data = requests.get(
        api_base + '/ImageMagick/ImageMagick/tags',
        headers=headers
    ).json()
    imagemagick_ver = re.sub(r'[^0-9.\-]', r'', data[1]['name'])
    open(root + 'versions' + os.path.sep + 'imagemagick.version', 'w+').write(imagemagick_ver)

    # Download ImageMagick tarball, calculate it's hash and write it to file
    open(root + 'versions' + os.path.sep + 'imagemagick.hash', 'w+').write(get_hash(
        file_base + '/ImageMagick/ImageMagick/archive/' + imagemagick_ver + '.tar.gz'
    ))

    # Get version information for aom and write it to file
    data = requests.get(
        api_base + '/jbeich/aom/tags',
        headers=headers
    ).json()
    libaom_ver = re.sub(r'[^0-9.]', r'', data[0]['name'])
    open(root + 'versions' + os.path.sep + 'aom.version', 'w+').write(libaom_ver)

    # Download aom tarball, calculate it's hash and write it to file
    open(root + 'versions' + os.path.sep + 'aom.hash', 'w+').write(get_hash(
        file_base + '/jbeich/aom/archive/v' + libaom_ver + '.tar.gz'
    ))

    # Get version information for libheif and write it to file
    data = requests.get(
        api_base + '/strukturag/libheif/tags',
        headers=headers
    ).json()
    libheif_ver = re.sub(r'[^0-9.]', r'', data[0]['name'])
    open(root + 'versions' + os.path.sep + 'libheif.version', 'w+').write(libheif_ver)

    # Download aom tarball, calculate it's hash and write it to file
    open(root + 'versions' + os.path.sep + 'libheif.hash', 'w+').write(get_hash(
        file_base + '/strukturag/libheif/releases/download/v' + libheif_ver + '/libheif-' + libheif_ver + '.tar.gz'
    ))

    # Return version information for README updates
    return {
        'imagemagick': imagemagick_ver,
        'libaom': libaom_ver,
        'libheif': libheif_ver
    }

def get_hash(url):
    """ Returns the SHA1 hash for the given file from URL """
    if "GITHUB_TOKEN" in os.environ:
        headers = {"Authorization": "Bearer " + os.environ['GITHUB_TOKEN']}
    else:
        headers = {}

    sha1 = hashlib.sha1()
    tf = tempfile.NamedTemporaryFile()

    with open(tf.name, "wb") as f:
        response = requests.get(url, headers=headers)
        f.write(response.content)

    with open(tf.name, "rb") as f:
        while True:
            chunk = f.read(sha1.block_size)
            if not chunk:
                break
            sha1.update(chunk)

    return sha1.hexdigest()

if __name__ == '__main__':
    readme_path = root + "README.md"
    readme = open(readme_path, "r").read()
    versions = get_versions()
    replacement = "\n* ImageMagick version: `" + versions['imagemagick'] + "`\n"
    replacement += "* libaom version: `" + versions['libaom'] + "`\n"
    replacement += "* libheif version: `" + versions['libheif'] + "`"

    r = re.compile(
        r'<!-- versions start -->.*<!-- versions end -->'.format(),
        re.DOTALL,
    )

    replacement = '<!-- versions start -->{}<!-- versions end -->'.format(replacement)

    open(readme_path, "w").write(r.sub(replacement, readme))


from abc import ABCMeta, abstractmethod
from contextlib import asynccontextmanager

__all__ = ["get_backend", "Backend"]

class Backend(metaclass=ABCMeta):
    def __init__(self, tg):
        self._tg = tg

    @abstractmethod
    @asynccontextmanager
    async def connect(self, *a, **k):
        """
        This async context manager returns a connection.
        """

    async def aclose(self):
        """
        Force-close the connection.
        """
        await self._tg.cancel_scope.cancel()

    def spawn(self, *a, **kw):
        return self._tg.spawn(*a, **kw)

    @abstractmethod
    @asynccontextmanager
    async def monitor(self, *topic):
        """
        Return an async iterator that listens to this topic.
        """

    @abstractmethod
    async def send(self, *topic, payload):
        """
        Send this payload to this topic.
        """

def get_backend(name):
    from importlib import import_module
    if '.' not in name:
        name = "distkv.backend."+name
    return import_module(name).connect


# -*- coding: utf-8 -*-
"""
Created on Tue Oct 22 14:44:21 2019

@author: IST_1
"""

import pandas as pd
import op_models
from matplotlib import pyplot as plt

intrepid_data = pd.read_excel('ISASM CustCare 2019 r2.xlsx')

intrepid_data['dayofyear'] = intrepid_data.Timestamp.dt.dayofyear

dayahead_2018_lbmp = pd.read_csv('OASIS_Day-Ahead_Market_Zonal_LBMP_NYC_2018.csv')
dayahead_2018_lbmp['total'] = (dayahead_2018_lbmp['DAM Zonal LBMP']+dayahead_2018_lbmp['DAM Zonal Losses']-dayahead_2018_lbmp['DAM Zonal Congestion'])
dayahead_2017_lbmp = pd.read_csv('OASIS_Day-Ahead_Market_Zonal_LBMP_NYC_2017.csv')
dayahead_2017_lbmp['total'] = (dayahead_2017_lbmp['DAM Zonal LBMP']+dayahead_2017_lbmp['DAM Zonal Losses']-dayahead_2017_lbmp['DAM Zonal Congestion'])
dayahead_2016_lbmp = pd.read_csv('OASIS_Day-Ahead_Market_Zonal_LBMP_NYC_2016.csv')
dayahead_2016_lbmp['total'] = (dayahead_2016_lbmp['DAM Zonal LBMP']+dayahead_2016_lbmp['DAM Zonal Losses']-dayahead_2016_lbmp['DAM Zonal Congestion'])
dayahead_2016_lbmp = dayahead_2016_lbmp.drop(dayahead_2016_lbmp.index[1416:1440])
dayahead_2015_lbmp = pd.read_csv('OASIS_Day-Ahead_Market_Zonal_LBMP_NYC_2015.csv')
dayahead_2015_lbmp['total'] = (dayahead_2015_lbmp['DAM Zonal LBMP']+dayahead_2015_lbmp['DAM Zonal Losses']-dayahead_2015_lbmp['DAM Zonal Congestion'])

total_dayahead_lbmp = pd.DataFrame(columns=['date','2015','2016','2017','2018','average'])
total_dayahead_lbmp = pd.DataFrame(pd.date_range(start='1/1/2018', end='1/1/2019',freq='H'))
total_dayahead_lbmp = total_dayahead_lbmp.drop(total_dayahead_lbmp.index[-1],axis=0)
total_dayahead_lbmp = total_dayahead_lbmp.rename(columns={0:'date'})
total_dayahead_lbmp['2015'] = dayahead_2015_lbmp.total
total_dayahead_lbmp['2016'] = dayahead_2016_lbmp.total
total_dayahead_lbmp['2017']= dayahead_2017_lbmp.total
total_dayahead_lbmp['2018'] = dayahead_2018_lbmp.total

total_dayahead_lbmp['average'] = total_dayahead_lbmp[['2015','2016','2017','2018']].sum(axis=1)/4
lbmp = total_dayahead_lbmp['average'].repeat(4).shift(-1)[0:24817].reset_index(drop=True)

intrepid_data['lbmp'] = lbmp/4/1000

intrepid_data = intrepid_data.drop(columns={'Period','Datehour'})
intrepid_data = intrepid_data.rename(columns={'Timestamp':'date','Con Ed kW':'original_building_power_kw'})
intrepid_data['energy_rate'] = 0.0079
#intrepid_data['energy_rate'] = intrepid_data.lbmp

intrepid_data["demand_rate1"] = [0] * len(intrepid_data.index)
intrepid_data["demand_rate_category1"] = [0] * len(intrepid_data.index)
intrepid_data["demand_rate2"] = [0] * len(intrepid_data.index)
intrepid_data["demand_rate_category2"] = [0] * len(intrepid_data.index)

demand_tariff_type = "SC9 Rate 2"
# conditions
intermediate_peak = ((intrepid_data['date'].dt.month <= 5) | (intrepid_data['date'].dt.month >= 10)) & (
        (intrepid_data['date'].dt.weekday >= 0) &
        (intrepid_data['date'].dt.weekday <= 5)) & \
          ((intrepid_data['date'].dt.hour >= 8) & (intrepid_data['date'].dt.hour < 22))

on_peak1 = ((intrepid_data['date'].dt.month >= 6) & (intrepid_data['date'].dt.month <= 9)) & (
        (intrepid_data['date'].dt.weekday >= 0) &
        (intrepid_data['date'].dt.weekday <= 5)) & \
          ((intrepid_data['date'].dt.hour >= 8) & (intrepid_data['date'].dt.hour < 18))

on_peak2 = ((intrepid_data['date'].dt.month >= 6) & (intrepid_data['date'].dt.month <= 9)) & (
        (intrepid_data['date'].dt.weekday >= 0) &
        (intrepid_data['date'].dt.weekday <= 5)) & \
          ((intrepid_data['date'].dt.hour >= 8) & (intrepid_data['date'].dt.hour < 22))

# intermediate Demand_Rate is set for the entire column,
# and other Demand_Rates overwrite it when the conditions are met
intrepid_data.loc[intermediate_peak,"demand_rate1"] = 11.48
intrepid_data.loc[intermediate_peak,"demand_rate2"] = 11.48
intrepid_data.loc[on_peak1, "demand_rate1"] = 8.33
intrepid_data.loc[on_peak2, "demand_rate2"] = 15.56
# finding cost for all data points, then assigning categories

intrepid_data.loc[intrepid_data["demand_rate1"] == 8.33, "demand_rate_category1"] = "on_peak1"
intrepid_data.loc[intrepid_data["demand_rate2"] == 15.56, "demand_rate_category2"] = "on_peak2"
intrepid_data.loc[intrepid_data["demand_rate1"] == 11.48, "demand_rate_category1"] = "intermediate"
intrepid_data.loc[intrepid_data["demand_rate2"] == 11.48, "demand_rate_category2"] = "intermediate"
intrepid_data.loc[intrepid_data["demand_rate1"] == 0, "demand_rate_category1"] = "off_peak"
intrepid_data.loc[intrepid_data["demand_rate2"] == 0, "demand_rate_category2"] = "off_peak"

#suggest 250kW/500kWh battery here
power = 250

df2 = pd.DataFrame(columns=['intervals','solar','Ein','Eout','charge_state','system_out'])
test_dates_df = pd.DataFrame(columns=['date','dayofyear','lbmp','demand_rate1','demand_rate_category1','demand_rate2','demand_rate_category2',
                                          'original_building_power_kw','output','energy_rate'])
demand_expenses = list()
energy_expenses = list()

for i in set(intrepid_data.date.dt.month):
    test_dates = intrepid_data.loc[(intrepid_data.date.dt.month == i)]#&(data.date.dt.dayofyear <= (i+1))]
    test_dates = test_dates.reset_index(drop=True)
    df,model = op_models.peak_shave(test_dates, power=power, capacity=power*2, eff=.8, itc=False, project_type='storage only', export=False)
    df2 = pd.concat([df2,df])
    test_dates_df = pd.concat([test_dates_df,test_dates])
    demand_expenses.append((model.demand_expenses()))
    energy_expenses.append((model.energy_expenses()))

df2 = df2.reset_index(drop=True)

intrepid_data['Ein'] = df2.Ein
intrepid_data['Eout'] = df2.Eout
intrepid_data['charge_state'] = df2.charge_state
intrepid_data['system_out'] = df2.system_out

demand_expenses_total = sum(demand_expenses)
energy_expenses_total = sum(energy_expenses)
expenses = demand_expenses_total + energy_expenses_total
battery_cost = power*2*340*0.7*0.8

print('Yearly Expenses with no energy storage system: $152095.67')
print('Yearly savings with storage system of size',power,': $',152095.67-expenses)
print('Years to payback: ', battery_cost/(152095.67-expenses))

graph_beginning = 19199
graph_end = 19294
plt.figure(figsize=(15,5))
plt.plot(intrepid_data.index,intrepid_data.original_building_power_kw,intrepid_data.system_out)
plt.figure(figsize=(15,5))
plt.plot(intrepid_data.index[graph_beginning:graph_end],intrepid_data.original_building_power_kw[graph_beginning:graph_end],intrepid_data.system_out[graph_beginning:graph_end])
plt.figure(figsize=(15,5))
plt.plot(intrepid_data.index[graph_beginning:graph_end],intrepid_data.system_out[graph_beginning:graph_end])

#print(intrepid_data.loc[intrepid_data.demand_rate_category1=='off_peak'].system_out.max())
#print(intrepid_data.loc[intrepid_data.demand_rate_category1=='on_peak1'].system_out.max())
#print(intrepid_data.loc[intrepid_data.demand_rate_category2=='on_peak2'].system_out.max())
#print(intrepid_data.loc[intrepid_data.demand_rate_category1=='intermediate'].system_out.max())

#intrepid_data['lbmp'] = total_dayahead_lbmp.loc[(intrepid_data.Timestamp.dt.hour == total_dayahead_lbmp.date.dt.hour)&
#        (intrepid_data.Timestamp.dt.day == total_dayahead_lbmp.date.dt.day)&(intrepid_data.Timestamp.dt.month == total_dayahead_lbmp.date.dt.month)]


#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
    First program

    Source:
         - http://zetcode.com/gui/pyqt4/menusandtoolbars/
"""

import sys
from PyQt4 import QtGui

# Instead of QWidget use QMainWindow which comes
# w/ common UI elements like a status bar and a file bar
import sys
from PyQt4 import QtGui

class Example(QtGui.QMainWindow):

    def __init__(self):
        super(Example, self).__init__()

        self.initUI()

    def initUI(self):

        # Add 'exit' to the File->Exit.  The "&" tells Qt that the following
        # letter is a short cut for this menu item.  Here, Alt+E will exit.
        exitAction = QtGui.QAction(QtGui.QIcon('exit.png'), '&Exit', self)

        # You can also set up explicit shortcuts.
        exitAction.setShortcut('Ctrl+Q')

        # This display custom hover text
        exitAction.setStatusTip('Exit application')

        # Qt is an event driven API that uses connections
        # notify parts of your code that they need to do something.
        exitAction.triggered.connect(QtGui.qApp.quit)

        self.statusBar()

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(exitAction)

        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('Menubar')
        self.show()

def main():

    app = QtGui.QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()


#!/usr/bin/python

import xml.dom.minidom

cyclists = [("Cyclist Name", 0, 0, "59:59", "0.0")]

filePath = str(input("Enter File Name:\t"))
print(filePath)

DomTree = xml.dom.minidom.parse(filePath)
collection = DomTree.documentElement

eventParticipants = collection.getElementsByTagName("event_participant")

for eventParticipant in eventParticipants:
    participant = eventParticipant.getElementsByTagName("participant")[0]
    print(participant)
    if participant.hasAttribute("name"):
        participantName = participant.getAttribute("name")
    else:
        particpantName = "None"

    if participant.hasAttribute("id"):
        participantID = int(participant.getAttribute("id"))
        print(participantID)
    else:
        participantID = -1

    rank = -1
    duration = "+59:59"
    rankTwo = "99.99"
    results = eventParticipant.getElementsByTagName("result")

    i = 0
    for entry in results:
        #result = entry.getElementsByTagName("result")[0]
        result = entry
        i = i+1
        if result.hasAttribute("result_code"):
            result_code = result.getAttribute("result_code")
            print(result_code)
            if result_code == "rank":
                if result.hasAttribute("value"):
                    rank = int(result.getAttribute("value"))
                    rankTwo = result.getAttribute("value")
            if result_code == "duration":
                if result.hasAttribute("value"):
                    duration = result.getAttribute("value")

    cyclists.append((participantName, participantID, rank, duration, rankTwo))

for cyclist in sorted(cyclists, key=lambda contestents: contestents[2]):
    print(cyclist[0] + "\t\t|" + str(cyclist[1]) + "\t|" + str(cyclist[2]) + "\t|" + cyclist[3])


#!/usr/bin/python3.6

"""
                --- Web Scrapper ---
This module when executed, scrappes the defined website for jokes and stores them in a list in jokes.py.
When the list becomes empty, i;e all the jokes are posted, this script is automatically executed and stores
the  jokes in the list.
"""

import bs4 as bs
import urllib.request
import re
import config
import url
import time

# Link to be parsed
URL = url.getUrl(0)

# Fake user agaent
user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36'

# List stores all the parsed text
all_content = []

# Function to extract jokes from the current page
def parsePage():

    request = urllib.request.Request(URL, headers={'User-Agent': user_agent})
    response = urllib.request.urlopen(request)

    # Bs4 Object
    soup = bs.BeautifulSoup(response, 'lxml')
    for div in soup.find_all('div', class_ = 'post-text'):
        all_content.append(str(div.text))

# Find the maximum number of pages in the url
def findMaxPages():
    request = urllib.request.Request(URL, headers={'User-Agent': user_agent})
    response = urllib.request.urlopen(request)

    # Bs4 Object
    soup = bs.BeautifulSoup(response, 'lxml')
    pages = []
    for div in soup.find_all('span', class_ = 'item'):
        pages.append(int(div.text))
    maxPages = pages[-1]
    return maxPages

parsePage()

currentPage = 2
# Use this in case you want to parse the whole site

#maxPages = findMaxPages()
maxPages = 15

resetUrl = URL
URL += "/page"

# Looping each page and parsing content
while currentPage <= maxPages:
    URL += "/"+str(currentPage)
    parsePage()
    URL = URL.split("/")
    del URL[-1]
    URL = "/".join(URL)
    currentPage += 1

#print(all_content)


# coding: utf-8
# -------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------
from devtools_testutils import AzureTestCase
from azure.communication.rooms.aio import RoomsClient

class RoomsAsyncTest(AzureTestCase):
    def __init__(self, method_name, **kwargs):
        super(RoomsAsyncTest, self).__init__(method_name, **kwargs)

    def create_client(self, endpoint):
        credential = self.get_credential(RoomsClient, is_async=True)
        return self.create_client_from_credential(
            RoomsClient,
            credential=credential,
            endpoint=endpoint,
        )


"""resolute URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.0/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('power/', views.power, name='power'),
    path('last_read/', views.last_read, name='last_read'),
    path('get_last_read/', views.get_last_read, name='get_last_read'),
    path('score_card/', views.score_card, name='score_card'),
    path('voltage/', views.voltage, name='voltage'),
    path('current/', views.current, name='current'),
    path('readings/', views.readings, name='readings'),
    path('get_line_readings/', views.get_line_readings, name='get_line_readings'),
    path('max_demand/', views.max_demand, name='max_demand'),
    path('fetch_vals_period/', views.fetch_vals_period, name='fetch_vals_period'),
    path('fetch_device_vals/', views.fetch_vals_period_per_device, name='fetch_vals_period_per_device'),
    path('load_datalogs/', views.load_datalogs, name='load_datalogs'),
    path('consumption/', views.consumption, name='consumption'),
    path('power_quality/', views.power_quality, name='power_quality'),
    path('load_readings/', views.load_readings, name='load_readings'),
    path('get_yesterday_today_usage/', views.get_yesterday_today_usage, name='get_yesterday_today_usage'),
    path('get_line_readings_log/', views.get_line_readings_log, name='get_line_readings_log'),
    path('get_energy_consumption_readings/', views.get_energy_consumption_readings, name='get_energy_consumption_readings'),
    path('get_capacity_factors/', views.get_capacity_factors, name='get_capacity_factors'),
    path('messaging/', views.messaging, name='messaging'),
    path('fetch_messages/', views.fetch_messages, name='fetch_messages'),
    path('check_new_message/', views.check_new_message, name='check_new_message'),
    path('send_message/', views.send_message, name='send_message'),
    path('simple_upload/', views.simple_upload, name='simple_upload'),
    path('upload_cdd/', views.upload_cdd, name='upload_cdd'),
    path('all_customers/', views.all_customers, name='all_customers'),
    path('view_customer/<int:id>', views.view_customer, name='view_customer'),
    path('view_profile/', views.view_profile, name='view_profile'),
    path('upload_image/', views.upload_image, name='upload_image'),
    path('update_details/', views.update_details, name='update_details'),
    path('add_user/', views.add_user, name='add_user'),
    path('edit_user/', views.edit_user, name='edit_user'),
    path('update_branch/', views.update_branch, name='update_branch'),
    path('update_device/', views.update_device, name='update_device'),
    path('create_branch/', views.create_branch, name='create_branch'),
    path('create_device/', views.create_device, name='create_device'),
    path('update_historic_scores/', views.update_historic_scores, name='update_historic_scores'),
    path('get_total_energy/', views.get_total_energy, name='get_total_energy'),
    path('get_stats/', views.get_stats, name='get_stats'),
    # path('detail_view', views.detail_view, name='detail_view'),
    # path('locationpost', views.locationpost, name='locationpost'),
    # path('incidents', views.incidents, name='incidents'),
    # path('table', views.table, name='table'),
    # path('logs', views.logs, name='logs'),
    # # path('track', views.track, name='track')
    # path('check/<slug:slug>/', views.check, name='check'),
    # path('collection_check/<int:id>/', views.collection_check, name='collection_check'),
    # path('track/<slug:slug>/', views.track, name='track'),
    # path('trail/<slug:slug>/', views.trail, name='trail'),
    # path('mapping/<slug:slug>/', views.mapping, name='mapping'),
    # path('get_lat_lng/<slug:id>', views.get_lat_lng, name='get_lat_lng'),# FOR PROFILE REALTIME MAP
    # path('get_latlng/<slug:username>', views.get_latlng, name='get_latlng'),
    # path('get_latlng_incident/<slug:username>/<slug:incident>/', views.get_latlng_incident, name='get_latlng_incident'),
    # path('post_latlng', views.post_latlng, name='post_latlng'),
    # path('check_panic', views.check_panic, name='check_panic'),
    # path('create_panic', views.create_panic, name='create_panic'),
    # path('resolve_panic_mobile', views.resolve_panic_mobile, name='resolve_panic_mobile'),
    # path('resolve_panic', views.resolve_panic, name='resolve_panic'),
    # path('recurring_gps_post', views.recurring_gps_post, name='recurring_gps_post'),
    # path('farmers', views.farmers, name='farmers'),
    # path('herdsmen', views.herdsmen, name='herdsmen'),
    # path('get_client_data', views.get_client_data, name='get_client_data'),
    # path('profile_page/<int:target_id>/<slug:is_farmer>', views.profile_page, name='profile_page')

    # path('test', views.test, name='test'),
]