<commit_before># Copyright (C) 2002 Python Software Foundation
# Author: barry@zope.com (Barry Warsaw)

"""Base class for MIME multipart/* type messages.
"""

from email import MIMEBase

class MIMEMultipart(MIMEBase.MIMEBase):
    """Base class for MIME multipart/* type messages."""

    def __init__(self, _subtype='mixed', boundary=None, *_subparts, **_params):
        """Creates a multipart/* type message.

        By default, creates a multipart/mixed message, with proper
        Content-Type and MIME-Version headers.

        _subtype is the subtype of the multipart content type, defaulting to
        `mixed'.

        boundary is the multipart boundary string.  By default it is
        calculated as needed.

        _subparts is a sequence of initial subparts for the payload.  It
        must be possible to convert this sequence to a list.  You can always
        attach new subparts to the message by using the attach() method.

        Additional parameters for the Content-Type header are taken from the
        keyword arguments (or passed into the _params argument).
        """
        MIMEBase.MIMEBase.__init__(self, 'multipart', _subtype, **_params)
        if _subparts:
            self.attach(*list(_subparts))
        if boundary:
            self.set_boundary(boundary)
<commit_msg>SF patch # 884030 by Amit Aronovitch; fixes the _subpart argument to match documented semantics.<commit_after># Copyright (C) 2002-2004 Python Software Foundation
# Author: barry@python.org (Barry Warsaw)

"""Base class for MIME multipart/* type messages.
"""

from email import MIMEBase

class MIMEMultipart(MIMEBase.MIMEBase):
    """Base class for MIME multipart/* type messages."""

    def __init__(self, _subtype='mixed', boundary=None, _subparts=None,
                 **_params):
        """Creates a multipart/* type message.

        By default, creates a multipart/mixed message, with proper
        Content-Type and MIME-Version headers.

        _subtype is the subtype of the multipart content type, defaulting to
        `mixed'.

        boundary is the multipart boundary string.  By default it is
        calculated as needed.

        _subparts is a sequence of initial subparts for the payload.  It
        must be an iterable object, such as a list.  You can always
        attach new subparts to the message by using the attach() method.

        Additional parameters for the Content-Type header are taken from the
        keyword arguments (or passed into the _params argument).
        """
        MIMEBase.MIMEBase.__init__(self, 'multipart', _subtype, **_params)
        if _subparts:
            for p in _subparts:
                self.attach(p)
        if boundary:
            self.set_boundary(boundary)
<|endoftext|>


<commit_before>#!/usr/bin/env python3
# Copyright (c) 2016-2019 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Encode and decode BASE58, P2PKH and P2SH addresses."""

import unittest

from .script import OP_TRUE, CScript, CScriptOp, hash160, hash256
from .util import assert_equal, hex_str_to_bytes

ADDRESS_ECREG_UNSPENDABLE = 'ecregtest:qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqcrl5mqkt'
ADDRESS_ECREG_UNSPENDABLE_DESCRIPTOR = 'addr(ecregtest:qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqcrl5mqkt)#u6xx93xc'
# Coins sent to this address can be spent with a scriptSig of just OP_TRUE
ADDRESS_ECREG_P2SH_OP_TRUE = 'ecregtest:prdpw30fk4ym6zl6rftfjuw806arpn26fvkgfu97xt'
SCRIPTSIG_OP_TRUE = CScriptOp.encode_op_pushdata(CScript([OP_TRUE]))

chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'

def byte_to_base58(b, version):
    result = ''
    str = b.hex()
    str = chr(version).encode('latin-1').hex() + str
    checksum = hash256(hex_str_to_bytes(str)).hex()
    str += checksum[:8]
    value = int('0x' + str, 0)
    while value > 0:
        result = chars[value % 58] + result
        value //= 58
    while (str[:2] == '00'):
        result = chars[0] + result
        str = str[2:]
    return result

def base58_to_byte(s, verify_checksum=True):
    if not s:
        return b''
    n = 0
    for c in s:
        n *= 58
        assert c in chars
        digit = chars.index(c)
        n += digit
    h = '{:x}'.format(n)
    if len(h) % 2:
        h = '0' + h
    res = n.to_bytes((n.bit_length() + 7) // 8, 'big')
    pad = 0
    for c in s:
        if c == chars[0]:
            pad += 1
        else:
            break
    res = b'\x00' * pad + res
    if verify_checksum:
        assert_equal(hash256(res[:-4])[:4], res[-4:])

    return res[1:-4], int(res[0])

def keyhash_to_p2pkh(hash, main=False):
    assert (len(hash) == 20)
    version = 0 if main else 111
    return byte_to_base58(hash, version)

def scripthash_to_p2sh(hash, main=False):
    assert (len(hash) == 20)
    version = 5 if main else 196
    return byte_to_base58(hash, version)

def key_to_p2pkh(key, main=False):
    key = check_key(key)
    return keyhash_to_p2pkh(hash160(key), main)

def script_to_p2sh(script, main=False):
    script = check_script(script)
    return scripthash_to_p2sh(hash160(script), main)

def check_key(key):
    if (isinstance(key, str)):
        key = hex_str_to_bytes(key)  # Assuming this is hex string
    if (isinstance(key, bytes) and (len(key) == 33 or len(key) == 65)):
        return key
    assert False

def check_script(script):
    if (isinstance(script, str)):
        script = hex_str_to_bytes(script)  # Assuming this is hex string
    if (isinstance(script, bytes) or isinstance(script, CScript)):
        return script
    assert False

class TestFrameworkScript(unittest.TestCase):
    def test_base58encodedecode(self):
        def check_base58(data, version):
            self.assertEqual(
                base58_to_byte(byte_to_base58(data, version)),
                (data, version))

        check_base58(
            b'\x1f\x8e\xa1p*{\xd4\x94\x1b\xca\tA\xb8R\xc4\xbb\xfe\xdb.\x05',
            111)
        check_base58(
            b':\x0b\x05\xf4\xd7\xf6l;\xa7\x00\x9fE50)l\x84\\\xc9\xcf', 111)
        check_base58(
            b'A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a',
            111)
        check_base58(
            b'\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a',
            111)
        check_base58(
            b'\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a',
            111)
        check_base58(
            b'\0\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a',
            111)
        check_base58(
            b'\x1f\x8e\xa1p*{\xd4\x94\x1b\xca\tA\xb8R\xc4\xbb\xfe\xdb.\x05', 0)
        check_base58(
            b':\x0b\x05\xf4\xd7\xf6l;\xa7\x00\x9fE50)l\x84\\\xc9\xcf', 0)
        check_base58(
            b'A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0)
        check_base58(
            b'\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0)
        check_base58(
            b'\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0)
        check_base58(
            b'\0\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0)
<commit_msg>[tests] Remove unused optional verify_checksum parameter<commit_after>#!/usr/bin/env python3
# Copyright (c) 2016-2019 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Encode and decode BASE58, P2PKH and P2SH addresses."""

import unittest

from .script import OP_TRUE, CScript, CScriptOp, hash160, hash256
from .util import assert_equal, hex_str_to_bytes

ADDRESS_ECREG_UNSPENDABLE = 'ecregtest:qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqcrl5mqkt'
ADDRESS_ECREG_UNSPENDABLE_DESCRIPTOR = 'addr(ecregtest:qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqcrl5mqkt)#u6xx93xc'
# Coins sent to this address can be spent with a scriptSig of just OP_TRUE
ADDRESS_ECREG_P2SH_OP_TRUE = 'ecregtest:prdpw30fk4ym6zl6rftfjuw806arpn26fvkgfu97xt'
SCRIPTSIG_OP_TRUE = CScriptOp.encode_op_pushdata(CScript([OP_TRUE]))

chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'

def byte_to_base58(b, version):
    result = ''
    str = b.hex()
    str = chr(version).encode('latin-1').hex() + str
    checksum = hash256(hex_str_to_bytes(str)).hex()
    str += checksum[:8]
    value = int('0x' + str, 0)
    while value > 0:
        result = chars[value % 58] + result
        value //= 58
    while (str[:2] == '00'):
        result = chars[0] + result
        str = str[2:]
    return result

def base58_to_byte(s):
    """Converts a base58-encoded string to its data and version.

    Throws if the base58 checksum is invalid."""
    if not s:
        return b''
    n = 0
    for c in s:
        n *= 58
        assert c in chars
        digit = chars.index(c)
        n += digit
    h = '{:x}'.format(n)
    if len(h) % 2:
        h = '0' + h
    res = n.to_bytes((n.bit_length() + 7) // 8, 'big')
    pad = 0
    for c in s:
        if c == chars[0]:
            pad += 1
        else:
            break
    res = b'\x00' * pad + res

    # Assert if the checksum is invalid
    assert_equal(hash256(res[:-4])[:4], res[-4:])

    return res[1:-4], int(res[0])

def keyhash_to_p2pkh(hash, main=False):
    assert (len(hash) == 20)
    version = 0 if main else 111
    return byte_to_base58(hash, version)

def scripthash_to_p2sh(hash, main=False):
    assert (len(hash) == 20)
    version = 5 if main else 196
    return byte_to_base58(hash, version)

def key_to_p2pkh(key, main=False):
    key = check_key(key)
    return keyhash_to_p2pkh(hash160(key), main)

def script_to_p2sh(script, main=False):
    script = check_script(script)
    return scripthash_to_p2sh(hash160(script), main)

def check_key(key):
    if (isinstance(key, str)):
        key = hex_str_to_bytes(key)  # Assuming this is hex string
    if (isinstance(key, bytes) and (len(key) == 33 or len(key) == 65)):
        return key
    assert False

def check_script(script):
    if (isinstance(script, str)):
        script = hex_str_to_bytes(script)  # Assuming this is hex string
    if (isinstance(script, bytes) or isinstance(script, CScript)):
        return script
    assert False

class TestFrameworkScript(unittest.TestCase):
    def test_base58encodedecode(self):
        def check_base58(data, version):
            self.assertEqual(
                base58_to_byte(byte_to_base58(data, version)),
                (data, version))

        check_base58(
            b'\x1f\x8e\xa1p*{\xd4\x94\x1b\xca\tA\xb8R\xc4\xbb\xfe\xdb.\x05',
            111)
        check_base58(
            b':\x0b\x05\xf4\xd7\xf6l;\xa7\x00\x9fE50)l\x84\\\xc9\xcf', 111)
        check_base58(
            b'A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a',
            111)
        check_base58(
            b'\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a',
            111)
        check_base58(
            b'\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a',
            111)
        check_base58(
            b'\0\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a',
            111)
        check_base58(
            b'\x1f\x8e\xa1p*{\xd4\x94\x1b\xca\tA\xb8R\xc4\xbb\xfe\xdb.\x05', 0)
        check_base58(
            b':\x0b\x05\xf4\xd7\xf6l;\xa7\x00\x9fE50)l\x84\\\xc9\xcf', 0)
        check_base58(
            b'A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0)
        check_base58(
            b'\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0)
        check_base58(
            b'\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0)
        check_base58(
            b'\0\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0)
<|endoftext|>


<commit_before>from __future__ import absolute_import, division, print_function
from builtins import str
from copy import deepcopy

from panoptes_client.exportable import Exportable
from panoptes_client.panoptes import PanoptesObject, LinkResolver
from panoptes_client.subject import Subject
from panoptes_client.subject_set import SubjectSet
from panoptes_client.utils import batchable

class Workflow(PanoptesObject, Exportable):
    _api_slug = 'workflows'
    _link_slug = 'workflows'
    _edit_attributes = (
        'active',
        'configuration',
        'display_name',
        'first_task',
        'mobile_friendly',
        'primary_language',
        'retirement',
        'tasks',
        {
            'links': (
                    'project',
            )
        },
    )

    def __init__(self, raw={}, etag=None):
        super(Workflow, self).__init__(raw, etag)
        if not self.configuration:
            self.configuration = {}
            self._original_configuration = {}
        if not self.retirement:
            self.retirement = {}
            self._original_retirement = {}
        if not self.tasks:
            self.tasks = {}
            self._original_tasks = {}

    def set_raw(self, raw, etag=None, loaded=True):
        super(Workflow, self).set_raw(raw, etag, loaded)
        if loaded:
            if self.configuration:
                self._original_configuration = deepcopy(self.configuration)
            if self.retirement:
                self._original_retirement = deepcopy(self.retirement)
            if self.tasks:
                self._original_tasks = deepcopy(self.tasks)
        elif loaded:
            self._original_configuration = None
            self._original_retirement = None
            self._original_tasks = None

    def save(self):
        """
        Adds workflow configuration, retirement, and tasks dicts to the list of
        savable attributes if it has changed.
        """
        if not self.configuration == self._original_configuration:
            self.modified_attributes.add('configuration')
        if not self.retirement == self._original_retirement:
            self.modified_attributes.add('retirement')
        if not self.tasks == self._original_tasks:
            self.modified_attributes.add('tasks')

        super(Workflow, self).save()

    @batchable
    def retire_subjects(self, subjects, reason='other'):
        """
        Retires subjects in this workflow.

        - **subjects** can be a list of :py:class:`Subject` instances, a list
          of subject IDs, a single :py:class:`Subject` instance, or a single
          subject ID.
        - **reason** gives the reason the :py:class:`Subject` has been retired.
          Defaults to **other**.

        Examples::

            workflow.retire_subjects(1234)
            workflow.retire_subjects([1,2,3,4])
            workflow.retire_subjects(Subject(1234))
            workflow.retire_subjects([Subject(12), Subject(34)])
        """

        subjects = [ s.id if isinstance(s, Subject) else s for s in subjects ]

        return Workflow.http_post(
            '{}/retired_subjects'.format(self.id),
            json={
                'subject_ids': subjects,
                'retirement_reason': reason
            },
        )

    @batchable
    def unretire_subjects(self, subjects, subject_sets):
        """
        Un-retires subjects in this workflow.

        - **subjects** can be a list of :py:class:`Subject` instances, a list
          of subject IDs, a single :py:class:`Subject` instance, or a single
          subject ID.

        - **subjects_sets* can be a list of :py:class:`SubjectSet` instances, a list
          of subject_set IDs, a single :py:class:`SubjectSet` instance, or a single
          subject_set ID.
        """

        subjects = [ s.id if isinstance(s, Subject) else s for s in subjects ]
        subject_sets = [ ss.id if isinstance(ss, SubjectSet) else ss for ss in subject_sets ]
        return Workflow.http_post(
            '{}/unretire_subjects'.format(self.id),
            json={
                'subject_ids': subjects,
                'subject_set_ids': subject_sets
            },
        )

    def add_subject_sets(self, subject_sets):
        """
        A wrapper around :py:meth:`.LinkCollection.add`. Equivalent to::

            workflow.links.subject_sets.add(subject_sets)
        """

        return self.links.subject_sets.add(subject_sets)

    def remove_subject_sets(self, subject_sets):
        """
        A wrapper around :py:meth:`.LinkCollection.remove`. Equivalent to::

            workflow.links.subject_sets.remove(subject_sets)
        """

        return self.links.subject_sets.remove(subject_sets)

    @property
    def versions(self):
        """
        A generator which yields all :py:class:`.WorkflowVersion` instances for
        this workflow.
        """

        return WorkflowVersion.where(workflow=self)

LinkResolver.register(Workflow)
LinkResolver.register(Workflow, 'active_workflows', readonly=True)

from panoptes_client.workflow_version import WorkflowVersion
<commit_msg>add default params<commit_after>from __future__ import absolute_import, division, print_function
from builtins import str
from copy import deepcopy

from panoptes_client.exportable import Exportable
from panoptes_client.panoptes import PanoptesObject, LinkResolver
from panoptes_client.subject import Subject
from panoptes_client.subject_set import SubjectSet
from panoptes_client.utils import batchable

class Workflow(PanoptesObject, Exportable):
    _api_slug = 'workflows'
    _link_slug = 'workflows'
    _edit_attributes = (
        'active',
        'configuration',
        'display_name',
        'first_task',
        'mobile_friendly',
        'primary_language',
        'retirement',
        'tasks',
        {
            'links': (
                    'project',
            )
        },
    )

    def __init__(self, raw={}, etag=None):
        super(Workflow, self).__init__(raw, etag)
        if not self.configuration:
            self.configuration = {}
            self._original_configuration = {}
        if not self.retirement:
            self.retirement = {}
            self._original_retirement = {}
        if not self.tasks:
            self.tasks = {}
            self._original_tasks = {}

    def set_raw(self, raw, etag=None, loaded=True):
        super(Workflow, self).set_raw(raw, etag, loaded)
        if loaded:
            if self.configuration:
                self._original_configuration = deepcopy(self.configuration)
            if self.retirement:
                self._original_retirement = deepcopy(self.retirement)
            if self.tasks:
                self._original_tasks = deepcopy(self.tasks)
        elif loaded:
            self._original_configuration = None
            self._original_retirement = None
            self._original_tasks = None

    def save(self):
        """
        Adds workflow configuration, retirement, and tasks dicts to the list of
        savable attributes if it has changed.
        """
        if not self.configuration == self._original_configuration:
            self.modified_attributes.add('configuration')
        if not self.retirement == self._original_retirement:
            self.modified_attributes.add('retirement')
        if not self.tasks == self._original_tasks:
            self.modified_attributes.add('tasks')

        super(Workflow, self).save()

    @batchable
    def retire_subjects(self, subjects, reason='other'):
        """
        Retires subjects in this workflow.

        - **subjects** can be a list of :py:class:`Subject` instances, a list
          of subject IDs, a single :py:class:`Subject` instance, or a single
          subject ID.
        - **reason** gives the reason the :py:class:`Subject` has been retired.
          Defaults to **other**.

        Examples::

            workflow.retire_subjects(1234)
            workflow.retire_subjects([1,2,3,4])
            workflow.retire_subjects(Subject(1234))
            workflow.retire_subjects([Subject(12), Subject(34)])
        """

        subjects = [ s.id if isinstance(s, Subject) else s for s in subjects ]

        return Workflow.http_post(
            '{}/retired_subjects'.format(self.id),
            json={
                'subject_ids': subjects,
                'retirement_reason': reason
            },
        )

    @batchable
    def unretire_subjects(self, subjects=[], subject_sets=[]):
        """
        Un-retires subjects in this workflow.

        - **subjects** can be a list of :py:class:`Subject` instances, a list
          of subject IDs, a single :py:class:`Subject` instance, or a single
          subject ID.

        - **subjects_sets* can be a list of :py:class:`SubjectSet` instances, a list
          of subject_set IDs, a single :py:class:`SubjectSet` instance, or a single
          subject_set ID.
        """

        subjects = [ s.id if isinstance(s, Subject) else s for s in subjects ]
        subject_sets = [ ss.id if isinstance(ss, SubjectSet) else ss for ss in subject_sets ]
        return Workflow.http_post(
            '{}/unretire_subjects'.format(self.id),
            json={
                'subject_ids': subjects,
                'subject_set_ids': subject_sets
            },
        )

    def add_subject_sets(self, subject_sets):
        """
        A wrapper around :py:meth:`.LinkCollection.add`. Equivalent to::

            workflow.links.subject_sets.add(subject_sets)
        """

        return self.links.subject_sets.add(subject_sets)

    def remove_subject_sets(self, subject_sets):
        """
        A wrapper around :py:meth:`.LinkCollection.remove`. Equivalent to::

            workflow.links.subject_sets.remove(subject_sets)
        """

        return self.links.subject_sets.remove(subject_sets)

    @property
    def versions(self):
        """
        A generator which yields all :py:class:`.WorkflowVersion` instances for
        this workflow.
        """

        return WorkflowVersion.where(workflow=self)

LinkResolver.register(Workflow)
LinkResolver.register(Workflow, 'active_workflows', readonly=True)

from panoptes_client.workflow_version import WorkflowVersion
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
from . import core as ac
from . import webui
import os
from .arg_parser import parse_args

def setSeekerData():
    r = [];
    print("设置检查器")
    while True:
        print("选择检查器类型(输入-1结束): ")
        for seeker_index, seeker_name in enumerate(ac.seeker.keys()):
            print("\t", seeker_index, "\t", seeker_name)
        user_selected_seeker_idx = int(input("请选择: "))
        if user_selected_seeker_idx < 0:
            break
        try:
            user_selected_seeker_name = list(ac.seeker.keys())[user_selected_seeker_idx];
        except IndexError:
            print("没有找到指定的检查器，请重试")
            continue
        user_input_chk_key = input("请输入检查关键字: ")
        r_i = { 'seeker': user_selected_seeker_name, 'chk_key': user_input_chk_key }
        r.append(r_i)
    return r;

def main():
    args = parse_args()
    ac.dbInit()

    if args.add:
        nc = ( "ID", "名称", "看到", "上映时间", "检查关键字" )
        nc_key = ("id", "name", "cur_epi", "on_air_day", "chk_key")
        print( "正在添加番组" )
        n = {}
        for i in range(1, 5):
            print( "%s: " % ( nc[i], ) )
            c = str(input())
            if not c=='':
                n[nc_key[i]] = c
            else:
                if i==2 or i==3:
                    n[nc_key[i]] = 0
                else:
                    n[nc_key[i]] = ''
        ac.create( **n )
    elif args.modify:
        nc = ( "ID", "名称", "看到", "上映时间", "检查关键字" )
        nc_key = ("bid", "name", "cur_epi", "on_air_day", "chk_key")
        n = ac.getAni( args.modify )
        t = { 'bid': args.modify }
        if not n:
            print( "错误: 未找到指定番组" )
            exit()
        print( "您正在修改%s的信息" % (n['name'], ) )
        for i in range(1, 5):
            print( "%s: (回车默认 %s )" % (nc[i], str(n[nc_key[i]])) )
            c = str(input())
            if not c=='':
                t[nc_key[i]] = c
        ac.modify( **t )
    elif args.remove:
        n = ac.getAni( args.remove )
        if n:
            print( "确定删除%s吗？(Y/n)" % (n['name'],  ) )
            c = str(input())
            if c=='' or c=='Y' or c=='y':
                ac.remove( args.remove )
                print( "%s 已删除" % n['name']  )
        else:
            print( "错误: 未找到指定番组" )
    elif args.plus:
        n = ac.getAni( args.plus )
        if n:
            print( "确定向%s(%d)加一吗？(Y/n)" % (n['name'], n['cur_epi'] ) )
            c = str(input())
            if c=='' or c=='Y' or c=='y':
                ac.increase( args.plus )
                print( "%s 已加一为 %d" % (n['name'], n['cur_epi']+1 ) )
        else:
            print( "错误: 未找到指定番组" )
    elif args.decrease:
        n = ac.getAni( args.decrease )
        if n:
            print( "确定向%s(%d)减一吗？(Y/n)" % (n['name'], n['cur_epi'] ) )
            c = str(input())
            if c=='' or c=='Y' or c=='y':
                ac.decrease( args.decrease )
                print( "%s 已减一为 %d" % (n['name'], n['cur_epi']-1 ) )
        else:
            print( "错误: 未找到指定番组" )
    elif args.chkup:
        if args.chkup>0:
            n = ac.getAni( args.chkup )
            if n:
                print( "查找 %s 的第 %d 集资源" % (n['name'], n['cur_epi']+1) )
                try:
                    r = ac.chkup(args.chkup)
                    print("%s\n%s"%(r['magname'], r['maglink']))
                    if os.system('echo "%s" | xclip -in -selection clipboard'%r['maglink']) == 0:
                        print("磁力链接已拷贝到剪贴板")
                except NameError:
                    print( "ERR: specified bgm not found." )
                except LookupError:
                    print( "没有找到相关资源" )
        elif args.chkup==-1:
            print( "查找所有资源" )
            n = ac.getAni()
            i = 0
            mls = []
            for row in n:
                try:
                    r = ac.chkup(row['id'])
                except:
                    continue
                    pass
                else:
                    if r:
                        print( "%-3d %s\n有更新: %s\n" % (row['id'], row['name'], r['magname']) )
                        mls.append(r['maglink'])
                        i = i+1
            if not i:
                print( "没有找到有更新的资源" )
            else:
                print( "%d个资源有更新" % i )
                if os.system('echo -e "%s" | xclip -in -selection clipboard'%( '\n'.join(mls), )) == 0:
                    print("磁力链接已拷贝到剪贴板")
    elif args.webui:
        webui.start();
        pass
    else:
        r = ac.getAni( args.show, args.showbyday )
        if args.show>=0:
            print( "%-3d %s\t已看%s/周%s更新" % (r['id'], r['name'], r['cur_epi'], str(r['on_air_day'])) )
        else:
            for row in r:
                print( "%-3d %s\t已看%s/周%s更新" % (row['id'], row['name'], row['cur_epi'], str(row['on_air_day']) ))
<commit_msg>User interaction logic for `create` & `modify` function set. Tommorrow's goal set.<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
from . import core as ac
from . import webui
import os
from .arg_parser import parse_args

def setSeekerData():
    r = [];
    print("设置检查器")
    while True:
        print("选择检查器类型(输入-1结束): ")
        for seeker_index, seeker_name in enumerate(ac.seeker.keys()):
            print("\t", seeker_index, "\t", seeker_name)
        user_selected_seeker_idx = int(input("请选择: "))
        if user_selected_seeker_idx < 0:
            break
        try:
            user_selected_seeker_name = list(ac.seeker.keys())[user_selected_seeker_idx];
        except IndexError:
            print("没有找到指定的检查器，请重试")
            continue
        user_input_chk_key = input("请输入检查关键字: ")
        r_i = { 'seeker': user_selected_seeker_name, 'chk_key': user_input_chk_key }
        r.append(r_i)
    return r;

def main():
    args = parse_args()
    ac.dbInit()

    if args.add:
        nc = ( "ID", "名称", "看到", "上映时间" )
        nc_key = ("id", "name", "cur_epi", "on_air_day")
        print( "正在添加番组" )
        n = {}
        for i in range(1, 4):
            print( "%s: " % ( nc[i], ) )
            c = str(input())
            if not c=='':
                n[nc_key[i]] = c
            else:
                if i==2 or i==3:
                    n[nc_key[i]] = 0
                else:
                    n[nc_key[i]] = ''
        n['seeker'] = setSeekerData()
        ac.create( **n )
    elif args.modify:
        nc = ( "ID", "名称", "看到", "上映时间" )
        nc_key = ("bid", "name", "cur_epi", "on_air_day")
        n = ac.getAni( args.modify )
        t = { 'bid': args.modify }
        if not n:
            print( "错误: 未找到指定番组" )
            exit()
        print( "您正在修改%s的信息" % (n['name'], ) )
        for i in range(1, 4):
            print( "%s: (回车默认 %s )" % (nc[i], str(n[nc_key[i]])) )
            c = str(input())
            if not c=='':
                t[nc_key[i]] = c
        t['seeker'] = setSeekerData()
        ac.modify( **t )
    elif args.remove:
        n = ac.getAni( args.remove )
        if n:
            print( "确定删除%s吗？(Y/n)" % (n['name'],  ) )
            c = str(input())
            if c=='' or c=='Y' or c=='y':
                ac.remove( args.remove )
                print( "%s 已删除" % n['name']  )
        else:
            print( "错误: 未找到指定番组" )
    elif args.plus:
        n = ac.getAni( args.plus )
        if n:
            print( "确定向%s(%d)加一吗？(Y/n)" % (n['name'], n['cur_epi'] ) )
            c = str(input())
            if c=='' or c=='Y' or c=='y':
                ac.increase( args.plus )
                print( "%s 已加一为 %d" % (n['name'], n['cur_epi']+1 ) )
        else:
            print( "错误: 未找到指定番组" )
    elif args.decrease:
        n = ac.getAni( args.decrease )
        if n:
            print( "确定向%s(%d)减一吗？(Y/n)" % (n['name'], n['cur_epi'] ) )
            c = str(input())
            if c=='' or c=='Y' or c=='y':
                ac.decrease( args.decrease )
                print( "%s 已减一为 %d" % (n['name'], n['cur_epi']-1 ) )
        else:
            print( "错误: 未找到指定番组" )
    elif args.chkup:
        # TODO Need to be reconstructured.
        if args.chkup>0:
            n = ac.getAni( args.chkup )
            if n:
                print( "查找 %s 的第 %d 集资源" % (n['name'], n['cur_epi']+1) )
                try:
                    r = ac.chkup(args.chkup)
                    print("%s\n%s"%(r['magname'], r['maglink']))
                    if os.system('echo "%s" | xclip -in -selection clipboard'%r['maglink']) == 0:
                        print("磁力链接已拷贝到剪贴板")
                except NameError:
                    print( "ERR: specified bgm not found." )
                except LookupError:
                    print( "没有找到相关资源" )
        elif args.chkup==-1:
            print( "查找所有资源" )
            n = ac.getAni()
            i = 0
            mls = []
            for row in n:
                try:
                    r = ac.chkup(row['id'])
                except:
                    continue
                    pass
                else:
                    if r:
                        print( "%-3d %s\n有更新: %s\n" % (row['id'], row['name'], r['magname']) )
                        mls.append(r['maglink'])
                        i = i+1
            if not i:
                print( "没有找到有更新的资源" )
            else:
                print( "%d个资源有更新" % i )
                if os.system('echo -e "%s" | xclip -in -selection clipboard'%( '\n'.join(mls), )) == 0:
                    print("磁力链接已拷贝到剪贴板")
    elif args.webui:
        webui.start();
        pass
    else:
        r = ac.getAni( args.show, args.showbyday )
        if args.show>=0:
            print( "%-3d %s\t已看%s/周%s更新" % (r['id'], r['name'], r['cur_epi'], str(r['on_air_day'])) )
        else:
            for row in r:
                print( "%-3d %s\t已看%s/周%s更新" % (row['id'], row['name'], row['cur_epi'], str(row['on_air_day']) ))
<|endoftext|>


<commit_before>from pudzu.charts import *

df = pd.read_csv("datasets/flagstriband.csv")
df = pd.concat([pd.DataFrame(df.colours.apply(list).tolist(), columns=list("TMB")), df], axis=1).set_index("colours")

FONT, SIZE = calibri, 24
fg, bg = "black", "#EEEEEE"
default_img = "https://s-media-cache-ak0.pinimg.com/736x/0d/36/e7/0d36e7a476b06333d9fe9960572b66b9.jpg"
COLORS = { "W": "white", "Y": "yellow", "R": "red", "G": "green", "B": "blue", "K": "black", }
W, H = 320, 200

def label(c, size):
    w, h = size
    label = Image.from_text_bounded(" ", (W,H), SIZE, partial(FONT, bold=True), beard_line=True)
    description = Image.from_text_bounded(" ", (W,H), SIZE, partial(FONT, italics=True), beard_line=True)
    flag = Rectangle((w-2, h-2), RGBA(COLORS.get(c)).blend(bg, 0.1)).pad(1, "grey") # TODO: orange
    return Image.from_column([label, description, flag], padding=2, bg=bg)

def process(d):
    if non(d['name']): return None
    label = Image.from_text_bounded(d['name'].replace("*","").upper(), (W,H), SIZE, partial(FONT, bold=True), beard_line=True)
    description = Image.from_text_bounded(get_non(d, 'description', " "), (W,H), SIZE, partial(FONT, italics=True), beard_line=True)
    flag = Image.from_url_with_cache(get_non(d, 'flag', default_img)).to_rgba()
    flag = flag.resize_fixed_aspect(height=H-2) if flag.width / flag.height < 1.3 else flag.resize((W-2,H-2))
    flag = flag.pad(1, "grey")
    flaglabel = Image.from_column([label, description, flag], padding=2, bg=bg)
    if "*" in d['name']: flaglabel = flaglabel.blend(Rectangle(flaglabel.size, bg), 0.3)
    return flaglabel

def grid(middle):
    ms = df[df.M == middle]
    colors = "".join(COLORS).replace(middle,"")
    array = [[dict(ms.loc[t+middle+b][["name", "description", "flag"]]) for b in colors] for t in colors]
    data = pd.DataFrame(array, index=list(colors), columns=list(colors))
    grid = grid_chart(data, process, padding=(10,20), fg=fg, bg=bg, yalign=1,
                      row_label=lambda row: label(data.index[row], (100, H)), col_label=lambda col: label(data.columns[col], (W,100)), corner_label=label(middle, (100,100)))
    return grid

grids = list(generate_batches([grid(c) for c in COLORS], 3))
grid = Image.from_array(grids, padding=60, bg=bg)

title = Image.from_column([
    Image.from_text_bounded("From Austria to Zanzibar".upper(), grid.size, 360, partial(FONT, bold=True), fg=fg, bg=bg, padding=10),
    Image.from_text_bounded("a color catalog of horizontal tribands".upper(), grid.size, 240, partial(FONT, bold=True), fg=fg, bg=bg, padding=10),
    ], padding=5)
img = Image.from_column([title, grid], bg=bg, padding=(20,0))
img.place(Image.from_text("/u/Udzu", FONT(24), fg=fg, bg=bg, padding=5).pad((1,1,0,0), fg), align=1, padding=5, copy=False)
img.save("output/flagstriband.png")

# Estonian Students' Society (not KBW)
# Club Atlético Nueva Chicago (not KGK)
# Puntland flag proposal (RBK)
<commit_msg>[dataviz] clean up triband viz<commit_after>from pudzu.charts import *

df = pd.read_csv("datasets/flagstriband.csv")
df = pd.concat([pd.DataFrame(df.colours.apply(list).tolist(), columns=list("TMB")), df], axis=1).set_index("colours")

FONT, SIZE = calibri, 24
fg, bg = "black", "#EEEEEE"
default_img = "https://s-media-cache-ak0.pinimg.com/736x/0d/36/e7/0d36e7a476b06333d9fe9960572b66b9.jpg"
COLORS = { "W": "white", "Y": "yellow", "R": "red", "G": "green", "B": "blue", "K": "black", }
W, H = 320, 200

# Estonian Students' Society (not KBW)
# Club Atlético Nueva Chicago (not KGK)
# Puntland flag proposal (RBK)

def label(c, size):
    w, h = size
    label = Image.from_text_bounded(" ", (W,H), SIZE, partial(FONT, bold=True), beard_line=True)
    description = Image.from_text_bounded(" ", (W,H), SIZE, partial(FONT, italics=True), beard_line=True)
    if c == "Y":
        flag = Triangle(max(w,h), "orange", "yellow", p=1.0).crop_to_aspect(w,h).trim(1).pad(1, "grey")
    else:
        flag = Rectangle((w-2, h-2), RGBA(COLORS.get(c)).blend(bg, 0.1)).pad(1, "grey")
    return Image.from_column([label, description, flag], padding=2, bg=bg)

def process(d):
    if non(d['name']): return None
    label = Image.from_text_bounded(d['name'].replace("*","").upper(), (W,H), SIZE, partial(FONT, bold=True), beard_line=True)
    description = Image.from_text_bounded(get_non(d, 'description', " "), (W,H), SIZE, partial(FONT, italics=True), beard_line=True)
    flag = Image.from_url_with_cache(get_non(d, 'flag', default_img)).to_rgba()
    flag = flag.resize_fixed_aspect(height=H-2) if flag.width / flag.height < 1.3 else flag.resize((W-2,H-2))
    flag = flag.pad(1, "grey")
    flaglabel = Image.from_column([label, description, flag], padding=2, bg=bg)
    if "*" in d['name']: flaglabel = flaglabel.blend(Rectangle(flaglabel.size, bg), 0.3)
    return flaglabel

def grid(middle):
    ms = df[df.M == middle]
    colors = "".join(COLORS).replace(middle,"")
    array = [[dict(ms.loc[t+middle+b][["name", "description", "flag"]]) for b in colors] for t in colors]
    data = pd.DataFrame(array, index=list(colors), columns=list(colors))
    grid = grid_chart(data, process, padding=(10,20), fg=fg, bg=bg, yalign=1,
                      row_label=lambda row: label(data.index[row], (100, H)), col_label=lambda col: label(data.columns[col], (W,100)), corner_label=label(middle, (100,100)))
    return grid

PAD = 100

grids = list(generate_batches([grid(c) for c in COLORS], 2))
grid = Image.from_array(grids, padding=(PAD,PAD//2), bg=bg)

title = Image.from_column([
    Image.from_text_bounded("From Austria to Zanzibar".upper(), grid.size, 360, partial(FONT, bold=True), fg=fg, bg=bg, padding=(PAD,20)),
    Image.from_text_bounded("a catalog of horizontal triband flags".upper(), grid.size, 240, partial(FONT, bold=True), fg=fg, bg=bg, padding=(PAD,20)),
    ], padding=0)
img = Image.from_column([title, grid], bg=bg, padding=(20,0)).pad(10, bg)
img.place(Image.from_text("/u/Udzu", FONT(48), fg=fg, bg=bg, padding=10).pad((2,2,0,0), fg), align=1, padding=10, copy=False)
img.save("output/flagstriband.png")
img.resize_fixed_aspect(scale=0.5).save("output/flagstriband2.png")
<|endoftext|>


<commit_before>#!/usr/bin/env python
#
# NAME
#
#        med2image
#
# DESCRIPTION
#
#        'med2image' converts from medical image data files to
#        display-friendly formats (like png and jpg).
#
# HISTORY
#
# 23 February 2015
# o Initial design and coding.
#

# System imports
import     os
import     sys
import     getpass
import     argparse
import     time
import     numpy             as         np
from       random            import     randint

# System dependency imports
import     nibabel           as         nib
import     dicom
import     pylab
import     matplotlib.cm     as         cm

# Project specific imports
import     error
import     message           as msg
from       _common           import     systemMisc     as misc
from       _common._colors   import     Colors

class med2image(object):
    """
        med2image accepts as input certain medical image formatted data
        and converts each (or specified) slice of this data to a graphical
        display format such as png or jpg.

    """

    _dictErr = {
        'inputFileFail'   : {
            'action'        : 'trying to read input file, ',
            'error'         : 'could not access/read file -- does it exist? Do you have permission?',
            'exitCode'      : 10},
        'emailFail'   : {
            'action'        : 'attempting to send notification email, ',
            'error'         : 'sending failed. Perhaps host is not email configured?',
            'exitCode'      : 20},
    }

    def description(self, *args):
        '''
        Get / set internal object description.
        '''
        if len(args):
            self._str_desc = args[0]
        else:
            return self._str_desc

    def log(self): return self._log

    def __init__(self, **kwargs):

        #
        # Object desc block
        #
        self._str_desc                  = ''

        # Directory and filenames
        self._str_workingDir            = ''
        self._str_inputFile             = ''
        self._str_outputFileStem        = ''
        self._str_outputFileType        = ''
        self._str_outputDir             = ''

        self._b_convertAllSlices        = False
        self._str_sliceToConvert        = ''
        self._str_frameToConvert        = ''
        self._sliceToConvert            = -1
        self._frameToConvert            = -1

        self._str_stdout                = ""
        self._str_stderr                = ""
        self._exitCode                  = 0

        # The actual data volume and slice
        # are numpy ndarrays
        self._b_4D                      = False
        self._b_3D                      = False
        self._b_DICOM                   = False
        self._Vnp_4DVol                 = None
        self._Vnp_3DVol                 = None
        self._Mnp_2Dslice               = None
        self._dcm                       = None

        # A logger
        self._log                       = msg.Message()
        self._log.syslog(True)

        # Flags
        self._b_showSlices              = False
        self._b_convertMiddleSlice      = False
        self._b_convertMiddleFrame      = False

        for key, value in kwargs.iteritems():
            if key == "inputFile":          self._str_inputFile         = value
            if key == "outputDir":          self._str_outputDir         = value
            if key == "outputFileStem":     self._str_outputFileStem    = value
            if key == "outputFileType":     self._str_outputFileType    = value
            if key == "sliceToConvert":     self._str_sliceToConvert    = value
            if key == "frameToConvert":     self._str_frameToConvert    = value
            if key == "showSlices":         self._b_showSlices          = value

        if self._str_frameToConvert.lower() == 'm':
            self._b_convertMiddleFrame = True
        elif len(self._str_frameToConvert):
            self._frameToConvert = int(self._str_frameToConvert)

        if self._str_sliceToConvert.lower() == 'm':
            self._b_convertMiddleSlice = True
        elif len(self._str_sliceToConvert):
            self._sliceToConvert = int(self._str_sliceToConvert)

        str_fileName, str_fileExtension  = os.path.splitext(self._str_outputFileStem)
        if len(self._str_outputFileType):
            str_fileExtension            = '.%s' % self._str_outputFileType

        if len(str_fileExtension) and not len(self._str_outputFileType):
            self._str_outputFileType     = str_fileExtension

        if not len(self._str_outputFileType) and not len(str_fileExtension):
            self._str_outputFileType     = '.png'

    def run(self):
        '''
        The main 'engine' of the class.
        '''

    def echo(self, *args):
        self._b_echoCmd         = True
        if len(args):
            self._b_echoCmd     = args[0]

    def echoStdOut(self, *args):
        self._b_echoStdOut      = True
        if len(args):
            self._b_echoStdOut  = args[0]

    def stdout(self):
        return self._str_stdout

    def stderr(self):
        return self._str_stderr

    def exitCode(self):
        return self._exitCode

    def echoStdErr(self, *args):
        self._b_echoStdErr      = True
        if len(args):
            self._b_echoStdErr  = args[0]

    def dontRun(self, *args):
        self._b_runCmd          = False
        if len(args):
            self._b_runCmd      = args[0]

    def workingDir(self, *args):
        if len(args):
            self._str_workingDir = args[0]
        else:
            return self._str_workingDir

    def slice_save(self, astr_outputFile):
        '''
        Processes/saves a single slice.

        ARGS

        o astr_output
        The output filename to save the slice to.

        '''
        self._log('outputfile = %s\n' % astr_outputFile)
        pylab.imsave(astr_outputFile, self._Mnp_2Dslice, cmap = cm.Greys_r)

class med2image_dcm(med2image):
    '''
    Sub class that handles DICOM data.
    '''
    def __init__(self, **kwargs):
        med2image.__init__(self, **kwargs)
        self._dcm = dicom.read_file(self._str_inputFile)
        image = self._dcm.pixel_array
        self._Mnp_2Dslice = image

    def run(self):
        '''
        Runs the DICOM conversion based on internal state.
        '''
        self._log('Converting DICOM image.\n')
        self._log('PatientName:    %s\n' % self._dcm.PatientName)
        self._log('PatientAge:     %s\n' % self._dcm.PatientAge)
        self._log('PatientSex:     %s\n' % self._dcm.PatientSex)
        self._log('PatientID:      %s\n' % self._dcm.PatientID)
        misc.mkdir(self._str_outputDir)
        str_outputFile = '%s/%s.%s' % (self._str_outputDir,
                                       self._str_outputFileStem,
                                       self._str_outputFileType)
        self.slice_save(str_outputFile)

class med2image_nii(med2image):
    '''
    Sub class that handles NIfTI data.
    '''

    def __init__(self, **kwargs):
        med2image.__init__(self, **kwargs)
        nimg = nib.load(self._str_inputFile)
        data = nimg.get_data()
        if data.ndim == 4:
            self._Vnp_4DVol     = data
            self._b_4D          = True
        if data.ndim == 3:
            self._Vnp_3DVol     = data
            self._b_3D          = True

    def run(self):
        '''
        Runs the NIfTI conversion based on internal state.
        '''

        self._log('About to perform NifTI to %s conversion...\n' %
                  self._str_outputFileType)

        frames     = 1
        frameStart = 0
        frameEnd   = 0

        sliceStart = 0
        sliceEnd   = 0

        if self._b_4D:
            self._log('4D volume detected.\n')
            frames = self._Vnp_4DVol.shape[3]
        if self._b_3D:
            self._log('3D volume detected.\n')

        if self._b_convertMiddleFrame:
            self._frameToConvert = int(frames/2)

        if self._frameToConvert == -1:
            frameEnd    = frames
        else:
            frameStart  = self._frameToConvert
            frameEnd    = self._frameToConvert + 1

        for f in range(frameStart, frameEnd):
            if self._b_4D:
                self._Vnp_3DVol = self._Vnp_4DVol[:,:,:,f]
            slices     = self._Vnp_3DVol.shape[2]
            if self._b_convertMiddleSlice:
                self._sliceToConvert = int(slices/2)

            if self._sliceToConvert == -1:
                sliceEnd    = self._Vnp_3DVol.shape[2]
            else:
                sliceStart  = self._sliceToConvert
                sliceEnd    = self._sliceToConvert + 1

            misc.mkdir(self._str_outputDir)
            for i in range(sliceStart, sliceEnd):
                imslice                 = self._Vnp_3DVol[:,:,i]
                # rotate the slice by 90 for conventional display
                self._Mnp_2Dslice       = np.rot90(imslice)

                if self._b_4D:
                    str_outputFile = '%s/%s-frame%03d-slice%03d.%s' % (
                                                            self._str_outputDir,
                                                            self._str_outputFileStem,
                                                            f, i,
                                                            self._str_outputFileType)
                else:
                    str_outputFile = '%s/%s-slice%03d.%s' % (self._str_outputDir,
                                                            self._str_outputFileStem,
                                                            i,
                                                            self._str_outputFileType)
                self.slice_save(str_outputFile)

def synopsis(ab_shortOnly = False):
    scriptName = os.path.basename(sys.argv[0])
    shortSynopsis =  '''
    SYNOPSIS

            %s                                   \\
                     -i|--input <inputFile>                \\
                    [-d|--outputDir <outputDir>]           \\
                     -o|--output <outputFileStem>          \\
                    [-t|--outputFileType <outputFileType>] \\
                    [-s|--sliceToConvert <sliceToConvert>] \\
                    [-f|--frameToConvert <frameToConvert>] \\
                    [--showSlices]                         \\
                    [--man|--synopsis]
    ''' % scriptName

    description =  '''
    DESCRIPTION

        `%s' converts input medical image formatted data to a more
        display friendly format.

        Currently understands nifti and dicom.

    ARGS

        -i|--inputFile <inputFile>
        Input file to convert. Typically a DICOM file or a nifti volume.

        [-d|--outputDir <outputDir>]
        The directory to contain the converted output image files.

        -o|--outputFileStem <outputFileStem>
        The output file stem to store conversion. If this is specified
        with an extension, this extension will be used to specify the
        output file type.

        [-t|--outputFileType <outputFileType>]
        The output file type. If different to <outputFileStem> extension,
        will override extension in favour of <outputFileType>.

        [-s|--sliceToConvert <sliceToConvert>]
        In the case of volume files, the slice (z) index to convert. Ignored
        for 2D input data. If a '-1' is sent, then convert *all* the slices.
        If an 'm' is specified, only convert the middle slice in an input
        volume.

        [-f|--frameToConvert <sliceToConvert>]
        In the case of 4D volume files, the volume (V) containing the
        slice (z) index to convert. Ignored for 3D input data. If a '-1' is
        sent, then convert *all* the frames. If an 'm' is specified, only
        convert the middle frame in the 4D input stack.

        [--showSlices]
        If specified, render/show image slices as they are created.

        [--man|--synopsis]
        Show either full help or short synopsis.

    EXAMPLES

    NIfTI

    o Convert each slice in a NIfTI volume to a jpg in a sub dir called
      'out' and start the name each converted file with 'vol', do

    med2image.py -i input.nii -d out -o vol --outputFileType jpg --sliceToConvert -1

    o Convert only the middle slice in an input volume

    med2image.py -i input.nii -d out -o vol --outputFileType jpg --sliceToConvert m

    o Convert a specific slice, i.e. slice 20

    med2image.py -i input.nii -d out -o vol --outputFileType jpg --sliceToConvert 20

    DICOM

    o Convert a DICOM file called slice.dcm

    med2image.py -i slice.dcm -d out -o slice --outputFileType jpg

    o Convert all DICOM in a directory/series

    for F in *dcm ; do med2image.py -i $F -d out -o $F --outputFileType jpg ; done

    GITHUB

        o See https://github.com/FNNDSC/med2image for more help and source.

    ''' % (scriptName)
    if ab_shortOnly:
        return shortSynopsis
    else:
        return shortSynopsis + description

if __name__ == '__main__':

    parser = argparse.ArgumentParser(description="med2view converts an input medical image file to a more conventional graphical format.")
    parser.add_argument("-i", "--inputFile",
                        help="input file",
                        dest='inputFile')
    parser.add_argument("-o", "--outputFileStem",
                        help="output file",
                        dest='outputFileStem')
    parser.add_argument("-d", "--outputDir",
                        help="output image directory",
                        dest='outputDir',
                        default='.')
    parser.add_argument("-t", "--outputFileType",
                        help="output image type",
                        dest='outputFileType',
                        default='')
    parser.add_argument("-s", "--sliceToConvert",
                        help="slice to convert (for 3D data)",
                        dest='sliceToConvert',
                        default='-1')
    parser.add_argument("-f", "--frameToConvert",
                        help="frame to convert (for 4D data)",
                        dest='frameToConvert',
                        default='-1')
    parser.add_argument("--printElapsedTime",
                        help="print program run time",
                        dest='printElapsedTime',
                        action='store_true',
                        default=False)
    parser.add_argument('--showSlices',
                        help="show slices that are converted",
                        dest='showSlices',
                        action='store_true',
                        default='False')
    parser.add_argument("--man",
                        help="man",
                        dest='man',
                        action='store_true',
                        default=False)
    parser.add_argument("--synopsis",
                        help="short synopsis",
                        dest='synopsis',
                        action='store_true',
                        default=False)
    args = parser.parse_args()

    if args.man or args.synopsis:
        if args.man:
            str_help     = synopsis(False)
        else:
            str_help     = synopsis(True)
        print(str_help)
        sys.exit(1)

    str_outputFileStem, str_outputFileExtension     = os.path.splitext(args.outputFileStem)
    if len(str_outputFileExtension):
        str_outputFileExtension = str_outputFileExtension.split('.')[1]
    str_inputFileStem,  str_inputFileExtension      = os.path.splitext(args.inputFile)

    if not len(args.outputFileType) and len(str_outputFileExtension):
        args.outputFileType = str_outputFileExtension

    if len(str_outputFileExtension):
        args.outputFileStem = str_outputFileStem

    b_niftiExt           = (str_inputFileExtension   == '.nii'    or \
                            str_inputFileExtension   == '.gz')
    b_dicomExt           =  str_inputFileExtension   == '.dcm'
    if b_niftiExt:
        C_convert     = med2image_nii(
                                inputFile         = args.inputFile,
                                outputDir         = args.outputDir,
                                outputFileStem    = args.outputFileStem,
                                outputFileType    = args.outputFileType,
                                sliceToConvert    = args.sliceToConvert,
                                frameToConvert    = args.frameToConvert,
                                showSlices        = args.showSlices
                            )

    if b_dicomExt:
        C_convert   = med2image_dcm(
                                inputFile         = args.inputFile,
                                outputDir         = args.outputDir,
                                outputFileStem    = args.outputFileStem,
                                outputFileType    = args.outputFileType,
                             )

    # And now run it!
    misc.tic()
    C_convert.run()
    if args.printElapsedTime: print("Elapsed time = %f seconds" % misc.toc())
    sys.exit(0)

<commit_msg>Improve help examples.<commit_after>#!/usr/bin/env python
#
# NAME
#
#        med2image
#
# DESCRIPTION
#
#        'med2image' converts from medical image data files to
#        display-friendly formats (like png and jpg).
#
# HISTORY
#
# 23 February 2015
# o Initial design and coding.
#

# System imports
import     os
import     sys
import     getpass
import     argparse
import     time
import     numpy             as         np
from       random            import     randint

# System dependency imports
import     nibabel           as         nib
import     dicom
import     pylab
import     matplotlib.cm     as         cm

# Project specific imports
import     error
import     message           as msg
from       _common           import     systemMisc     as misc
from       _common._colors   import     Colors

class med2image(object):
    """
        med2image accepts as input certain medical image formatted data
        and converts each (or specified) slice of this data to a graphical
        display format such as png or jpg.

    """

    _dictErr = {
        'inputFileFail'   : {
            'action'        : 'trying to read input file, ',
            'error'         : 'could not access/read file -- does it exist? Do you have permission?',
            'exitCode'      : 10},
        'emailFail'   : {
            'action'        : 'attempting to send notification email, ',
            'error'         : 'sending failed. Perhaps host is not email configured?',
            'exitCode'      : 20},
    }

    def description(self, *args):
        '''
        Get / set internal object description.
        '''
        if len(args):
            self._str_desc = args[0]
        else:
            return self._str_desc

    def log(self): return self._log

    def __init__(self, **kwargs):

        #
        # Object desc block
        #
        self._str_desc                  = ''

        # Directory and filenames
        self._str_workingDir            = ''
        self._str_inputFile             = ''
        self._str_outputFileStem        = ''
        self._str_outputFileType        = ''
        self._str_outputDir             = ''

        self._b_convertAllSlices        = False
        self._str_sliceToConvert        = ''
        self._str_frameToConvert        = ''
        self._sliceToConvert            = -1
        self._frameToConvert            = -1

        self._str_stdout                = ""
        self._str_stderr                = ""
        self._exitCode                  = 0

        # The actual data volume and slice
        # are numpy ndarrays
        self._b_4D                      = False
        self._b_3D                      = False
        self._b_DICOM                   = False
        self._Vnp_4DVol                 = None
        self._Vnp_3DVol                 = None
        self._Mnp_2Dslice               = None
        self._dcm                       = None

        # A logger
        self._log                       = msg.Message()
        self._log.syslog(True)

        # Flags
        self._b_showSlices              = False
        self._b_convertMiddleSlice      = False
        self._b_convertMiddleFrame      = False

        for key, value in kwargs.iteritems():
            if key == "inputFile":          self._str_inputFile         = value
            if key == "outputDir":          self._str_outputDir         = value
            if key == "outputFileStem":     self._str_outputFileStem    = value
            if key == "outputFileType":     self._str_outputFileType    = value
            if key == "sliceToConvert":     self._str_sliceToConvert    = value
            if key == "frameToConvert":     self._str_frameToConvert    = value
            if key == "showSlices":         self._b_showSlices          = value

        if self._str_frameToConvert.lower() == 'm':
            self._b_convertMiddleFrame = True
        elif len(self._str_frameToConvert):
            self._frameToConvert = int(self._str_frameToConvert)

        if self._str_sliceToConvert.lower() == 'm':
            self._b_convertMiddleSlice = True
        elif len(self._str_sliceToConvert):
            self._sliceToConvert = int(self._str_sliceToConvert)

        str_fileName, str_fileExtension  = os.path.splitext(self._str_outputFileStem)
        if len(self._str_outputFileType):
            str_fileExtension            = '.%s' % self._str_outputFileType

        if len(str_fileExtension) and not len(self._str_outputFileType):
            self._str_outputFileType     = str_fileExtension

        if not len(self._str_outputFileType) and not len(str_fileExtension):
            self._str_outputFileType     = '.png'

    def run(self):
        '''
        The main 'engine' of the class.
        '''

    def echo(self, *args):
        self._b_echoCmd         = True
        if len(args):
            self._b_echoCmd     = args[0]

    def echoStdOut(self, *args):
        self._b_echoStdOut      = True
        if len(args):
            self._b_echoStdOut  = args[0]

    def stdout(self):
        return self._str_stdout

    def stderr(self):
        return self._str_stderr

    def exitCode(self):
        return self._exitCode

    def echoStdErr(self, *args):
        self._b_echoStdErr      = True
        if len(args):
            self._b_echoStdErr  = args[0]

    def dontRun(self, *args):
        self._b_runCmd          = False
        if len(args):
            self._b_runCmd      = args[0]

    def workingDir(self, *args):
        if len(args):
            self._str_workingDir = args[0]
        else:
            return self._str_workingDir

    def slice_save(self, astr_outputFile):
        '''
        Processes/saves a single slice.

        ARGS

        o astr_output
        The output filename to save the slice to.

        '''
        self._log('outputfile = %s\n' % astr_outputFile)
        pylab.imsave(astr_outputFile, self._Mnp_2Dslice, cmap = cm.Greys_r)

class med2image_dcm(med2image):
    '''
    Sub class that handles DICOM data.
    '''
    def __init__(self, **kwargs):
        med2image.__init__(self, **kwargs)
        self._dcm = dicom.read_file(self._str_inputFile)
        image = self._dcm.pixel_array
        self._Mnp_2Dslice = image

    def run(self):
        '''
        Runs the DICOM conversion based on internal state.
        '''
        self._log('Converting DICOM image.\n')
        self._log('PatientName:    %s\n' % self._dcm.PatientName)
        self._log('PatientAge:     %s\n' % self._dcm.PatientAge)
        self._log('PatientSex:     %s\n' % self._dcm.PatientSex)
        self._log('PatientID:      %s\n' % self._dcm.PatientID)
        misc.mkdir(self._str_outputDir)
        str_outputFile = '%s/%s.%s' % (self._str_outputDir,
                                       self._str_outputFileStem,
                                       self._str_outputFileType)
        self.slice_save(str_outputFile)

class med2image_nii(med2image):
    '''
    Sub class that handles NIfTI data.
    '''

    def __init__(self, **kwargs):
        med2image.__init__(self, **kwargs)
        nimg = nib.load(self._str_inputFile)
        data = nimg.get_data()
        if data.ndim == 4:
            self._Vnp_4DVol     = data
            self._b_4D          = True
        if data.ndim == 3:
            self._Vnp_3DVol     = data
            self._b_3D          = True

    def run(self):
        '''
        Runs the NIfTI conversion based on internal state.
        '''

        self._log('About to perform NifTI to %s conversion...\n' %
                  self._str_outputFileType)

        frames     = 1
        frameStart = 0
        frameEnd   = 0

        sliceStart = 0
        sliceEnd   = 0

        if self._b_4D:
            self._log('4D volume detected.\n')
            frames = self._Vnp_4DVol.shape[3]
        if self._b_3D:
            self._log('3D volume detected.\n')

        if self._b_convertMiddleFrame:
            self._frameToConvert = int(frames/2)

        if self._frameToConvert == -1:
            frameEnd    = frames
        else:
            frameStart  = self._frameToConvert
            frameEnd    = self._frameToConvert + 1

        for f in range(frameStart, frameEnd):
            if self._b_4D:
                self._Vnp_3DVol = self._Vnp_4DVol[:,:,:,f]
            slices     = self._Vnp_3DVol.shape[2]
            if self._b_convertMiddleSlice:
                self._sliceToConvert = int(slices/2)

            if self._sliceToConvert == -1:
                sliceEnd    = self._Vnp_3DVol.shape[2]
            else:
                sliceStart  = self._sliceToConvert
                sliceEnd    = self._sliceToConvert + 1

            misc.mkdir(self._str_outputDir)
            for i in range(sliceStart, sliceEnd):
                imslice                 = self._Vnp_3DVol[:,:,i]
                # rotate the slice by 90 for conventional display
                self._Mnp_2Dslice       = np.rot90(imslice)

                if self._b_4D:
                    str_outputFile = '%s/%s-frame%03d-slice%03d.%s' % (
                                                            self._str_outputDir,
                                                            self._str_outputFileStem,
                                                            f, i,
                                                            self._str_outputFileType)
                else:
                    str_outputFile = '%s/%s-slice%03d.%s' % (self._str_outputDir,
                                                            self._str_outputFileStem,
                                                            i,
                                                            self._str_outputFileType)
                self.slice_save(str_outputFile)

def synopsis(ab_shortOnly = False):
    scriptName = os.path.basename(sys.argv[0])
    shortSynopsis =  '''
    SYNOPSIS

            %s                                   \\
                     -i|--input <inputFile>                \\
                    [-d|--outputDir <outputDir>]           \\
                     -o|--output <outputFileStem>          \\
                    [-t|--outputFileType <outputFileType>] \\
                    [-s|--sliceToConvert <sliceToConvert>] \\
                    [-f|--frameToConvert <frameToConvert>] \\
                    [--showSlices]                         \\
                    [--man|--synopsis]
    ''' % scriptName

    description =  '''
    DESCRIPTION

        `%s' converts input medical image formatted data to a more
        display friendly format.

        Currently understands nifti and dicom.

    ARGS

        -i|--inputFile <inputFile>
        Input file to convert. Typically a DICOM file or a nifti volume.

        [-d|--outputDir <outputDir>]
        The directory to contain the converted output image files.

        -o|--outputFileStem <outputFileStem>
        The output file stem to store conversion. If this is specified
        with an extension, this extension will be used to specify the
        output file type.

        [-t|--outputFileType <outputFileType>]
        The output file type. If different to <outputFileStem> extension,
        will override extension in favour of <outputFileType>.

        [-s|--sliceToConvert <sliceToConvert>]
        In the case of volume files, the slice (z) index to convert. Ignored
        for 2D input data. If a '-1' is sent, then convert *all* the slices.
        If an 'm' is specified, only convert the middle slice in an input
        volume.

        [-f|--frameToConvert <sliceToConvert>]
        In the case of 4D volume files, the volume (V) containing the
        slice (z) index to convert. Ignored for 3D input data. If a '-1' is
        sent, then convert *all* the frames. If an 'm' is specified, only
        convert the middle frame in the 4D input stack.

        [--showSlices]
        If specified, render/show image slices as they are created.

        [--man|--synopsis]
        Show either full help or short synopsis.

    EXAMPLES

    NIfTI

    o Convert each slice in a NIfTI volume 'vol.nii' to a jpg called
      'image-sliceXXX.jpg' and store results in a directory called 'out':

    		med2image.py -i vol.nii -d out -o image.jpg -s -1

    o Convert only the middle slice in an input volume and store in current
      directory:

    		med2image.py -i vol.nii -o image.jpg -s m

    o Convert a specific slice, i.e. slice 20

    		med2image.py -i vol.nii -o image.jpg -s 20

    DICOM

    o Simply convert a DICOM file called 'slice.dcm' to a jpg called 'slice.jpg':

    		med2image.py -i slice.dcm -o slice.jpg

    o Convert all DICOM in a directory/series

    		for F in *dcm ; do med2image.py -i $F -o ${F}.jpg ; done

    GITHUB

        o See https://github.com/FNNDSC/med2image for more help and source.

    ''' % (scriptName)
    if ab_shortOnly:
        return shortSynopsis
    else:
        return shortSynopsis + description

if __name__ == '__main__':

    parser = argparse.ArgumentParser(description="med2view converts an input medical image file to a more conventional graphical format.")
    parser.add_argument("-i", "--inputFile",
                        help="input file",
                        dest='inputFile')
    parser.add_argument("-o", "--outputFileStem",
                        help="output file",
                        dest='outputFileStem')
    parser.add_argument("-d", "--outputDir",
                        help="output image directory",
                        dest='outputDir',
                        default='.')
    parser.add_argument("-t", "--outputFileType",
                        help="output image type",
                        dest='outputFileType',
                        default='')
    parser.add_argument("-s", "--sliceToConvert",
                        help="slice to convert (for 3D data)",
                        dest='sliceToConvert',
                        default='-1')
    parser.add_argument("-f", "--frameToConvert",
                        help="frame to convert (for 4D data)",
                        dest='frameToConvert',
                        default='-1')
    parser.add_argument("--printElapsedTime",
                        help="print program run time",
                        dest='printElapsedTime',
                        action='store_true',
                        default=False)
    parser.add_argument('--showSlices',
                        help="show slices that are converted",
                        dest='showSlices',
                        action='store_true',
                        default='False')
    parser.add_argument("--man",
                        help="man",
                        dest='man',
                        action='store_true',
                        default=False)
    parser.add_argument("--synopsis",
                        help="short synopsis",
                        dest='synopsis',
                        action='store_true',
                        default=False)
    args = parser.parse_args()

    if args.man or args.synopsis:
        if args.man:
            str_help     = synopsis(False)
        else:
            str_help     = synopsis(True)
        print(str_help)
        sys.exit(1)

    str_outputFileStem, str_outputFileExtension     = os.path.splitext(args.outputFileStem)
    if len(str_outputFileExtension):
        str_outputFileExtension = str_outputFileExtension.split('.')[1]
    str_inputFileStem,  str_inputFileExtension      = os.path.splitext(args.inputFile)

    if not len(args.outputFileType) and len(str_outputFileExtension):
        args.outputFileType = str_outputFileExtension

    if len(str_outputFileExtension):
        args.outputFileStem = str_outputFileStem

    b_niftiExt           = (str_inputFileExtension   == '.nii'    or \
                            str_inputFileExtension   == '.gz')
    b_dicomExt           =  str_inputFileExtension   == '.dcm'
    if b_niftiExt:
        C_convert     = med2image_nii(
                                inputFile         = args.inputFile,
                                outputDir         = args.outputDir,
                                outputFileStem    = args.outputFileStem,
                                outputFileType    = args.outputFileType,
                                sliceToConvert    = args.sliceToConvert,
                                frameToConvert    = args.frameToConvert,
                                showSlices        = args.showSlices
                            )

    if b_dicomExt:
        C_convert   = med2image_dcm(
                                inputFile         = args.inputFile,
                                outputDir         = args.outputDir,
                                outputFileStem    = args.outputFileStem,
                                outputFileType    = args.outputFileType,
                             )

    # And now run it!
    misc.tic()
    C_convert.run()
    if args.printElapsedTime: print("Elapsed time = %f seconds" % misc.toc())
    sys.exit(0)

<|endoftext|>