<commit_before># Copyright (c) 2009 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

{
  'variables': {
    'chromium_code': 1,
    # Mac NOTE: at the start of the conditions block we default some vars
    # that control features based on the branding, this way each place that
    # needs to know about the feature isn't hard coded to the branding type.
  },
  'includes': [
    '../build/common.gypi',
  ],
  'target_defaults': {
    'sources/': [
      ['exclude', '/(cocoa|gtk|win)/'],
      ['exclude', '_(cocoa|gtk|linux|mac|posix|skia|win|x)\\.(cc|mm?)$'],
      ['exclude', '/(gtk|win|x11)_[^/]*\\.cc$'],
    ],
    'conditions': [
      ['OS=="linux"', {'sources/': [
        ['include', '/gtk/'],
        ['include', '_(gtk|linux|posix|skia|x)\\.cc$'],
        ['include', '/(gtk|x11)_[^/]*\\.cc$'],
      ]}],
      ['OS=="mac"', {'sources/': [
        ['include', '/cocoa/'],
        ['include', '_(cocoa|mac|posix)\\.(cc|mm?)$'],
      ]}, { # else: OS != "mac"
        'sources/': [
          ['exclude', '\\.mm?$'],
        ],
      }],
      ['OS=="win"', {'sources/': [
        ['include', '_(win)\\.cc$'],
        ['include', '/win/'],
        ['include', '/win_[^/]*\\.cc$'],
      ]}],
    ],
  },
  'targets': [
    {
      'target_name': 'app_base',
      'type': '<(library)',
      'msvs_guid': '4631946D-7D5F-44BD-A5A8-504C0A7033BE',
      'dependencies': [
        '../base/base.gyp:base',
        '../base/base.gyp:base_gfx',
        '../net/net.gyp:net',
        '../skia/skia.gyp:skia',
        '../third_party/icu38/icu38.gyp:icui18n',
        '../third_party/icu38/icu38.gyp:icuuc',
      ],
      'include_dirs': [
        '..',
        '../chrome/third_party/wtl/include',
      ],
      'sources': [
        # All .cc, .h, and .mm files under app/ except for tests.
        'animation.cc',
        'animation.h',
        'app_paths.h',
        'app_paths.cc',
        'app_switches.h',
        'app_switches.cc',
        'drag_drop_types.cc',
        'drag_drop_types.h',
        'gfx/canvas.cc',
        'gfx/canvas.h',
        'gfx/canvas_linux.cc',
        'gfx/canvas_win.cc',
        'gfx/font.h',
        'gfx/font_gtk.cc',
        'gfx/font_mac.mm',
        'gfx/font_skia.cc',
        'gfx/font_win.cc',
        'gfx/color_utils.cc',
        'gfx/color_utils.h',
        'gfx/favicon_size.h',
        'gfx/gtk_util.cc',
        'gfx/gtk_util.h',
        'gfx/icon_util.cc',
        'gfx/icon_util.h',
        'gfx/insets.h',
        'gfx/path_gtk.cc',
        'gfx/path_win.cc',
        'gfx/path.h',
        'gfx/text_elider.cc',
        'gfx/text_elider.h',
        'l10n_util.cc',
        'l10n_util.h',
        'l10n_util_posix.cc',
        'l10n_util_win.cc',
        'l10n_util_win.h',
        'message_box_flags.h',
        'os_exchange_data_win.cc',
        'os_exchange_data_gtk.cc',
        'os_exchange_data.h',
        'resource_bundle.cc',
        'resource_bundle.h',
        'resource_bundle_win.cc',
        'resource_bundle_linux.cc',
        'resource_bundle_mac.mm',
        'slide_animation.cc',
        'slide_animation.h',
        'theme_provider.h',
        'throb_animation.cc',
        'throb_animation.h',
      ],
      'direct_dependent_settings': {
        'include_dirs': [
          '..',
        ],
      },
      'conditions': [
        ['OS=="linux"', {
          'dependencies': [
            # font_gtk.cc uses fontconfig.
            # TODO(evanm): I think this is wrong; it should just use GTK.
            '../build/linux/system.gyp:fontconfig',
            '../build/linux/system.gyp:gtk',
          ],
        }],
        ['OS=="win"', {
          # TODO: remove this when chrome_resources/chrome_strings are
          #       generated by GYP.
          # The legacy vcproj we rely on places the grit output in this
          # directory, so we need to explicitly add it to our include path.
          'include_dirs': [
            '<(PRODUCT_DIR)/grit_derived_sources',
          ],
          'sources': [
            'win_util.cc',
            'win_util.h',
          ],
        }],
        ['OS!="win"', {
          'sources!': [
            'drag_drop_types.cc',
            'drag_drop_types.h',
            'gfx/icon_util.cc',
            'gfx/icon_util.h',
            'os_exchange_data.cc',
          ],
          # TODO: Move these dependencies to platform-neutral once these
          # projects are generated by GYP.
          'dependencies': [
            '../chrome/chrome.gyp:chrome_resources',
            '../chrome/chrome.gyp:chrome_strings',
          ],
          'conditions': [
            ['toolkit_views==0', {
              # Note: because of gyp predence rules this has to be defined as
              # 'sources/' rather than 'sources!'.
              'sources/': [
                ['exclude', '^os_exchange_data_gtk.cc'],
                ['exclude', '^os_exchange_data.h'],
              ],
            }],
          ],
        }],
      ],
    },
  ],
}
<commit_msg>forgot to remove this comment<commit_after># Copyright (c) 2009 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

{
  'variables': {
    'chromium_code': 1,
  },
  'includes': [
    '../build/common.gypi',
  ],
  'target_defaults': {
    'sources/': [
      ['exclude', '/(cocoa|gtk|win)/'],
      ['exclude', '_(cocoa|gtk|linux|mac|posix|skia|win|x)\\.(cc|mm?)$'],
      ['exclude', '/(gtk|win|x11)_[^/]*\\.cc$'],
    ],
    'conditions': [
      ['OS=="linux"', {'sources/': [
        ['include', '/gtk/'],
        ['include', '_(gtk|linux|posix|skia|x)\\.cc$'],
        ['include', '/(gtk|x11)_[^/]*\\.cc$'],
      ]}],
      ['OS=="mac"', {'sources/': [
        ['include', '/cocoa/'],
        ['include', '_(cocoa|mac|posix)\\.(cc|mm?)$'],
      ]}, { # else: OS != "mac"
        'sources/': [
          ['exclude', '\\.mm?$'],
        ],
      }],
      ['OS=="win"', {'sources/': [
        ['include', '_(win)\\.cc$'],
        ['include', '/win/'],
        ['include', '/win_[^/]*\\.cc$'],
      ]}],
    ],
  },
  'targets': [
    {
      'target_name': 'app_base',
      'type': '<(library)',
      'msvs_guid': '4631946D-7D5F-44BD-A5A8-504C0A7033BE',
      'dependencies': [
        '../base/base.gyp:base',
        '../base/base.gyp:base_gfx',
        '../net/net.gyp:net',
        '../skia/skia.gyp:skia',
        '../third_party/icu38/icu38.gyp:icui18n',
        '../third_party/icu38/icu38.gyp:icuuc',
      ],
      'include_dirs': [
        '..',
        '../chrome/third_party/wtl/include',
      ],
      'sources': [
        # All .cc, .h, and .mm files under app/ except for tests.
        'animation.cc',
        'animation.h',
        'app_paths.h',
        'app_paths.cc',
        'app_switches.h',
        'app_switches.cc',
        'drag_drop_types.cc',
        'drag_drop_types.h',
        'gfx/canvas.cc',
        'gfx/canvas.h',
        'gfx/canvas_linux.cc',
        'gfx/canvas_win.cc',
        'gfx/font.h',
        'gfx/font_gtk.cc',
        'gfx/font_mac.mm',
        'gfx/font_skia.cc',
        'gfx/font_win.cc',
        'gfx/color_utils.cc',
        'gfx/color_utils.h',
        'gfx/favicon_size.h',
        'gfx/gtk_util.cc',
        'gfx/gtk_util.h',
        'gfx/icon_util.cc',
        'gfx/icon_util.h',
        'gfx/insets.h',
        'gfx/path_gtk.cc',
        'gfx/path_win.cc',
        'gfx/path.h',
        'gfx/text_elider.cc',
        'gfx/text_elider.h',
        'l10n_util.cc',
        'l10n_util.h',
        'l10n_util_posix.cc',
        'l10n_util_win.cc',
        'l10n_util_win.h',
        'message_box_flags.h',
        'os_exchange_data_win.cc',
        'os_exchange_data_gtk.cc',
        'os_exchange_data.h',
        'resource_bundle.cc',
        'resource_bundle.h',
        'resource_bundle_win.cc',
        'resource_bundle_linux.cc',
        'resource_bundle_mac.mm',
        'slide_animation.cc',
        'slide_animation.h',
        'theme_provider.h',
        'throb_animation.cc',
        'throb_animation.h',
      ],
      'direct_dependent_settings': {
        'include_dirs': [
          '..',
        ],
      },
      'conditions': [
        ['OS=="linux"', {
          'dependencies': [
            # font_gtk.cc uses fontconfig.
            # TODO(evanm): I think this is wrong; it should just use GTK.
            '../build/linux/system.gyp:fontconfig',
            '../build/linux/system.gyp:gtk',
          ],
        }],
        ['OS=="win"', {
          # TODO: remove this when chrome_resources/chrome_strings are
          #       generated by GYP.
          # The legacy vcproj we rely on places the grit output in this
          # directory, so we need to explicitly add it to our include path.
          'include_dirs': [
            '<(PRODUCT_DIR)/grit_derived_sources',
          ],
          'sources': [
            'win_util.cc',
            'win_util.h',
          ],
        }],
        ['OS!="win"', {
          'sources!': [
            'drag_drop_types.cc',
            'drag_drop_types.h',
            'gfx/icon_util.cc',
            'gfx/icon_util.h',
            'os_exchange_data.cc',
          ],
          # TODO: Move these dependencies to platform-neutral once these
          # projects are generated by GYP.
          'dependencies': [
            '../chrome/chrome.gyp:chrome_resources',
            '../chrome/chrome.gyp:chrome_strings',
          ],
          'conditions': [
            ['toolkit_views==0', {
              # Note: because of gyp predence rules this has to be defined as
              # 'sources/' rather than 'sources!'.
              'sources/': [
                ['exclude', '^os_exchange_data_gtk.cc'],
                ['exclude', '^os_exchange_data.h'],
              ],
            }],
          ],
        }],
      ],
    },
  ],
}
<|endoftext|>


<commit_before>#!/usr/bin/env python3
#
# Copyright (C) 2021 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import unittest
import json

from base_vyostest_shim import VyOSUnitTestSHIM

from vyos.configsession import ConfigSessionError
from vyos.util import cmd
from vyos.util import process_named_running
from vyos.util import read_file

base_path = ['container']
cont_image = 'busybox'
prefix = '192.168.205.0/24'
net_name = 'NET01'
PROCESS_NAME = 'podman'

def cmd_to_json(command):
    c = cmd(command + ' --format=json')
    data = json.loads(c)[0]

    return data

class TesContainer(VyOSUnitTestSHIM.TestCase):

    def test_01_basic_container(self):
        cont_name = 'c1'

        self.cli_set(['interfaces', 'ethernet', 'eth0', 'address', '10.0.2.15/24'])
        self.cli_set(['protocols', 'static', 'route', '0.0.0.0/0', 'next-hop', '10.0.2.2'])
        self.cli_set(['system', 'name-server', '1.1.1.1'])
        self.cli_set(['system', 'name-server', '8.8.8.8'])

        self.cli_set(base_path + ['name', cont_name, 'image', cont_image])
        self.cli_set(base_path + ['name', cont_name, 'allow-host-networks'])

        # commit changes
        self.cli_commit()

        # Check for running process
        self.assertTrue(process_named_running(PROCESS_NAME))

    def test_02_container_network(self):
        cont_name = 'c2'
        cont_ip = '192.168.205.25'
        self.cli_set(base_path + ['network', net_name, 'ipv4-prefix', prefix])
        self.cli_set(base_path + ['name', cont_name, 'image', cont_image])
        self.cli_set(base_path + ['name', cont_name, 'network', net_name, 'address', cont_ip])

        # commit changes
        self.cli_commit()

        n = cmd_to_json(f'sudo podman network inspect {net_name}')
        json_subnet = n['plugins'][0]['ipam']['ranges'][0][0]['subnet']

        c = cmd_to_json(f'sudo podman container inspect {cont_name}')
        json_ip = c['NetworkSettings']['Networks'][net_name]['IPAddress']

        self.assertEqual(json_subnet, prefix)
        self.assertEqual(json_ip, cont_ip)

if __name__ == '__main__':
    unittest.main(verbosity=2)
<commit_msg>containers: T2216: Re-enable container smoketest using busybox image<commit_after>#!/usr/bin/env python3
#
# Copyright (C) 2021 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import unittest
import glob
import json

from base_vyostest_shim import VyOSUnitTestSHIM

from vyos.configsession import ConfigSessionError
from vyos.util import cmd
from vyos.util import process_named_running
from vyos.util import read_file

base_path = ['container']
cont_image = 'busybox:stable' # busybox is included in vyos-build
prefix = '192.168.205.0/24'
net_name = 'NET01'
PROCESS_NAME = 'conmon'
PROCESS_PIDFILE = '/run/vyos-container-{0}.service.pid'

busybox_image_path = '/usr/share/vyos/busybox-stable.tar'

def cmd_to_json(command):
    c = cmd(command + ' --format=json')
    data = json.loads(c)[0]

    return data

class TestContainer(VyOSUnitTestSHIM.TestCase):
    @classmethod
    def setUpClass(cls):
        super(TestContainer, cls).setUpClass()

        # Load image for smoketest provided in vyos-build
        cmd(f'cat {busybox_image_path} | sudo podman load')

    @classmethod
    def tearDownClass(cls):
        super(TestContainer, cls).tearDownClass()

        # Cleanup podman image
        cmd(f'sudo podman image rm -f {cont_image}')

    def tearDown(self):
        self.cli_delete(base_path)
        self.cli_commit()

        # Ensure no container process remains
        self.assertIsNone(process_named_running(PROCESS_NAME))

        # Ensure systemd units are removed
        units = glob.glob('/run/systemd/system/vyos-container-*')
        self.assertEqual(units, [])

    def test_01_basic_container(self):
        cont_name = 'c1'

        self.cli_set(['interfaces', 'ethernet', 'eth0', 'address', '10.0.2.15/24'])
        self.cli_set(['protocols', 'static', 'route', '0.0.0.0/0', 'next-hop', '10.0.2.2'])
        self.cli_set(['system', 'name-server', '1.1.1.1'])
        self.cli_set(['system', 'name-server', '8.8.8.8'])

        self.cli_set(base_path + ['name', cont_name, 'image', cont_image])
        self.cli_set(base_path + ['name', cont_name, 'allow-host-networks'])

        # commit changes
        self.cli_commit()

        pid = 0
        with open(PROCESS_PIDFILE.format(cont_name), 'r') as f:
            pid = int(f.read())

        # Check for running process
        self.assertEqual(process_named_running(PROCESS_NAME), pid)

    def test_02_container_network(self):
        cont_name = 'c2'
        cont_ip = '192.168.205.25'
        self.cli_set(base_path + ['network', net_name, 'prefix', prefix])
        self.cli_set(base_path + ['name', cont_name, 'image', cont_image])
        self.cli_set(base_path + ['name', cont_name, 'network', net_name, 'address', cont_ip])

        # commit changes
        self.cli_commit()

        n = cmd_to_json(f'sudo podman network inspect {net_name}')
        json_subnet = n['subnets'][0]['subnet']

        c = cmd_to_json(f'sudo podman container inspect {cont_name}')
        json_ip = c['NetworkSettings']['Networks'][net_name]['IPAddress']

        self.assertEqual(json_subnet, prefix)
        self.assertEqual(json_ip, cont_ip)

if __name__ == '__main__':
    unittest.main(verbosity=2)
<|endoftext|>


<commit_before>"""This script provides a GUI front-end for the Archiver utility."""

##==============================================================#
## DEVELOPED 2012, REVISED 2014, Jeff Rimko.                    #
##==============================================================#

##==============================================================#
## SECTION: Imports                                             #
##==============================================================#

import os
import sys
from time import sleep

import wx

import archiver
from archiver import create_archive, make_outname

##==============================================================#
## SECTION: Global Definitions                                  #
##==============================================================#

# The app name.
APPNAME = "gArchiver"

##==============================================================#
## SECTION: Class Definitions                                   #
##==============================================================#

class MainPanel(wx.Panel):
    """This class defines the main panel."""

    def __init__(self, parent):
        """This function defines initialization logic of the main panel."""
        wx.Panel.__init__(self, parent)

        # The parent is needed to make calls to close().
        self.parent = parent

        # Create the Sizers used for this panel.
        main_sizer = wx.BoxSizer(wx.VERTICAL)
        opts_sizer = wx.BoxSizer(wx.VERTICAL)
        prev_sizer = wx.BoxSizer(wx.VERTICAL)
        bttn_sizer = wx.BoxSizer(wx.HORIZONTAL)

        # Create text input for the archive name.
        name_label = wx.StaticText(self, label="Archive Name:")
        self.name_text = wx.TextCtrl(self, size=(300,-1), style=wx.TE_MULTILINE | wx.HSCROLL | wx.TE_RICH)
        archive_name = os.path.splitext(os.path.basename(sys.argv[1]))[0]
        self.name_text.ChangeValue(archive_name)

        # Create text input for the archive log.
        log_label = wx.StaticText(self, label="Log Text:")
        self.log_text = wx.TextCtrl(self, size=(300,200), style=wx.TE_MULTILINE | wx.TE_RICH | wx.TE_PROCESS_ENTER )

        # Create option check boxes and add to sizer.
        self.no_ts_cb = wx.CheckBox(self, -1, "Do not include timestamp in archive name.")
        self.short_ts_cb = wx.CheckBox(self, -1, "Only timestamp to the day (hour:min otherwise).")
        self.del_cb = wx.CheckBox(self, -1, "Delete original files after archiving.")
        opts_sizer.Add(self.no_ts_cb, 0)
        opts_sizer.Add(self.short_ts_cb, 0, wx.TOP, 10)
        opts_sizer.Add(self.del_cb, 0, wx.TOP, 10)

        # Create output filename preview.
        prev_label = wx.StaticText(self, label="Output File Name:")
        self.prev_text = wx.TextCtrl(self, size=(300,-1), style=wx.TE_MULTILINE | wx.HSCROLL | wx.TE_RICH)

        # Create main control buttons and add to sizer.
        ok_button = wx.Button(self, wx.ID_OK)
        cancel_button = wx.Button(self, wx.ID_CANCEL)
        bttn_sizer.Add(ok_button, 0, wx.LEFT, 30)
        bttn_sizer.Add(cancel_button, 0, wx.LEFT, 90)

        prev_sizer.Add(prev_label, 0, wx.LEFT, 20)
        prev_sizer.Add(self.prev_text, 0, wx.LEFT, 20)

        # Add items to main sizer.
        main_sizer.Add(name_label, 0, wx.TOP | wx.LEFT, 20)
        main_sizer.Add(self.name_text, 0, wx.LEFT, 20)
        main_sizer.Add(log_label, 0, wx.TOP | wx.LEFT, 20)
        main_sizer.Add(self.log_text, 0, wx.LEFT | wx.BOTTOM, 20)
        main_sizer.Add(opts_sizer, 0, wx.LEFT, 20)
        main_sizer.Add(prev_sizer, 0, wx.TOP, 20)
        main_sizer.Add(bttn_sizer, 0, wx.TOP | wx.LEFT, 20)
        self.SetSizerAndFit(main_sizer)

        # Bind events to the methods containing the logic.
        self.Bind(wx.EVT_BUTTON, self.create_new_archive, ok_button)
        self.Bind(wx.EVT_TEXT_ENTER, self.create_new_archive, self.log_text)
        self.Bind(wx.EVT_BUTTON, self.quit, cancel_button)
        self.Bind(wx.EVT_CHECKBOX, self.update_prev, self.no_ts_cb)
        self.Bind(wx.EVT_CHECKBOX, self.update_prev, self.short_ts_cb)
        self.Bind(wx.EVT_TEXT, self.update_prev, self.name_text)

        # Prepare the utility data.
        self.udata = archiver.UtilData()

        # Update output filename preview.
        self.update_prev()

        # This sets initial focus to the log text input.
        self.log_text.SetFocus()

    def quit(self, event):
        """Exit the application."""
        self.parent.Close()

    def update_prev(self, event=None):
        """Updates the output filename preview."""
        self.update_udata()
        self.prev_text.ChangeValue(make_outname(self.udata))

    def update_udata(self, event=None):
        """Updates the archiver utility data."""
        if len(sys.argv) > 1:
            # Since the typical use case for the GUI utility is to call it from
            # the Windows SendTo prompt, the archive should be created in the
            # directory where the call is made.
            if os.path.isfile(sys.argv[1]):
                self.udata['outdir'] = os.path.dirname(sys.argv[1])
                if not self.udata['outdir']:
                    # NOTE: During testing, if the current directory was the
                    # output directory, the output directory would be blank
                    # which would cause issues with the archiver module.
                    self.udata['outdir'] = "."
            elif os.path.isdir(sys.argv[1]):
                self.udata['outdir'] = os.path.normpath(os.path.join(sys.argv[1], ".."))
            else:
                sys.exit("ERROR: Unknown target type!")
            self.udata['log_text'] = self.log_text.GetValue()
            self.udata['name'] = self.name_text.GetValue()
            self.udata['targets'] = sys.argv[1:]
            self.udata['no_ts'] = self.no_ts_cb.GetValue()
            self.udata['short_ts'] = self.short_ts_cb.GetValue()
            self.udata['delete'] = self.del_cb.GetValue()

    def create_new_archive(self, event):
        """Create a new archive."""
        self.update_udata()
        if self.udata['targets']:
            # Set the mouse cursor to waiting.
            wx.BeginBusyCursor()
            # Create archive.
            create_archive(self.udata, self.prev_text.GetValue())
            # Return the mouse cursor to normal.
            wx.EndBusyCursor()
        # Exit the application.
        self.quit(event)

class MainWindow(wx.Frame):
    """This class defines the main window."""

    def __init__(self, parent, title):
        """This function defines initialization logic of the main window."""
        wx.Frame.__init__(self,
                          parent,
                          title=title,
                          size=(350, 540),
                          # This style disables the ability to resize the window.
                          style=wx.DEFAULT_FRAME_STYLE & ~(wx.RESIZE_BORDER | wx.RESIZE_BOX | wx.MAXIMIZE_BOX))
        panel = MainPanel(self)
        self.Show(True)

##==============================================================#
## SECTION: Main Body                                           #
##==============================================================#

if __name__ == "__main__":
    if len(sys.argv) >= 2:
        app = wx.App(False)
        frame = MainWindow(None, "%s %s" % (APPNAME, archiver.__version__))
        app.MainLoop()
<commit_msg>Various cleanup.<commit_after>"""This script provides a GUI front-end for the Archiver utility."""

##==============================================================#
## DEVELOPED 2012, REVISED 2014, Jeff Rimko.                    #
##==============================================================#

##==============================================================#
## SECTION: Imports                                             #
##==============================================================#

import os
import sys
from time import sleep

import wx

import archiver
from archiver import create_archive, make_outname

##==============================================================#
## SECTION: Global Definitions                                  #
##==============================================================#

# The app name.
APPNAME = "gArchiver"

##==============================================================#
## SECTION: Class Definitions                                   #
##==============================================================#

class MainPanel(wx.Panel):
    """This class defines the main panel."""

    def __init__(self, parent):
        """This function defines initialization logic of the main panel."""
        wx.Panel.__init__(self, parent)

        # The parent is needed to make calls to close().
        self.parent = parent

        # Create the Sizers used for this panel.
        main_sizer = wx.BoxSizer(wx.VERTICAL)
        opts_sizer = wx.BoxSizer(wx.VERTICAL)
        prev_sizer = wx.BoxSizer(wx.VERTICAL)
        bttn_sizer = wx.BoxSizer(wx.HORIZONTAL)

        # Create text input for the archive name.
        name_label = wx.StaticText(self, label="Archive Name:")
        style = wx.TE_MULTILINE | wx.HSCROLL | wx.TE_RICH
        self.name_text = wx.TextCtrl(self, size=(300,-1), style=style)
        archive_name = os.path.splitext(os.path.basename(sys.argv[1]))[0]
        self.name_text.ChangeValue(archive_name)

        # Create text input for the archive log.
        log_label = wx.StaticText(self, label="Log Text:")
        style = wx.TE_MULTILINE | wx.TE_RICH | wx.TE_PROCESS_ENTER
        self.log_text = wx.TextCtrl(self, size=(300,200), style=style)

        # Create option check boxes and add to sizer.
        self.no_ts_cb = wx.CheckBox(self, -1,
                "Do not include timestamp in archive name.")
        self.short_ts_cb = wx.CheckBox(self, -1,
                "Only timestamp to the day (hour:min otherwise).")
        self.del_cb = wx.CheckBox(self, -1,
                "Delete original files after archiving.")
        opts_sizer.Add(self.no_ts_cb, 0)
        opts_sizer.Add(self.short_ts_cb, 0, wx.TOP, 10)
        opts_sizer.Add(self.del_cb, 0, wx.TOP, 10)

        # Create output filename preview.
        prev_label = wx.StaticText(self, label="Output File Name:")
        style = wx.TE_MULTILINE | wx.HSCROLL | wx.TE_RICH
        self.prev_text = wx.TextCtrl(self, size=(300,-1), style=style)

        # Create main control buttons and add to sizer.
        ok_button = wx.Button(self, wx.ID_OK)
        cancel_button = wx.Button(self, wx.ID_CANCEL)
        bttn_sizer.Add(ok_button, 0, wx.LEFT, 30)
        bttn_sizer.Add(cancel_button, 0, wx.LEFT, 90)

        prev_sizer.Add(prev_label, 0, wx.LEFT, 20)
        prev_sizer.Add(self.prev_text, 0, wx.LEFT, 20)

        # Add items to main sizer.
        main_sizer.Add(name_label, 0, wx.TOP | wx.LEFT, 20)
        main_sizer.Add(self.name_text, 0, wx.LEFT, 20)
        main_sizer.Add(log_label, 0, wx.TOP | wx.LEFT, 20)
        main_sizer.Add(self.log_text, 0, wx.LEFT | wx.BOTTOM, 20)
        main_sizer.Add(opts_sizer, 0, wx.LEFT, 20)
        main_sizer.Add(prev_sizer, 0, wx.TOP, 20)
        main_sizer.Add(bttn_sizer, 0, wx.TOP | wx.LEFT, 20)
        self.SetSizerAndFit(main_sizer)

        # Bind events to the methods containing the logic.
        self.Bind(wx.EVT_BUTTON, self.create_new_archive, ok_button)
        self.Bind(wx.EVT_BUTTON, self.quit, cancel_button)
        self.Bind(wx.EVT_CHECKBOX, self.update_prev, self.no_ts_cb)
        self.Bind(wx.EVT_CHECKBOX, self.update_prev, self.short_ts_cb)
        self.Bind(wx.EVT_TEXT, self.update_prev, self.name_text)
        self.Bind(wx.EVT_TEXT_ENTER, self.create_new_archive, self.log_text)

        # Prepare the utility data.
        self.udata = archiver.UtilData()

        # Update output filename preview.
        self.update_prev()

        # This sets initial focus to the log text input.
        self.log_text.SetFocus()

    def quit(self, event):
        """Exit the application."""
        self.parent.Close()

    def update_prev(self, event=None):
        """Updates the output filename preview."""
        self.update_udata()
        self.prev_text.ChangeValue(make_outname(self.udata))

    def update_udata(self, event=None):
        """Updates the archiver utility data."""
        if len(sys.argv) > 1:
            # Since the typical use case for the GUI utility is to call it from
            # the Windows SendTo prompt, the archive should be created in the
            # directory where the call is made.
            if os.path.isfile(sys.argv[1]):
                self.udata['outdir'] = os.path.dirname(sys.argv[1])
                if not self.udata['outdir']:
                    # NOTE: During testing, if the current directory was the
                    # output directory, the output directory would be blank
                    # which would cause issues with the archiver module.
                    self.udata['outdir'] = "."
            elif os.path.isdir(sys.argv[1]):
                self.udata['outdir'] = os.path.normpath(
                        os.path.join(sys.argv[1], ".."))
            else:
                sys.exit("ERROR: Unknown target type!")
            self.udata['log_text'] = self.log_text.GetValue()
            self.udata['name'] = self.name_text.GetValue()
            self.udata['targets'] = sys.argv[1:]
            self.udata['no_ts'] = self.no_ts_cb.GetValue()
            self.udata['short_ts'] = self.short_ts_cb.GetValue()
            self.udata['delete'] = self.del_cb.GetValue()

    def create_new_archive(self, event):
        """Create a new archive."""
        self.update_udata()
        if self.udata['targets']:
            # Set the mouse cursor to waiting.
            wx.BeginBusyCursor()
            # Create archive.
            create_archive(self.udata, self.prev_text.GetValue())
            # Return the mouse cursor to normal.
            wx.EndBusyCursor()
        # Exit the application.
        self.quit(event)

class MainWindow(wx.Frame):
    """This class defines the main window."""

    def __init__(self, parent, title):
        """This function defines initialization logic of the main window."""
        # This style disables the ability to resize the window.
        style = wx.DEFAULT_FRAME_STYLE
        style &= ~(wx.RESIZE_BORDER | wx.RESIZE_BOX | wx.MAXIMIZE_BOX)
        wx.Frame.__init__(self,
                          parent,
                          title=title,
                          size=(350, 540),
                          style=style)
        panel = MainPanel(self)
        self.Show(True)

##==============================================================#
## SECTION: Main Body                                           #
##==============================================================#

if __name__ == "__main__":
    if len(sys.argv) >= 2:
        app = wx.App(False)
        frame = MainWindow(None, "%s %s" % (APPNAME, archiver.__version__))
        app.MainLoop()
<|endoftext|>


<commit_before>import flask
import tasks

BROKER_URL = 'amqp://guest:guest@localhost:5672//'

flask_app = flask.Flask(__name__)
flask_app.config.update(
    CELERY_BROKER_URL=BROKER_URL,
    CELERY_RESULT_BACKEND=BROKER_URL
)
celery = tasks.make_celery(flask_app)

@flask_app.route("/")
def main(name=None):
    return flask.render_template('main.html', name=name)

@celery.task()
def sort_until_done(integers):
    import time
    time.sleep(1)
    return sorted(integers)

# def bogosort(seq):
    # """In-place bogosort with inversion number counter."""
    # inversion_counter = collections.Counter()
    # current_inversions = inversions.inversion_number(seq)

    # # bogosort
    # while current_inversions:
    #     inversion_counter[current_inversions] += 1
    #     random.shuffle(seq)
    #     current_inversions = inversions.inversion_number(seq)

<commit_msg>outline main module structure<commit_after>import flask
import tasks
import numpy

BROKER_URL = 'amqp://guest:guest@localhost:5672//'

flask_app = flask.Flask(__name__)
flask_app.config.update(
    CELERY_BROKER_URL=BROKER_URL,
    CELERY_RESULT_BACKEND=BROKER_URL
)
celery = tasks.make_celery(flask_app)

@flask_app.route("/")
def main(name=None):
    return flask.render_template('main.html', name=name)

@flask_app.route("/history")
def history():
    # return flask.render_template('history.html', name=name)
    return "TODO"

@celery.task()
def sort_until_done(integers):
    import time
    time.sleep(5)
    return sorted(integers)

def get_from_db():
    #TODO
    return []

def next_list(n):
    return list(range(1, n+1))

def powers_of_ten(start=1, end=7):
    return map(lambda n: 10**n, range(start, end))

def restart_from_previous_known_state():
    sequence = get_from_db()
    bogo(sequence)

def bogo(sequence=None):
    prev_ten_exponent = int(numpy.log10(len(sequence))) if sequence else 1
    is_restarting = sequence is not None

    for length in powers_of_ten(prev_ten_exponent, 7):
        if is_restarting:
            is_restarting = False
        else:
            sequence = next_list(length)
        result = sort_until_done.delay(sequence)
        result.wait()

if __name__ == "__main__":
    if not celery.current_task:
        restart_from_previous_known_state()
<|endoftext|>


<commit_before>from flask import render_template, abort, request, url_for
from random import choice
from datetime import datetime
from twilio.twiml import Response
from sqlalchemy.exc import IntegrityError
from config import *
from database.models import Reminder
from . import app, reps, db_session
from .decorators import validate_twilio_request

@app.route("/")
def root():
    important_reps = []
    return render_template("index.html", reps=important_reps)

@app.route("/politiker/")
def representatives():
    return render_template("representatives.html", reps=reps.representatives)

@app.route("/p/<prettyname>/")
def representative(prettyname):
    rep = reps.get_representative_by_name(prettyname)
    if rep:
        return render_template("representative.html", rep=rep, twilio_number=TWILIO_NUMBERS[0])
    else:
        abort(404)

@app.route("/weitersagen/")
def share():
    return render_template("share.html")

@app.route("/faq/")
def faq():
    return render_template("faq.html")

@app.route("/datenschutz/")
def privacy():
    return render_template("privacy.html")

def sendmail(rep, firstname, lastname, email):
    return False

@app.route("/act/mail/", methods=["POST"])
def mail():
    id = request.form.get("id")
    firstname = request.form.get("firstname")
    lastname = request.form.get("lastname")
    email = request.form.get("email")
    newsletter = True if request.form.get("newsletter") == "yes" else False
    rep = reps.get_representative_by_id(id)

    if not all([rep, firstname, lastname, email]):
        app.logger.info("Sendmail: passed invalid arguments.")
        abort(400) # bad request

    if not app.debug:
        success = sendmail(rep, firstname, lastname, email, newsletter)

    return render_template("representative.html", rep=rep, success=success)

@app.route("/act/call/", methods=["POST"])
@validate_twilio_request
def call():
    resp = Response()

    resp.play(url_for("static", filename="audio/intro.wav"))
    resp.redirect(url_for("gather_menu"))

    return str(resp)

@app.route("/act/gather-menu/", methods=["POST"])
@validate_twilio_request
def gather_menu():
    number = request.values.get("From")
    resp = Response()

    try:
        reminder = Reminder(number)
        db_session.add(reminder)
        db_session.commit()
    except IntegrityError:
        pass

    with resp.gather(numDigits=1, action=url_for("handle_menu")) as g:
        g.play(url_for("static", filename="audio/gather_menu.wav"))

    resp.redirect(url_for("gather_menu"))

    return str(resp)

@app.route("/act/handle-menu/", methods=["POST"])
@validate_twilio_request
def handle_menu():
    digits_pressed = request.values.get("Digits", 0, type=int)
    resp = Response()

    if digits_pressed == 1:
        resp.redirect(url_for("gather_reminder_time"))
    elif digits_pressed == 2:
        resp.redirect(url_for("gather_representative"))
    elif digits_pressed == 3:
        resp.redirect(url_for("info_tape"))
    elif digits_pressed == 4:
        resp.redirect(url_for("handle_reminder_unsubscribe"))
    else:
        resp.play(url_for("static", filename="audio/invalid.wav"))
        resp.redirect(url_for("gather_menu"))

    return str(resp)

@app.route("/act/gather-reminder-time/", methods=["POST"])
@validate_twilio_request
def gather_reminder_time():
    resp = Response()

    with resp.gather(numDigits=2, action=url_for("handle_reminder_time")) as g:
        g.play(url_for("static", filename="audio/gather_reminder_time.wav"))

    resp.redirect(url_for("gather_reminder_time"))

    return str(resp)

@app.route("/act/handle-reminder-time/", methods=["POST"])
@validate_twilio_request
def handle_reminder_time():
    digits_pressed = request.values.get("Digits", 0, type=int)
    number = request.values.get("From")
    resp = Response()

    if not number or number in ["+7378742833", "+2562533", "+8656696", "+266696687", "+86282452253"]:
        resp.play(url_for("static", filename="audio/handle_reminder_time_error.wav"))
    if 9 <= digits_pressed <= 16:
        reminder = db_session.query(Reminder).filter_by(phone_number = number).first()
        if reminder.time is None:
            resp.play(url_for("static", filename="audio/handle_reminder_time_set.wav"))
        else:
            if digits_pressed > datetime.now().hour and reminder.last_called.date() == datetime.today().date():
                reminder.last_called = None

            resp.play(url_for("static", filename="audio/handle_reminder_time_reset.wav"))

        reminder.time = digits_pressed
        db_session.commit()
    else:
        resp.play(url_for("static", filename="audio/handle_reminder_time_invalid.wav"))
        resp.redirect(url_for("gather_reminder_time"))

    return str(resp)

@app.route("/act/gather-representative/", methods=["POST"])
@validate_twilio_request
def gather_representative():
    resp = Response()

    with resp.gather(numDigits=5, action=url_for("handle_representative")) as g:
        g.play(url_for("static", filename="audio/gather_representative.wav"))

    resp.redirect(url_for("gather_representative"))

    return str(resp)

@app.route("/act/handle-representative/", methods=["POST"])
@validate_twilio_request
def handle_representative():
    digits_pressed = request.values.get("Digits", "00000", type=str)
    rep = reps.get_representative_by_id(digits_pressed)
    resp = Response()

    if rep is not None:
        resp.play(url_for("static", filename="audio/handle_representative_a.wav"))
        resp.say(str(rep), language="de-DE", voice="alice")
        resp.play(url_for("static", filename="audio/handle_representative_c.wav"))

        if not app.debug:
            resp.dial(rep.contact.phone, timelimit=600, callerid=choice(TWILIO_NUMBERS))
    else:
        resp.play(url_for("static", filename="audio/handle_representative_invalid.wav"))
        resp.redirect(url_for("gather_representative"))

    return str(resp)

@app.route("/act/handle-reminder-unsubscribe/", methods=["POST"])
@validate_twilio_request
def handle_reminder_unsubscribe():
    resp = Response()

    direction = request.values.get("Direction")

    if direction == "inbound":
        number = request.values.get("From")
    else:
        number = request.values.get("To")

    reminder = db_session.query(Reminder).filter_by(phone_number = number).first()
    reminder.time = None
    db_session.commit()
    resp.play(url_for("static", filename="audio/handle_reminder_unsubscribe.wav"))

    return str(resp)

@app.route("/act/gather-reminder-call/", methods=["POST"])
@validate_twilio_request
def gather_reminder_call():
    resp = Response()

    resp.play(url_for("static", filename="audio/gather_reminder_call.wav"))
    resp.redirect(url_for("gather_reminder_menu"))

    return str(resp)

@app.route("/act/gather-reminder-menu/", methods=["POST"])
@validate_twilio_request
def gather_reminder_menu():
    resp = Response()

    with resp.gather(numDigits=1, action=url_for("handle_reminder_menu")) as g:
        g.play(url_for("static", filename="audio/gather_reminder_menu.wav"), loop = 5)

    return str(resp)

@app.route("/act/handle-reminder-menu/", methods=["POST"])
@validate_twilio_request
def handle_reminder_menu():
    digits_pressed = request.values.get("Digits", 0, type=int)
    number = request.values.get("To")
    resp = Response()

    if digits_pressed == 1:
        reminder = db_session.query(Reminder).filter_by(phone_number = number).first()
        reminder.times_forwarded = reminder.times_forwarded + 1
        db_session.commit()

        rep = choice([rep for rep in resp.representatives if rep.team.prettyname == "spy"])
        resp.play(url_for("static", filename="audio/handle_representative_a.wav"))
        resp.say(str(rep), language="de-DE", voice="alice")
        resp.play(url_for("static", filename="audio/handle_representative_c.wav"))

        if not app.debug:
            resp.dial(rep.contact.phone, timelimit=600, callerid=choice(TWILIO_NUMBERS))

    elif digits_pressed == 2:
        pass # hang up
    elif digits_pressed == 3:
        resp.redirect(url_for("reminder_info_tape"))
    elif digits_pressed == 4:
        resp.redirect(url_for("handle_reminder_unsubscribe"))
    else:
        resp.play(url_for("static", filename="audio/invalid.wav"))
        resp.redirect(url_for("gather_reminder_menu"))

    return str(resp)

@app.route("/act/info_tape/", methods=["POST"])
@validate_twilio_request
def info_tape():
    resp = Response()

    with resp.gather(numDigits=1, action=url_for("gather_menu")) as g:
        g.play(url_for("static", filename="audio/info_tape.wav"))

    resp.redirect(url_for("gather_menu"))

    return str(resp)

@app.route("/act/reminder_info_tape/", methods=["POST"])
@validate_twilio_request
def reminder_info_tape():
    resp = Response()

    with resp.gather(numDigits=1, action=url_for("gather_reminder_menu")) as g:
        g.play(url_for("static", filename="audio/info_tape.wav"))

    resp.redirect(url_for("gather_reminder_menu"))

    return str(resp)

@app.errorhandler(404)
def page_not_found(error):
    return render_template('404.html'), 404
<commit_msg>Limit general loop.<commit_after>from flask import render_template, abort, request, url_for
from random import choice
from datetime import datetime
from twilio.twiml import Response
from sqlalchemy.exc import IntegrityError
from config import *
from database.models import Reminder
from . import app, reps, db_session
from .decorators import validate_twilio_request

@app.route("/")
def root():
    important_reps = []
    return render_template("index.html", reps=important_reps)

@app.route("/politiker/")
def representatives():
    return render_template("representatives.html", reps=reps.representatives)

@app.route("/p/<prettyname>/")
def representative(prettyname):
    rep = reps.get_representative_by_name(prettyname)
    if rep:
        return render_template("representative.html", rep=rep, twilio_number=TWILIO_NUMBERS[0])
    else:
        abort(404)

@app.route("/weitersagen/")
def share():
    return render_template("share.html")

@app.route("/faq/")
def faq():
    return render_template("faq.html")

@app.route("/datenschutz/")
def privacy():
    return render_template("privacy.html")

def sendmail(rep, firstname, lastname, email):
    return False

@app.route("/act/mail/", methods=["POST"])
def mail():
    id = request.form.get("id")
    firstname = request.form.get("firstname")
    lastname = request.form.get("lastname")
    email = request.form.get("email")
    newsletter = True if request.form.get("newsletter") == "yes" else False
    rep = reps.get_representative_by_id(id)

    if not all([rep, firstname, lastname, email]):
        app.logger.info("Sendmail: passed invalid arguments.")
        abort(400) # bad request

    if not app.debug:
        success = sendmail(rep, firstname, lastname, email, newsletter)

    return render_template("representative.html", rep=rep, success=success)

@app.route("/act/call/", methods=["POST"])
@validate_twilio_request
def call():
    resp = Response()

    resp.play(url_for("static", filename="audio/intro.wav"))
    resp.redirect(url_for("gather_menu"))

    return str(resp)

@app.route("/act/gather-menu/", methods=["POST"])
@validate_twilio_request
def gather_menu():
    number = request.values.get("From")
    resp = Response()

    try:
        reminder = Reminder(number)
        db_session.add(reminder)
        db_session.commit()
    except IntegrityError:
        pass

    with resp.gather(numDigits=1, action=url_for("handle_menu")) as g:
        g.play(url_for("static", filename="audio/gather_menu.wav"), loop = 4)

    return str(resp)

@app.route("/act/handle-menu/", methods=["POST"])
@validate_twilio_request
def handle_menu():
    digits_pressed = request.values.get("Digits", 0, type=int)
    resp = Response()

    if digits_pressed == 1:
        resp.redirect(url_for("gather_reminder_time"))
    elif digits_pressed == 2:
        resp.redirect(url_for("gather_representative"))
    elif digits_pressed == 3:
        resp.redirect(url_for("info_tape"))
    elif digits_pressed == 4:
        resp.redirect(url_for("handle_reminder_unsubscribe"))
    else:
        resp.play(url_for("static", filename="audio/invalid.wav"))
        resp.redirect(url_for("gather_menu"))

    return str(resp)

@app.route("/act/gather-reminder-time/", methods=["POST"])
@validate_twilio_request
def gather_reminder_time():
    resp = Response()

    with resp.gather(numDigits=2, action=url_for("handle_reminder_time")) as g:
        g.play(url_for("static", filename="audio/gather_reminder_time.wav"), loop = 4)

    return str(resp)

@app.route("/act/handle-reminder-time/", methods=["POST"])
@validate_twilio_request
def handle_reminder_time():
    digits_pressed = request.values.get("Digits", 0, type=int)
    number = request.values.get("From")
    resp = Response()

    if not number or number in ["+7378742833", "+2562533", "+8656696", "+266696687", "+86282452253"]:
        resp.play(url_for("static", filename="audio/handle_reminder_time_error.wav"))
    if 9 <= digits_pressed <= 16:
        reminder = db_session.query(Reminder).filter_by(phone_number = number).first()
        if reminder.time is None:
            resp.play(url_for("static", filename="audio/handle_reminder_time_set.wav"))
        else:
            if digits_pressed > datetime.now().hour and reminder.last_called.date() == datetime.today().date():
                reminder.last_called = None

            resp.play(url_for("static", filename="audio/handle_reminder_time_reset.wav"))

        reminder.time = digits_pressed
        db_session.commit()
    else:
        resp.play(url_for("static", filename="audio/handle_reminder_time_invalid.wav"))
        resp.redirect(url_for("gather_reminder_time"))

    return str(resp)

@app.route("/act/gather-representative/", methods=["POST"])
@validate_twilio_request
def gather_representative():
    resp = Response()

    with resp.gather(numDigits=5, action=url_for("handle_representative")) as g:
        g.play(url_for("static", filename="audio/gather_representative.wav"), loop = 4)

    return str(resp)

@app.route("/act/handle-representative/", methods=["POST"])
@validate_twilio_request
def handle_representative():
    digits_pressed = request.values.get("Digits", "00000", type=str)
    rep = reps.get_representative_by_id(digits_pressed)
    resp = Response()

    if rep is not None:
        resp.play(url_for("static", filename="audio/handle_representative_a.wav"))
        resp.say(str(rep), language="de-DE", voice="alice")
        resp.play(url_for("static", filename="audio/handle_representative_c.wav"))

        if not app.debug:
            resp.dial(rep.contact.phone, timelimit=600, callerid=choice(TWILIO_NUMBERS))
    else:
        resp.play(url_for("static", filename="audio/handle_representative_invalid.wav"))
        resp.redirect(url_for("gather_representative"))

    return str(resp)

@app.route("/act/handle-reminder-unsubscribe/", methods=["POST"])
@validate_twilio_request
def handle_reminder_unsubscribe():
    resp = Response()

    direction = request.values.get("Direction")

    if direction == "inbound":
        number = request.values.get("From")
    else:
        number = request.values.get("To")

    reminder = db_session.query(Reminder).filter_by(phone_number = number).first()
    reminder.time = None
    db_session.commit()
    resp.play(url_for("static", filename="audio/handle_reminder_unsubscribe.wav"))

    return str(resp)

@app.route("/act/gather-reminder-call/", methods=["POST"])
@validate_twilio_request
def gather_reminder_call():
    resp = Response()

    resp.play(url_for("static", filename="audio/gather_reminder_call.wav"))
    resp.redirect(url_for("gather_reminder_menu"))

    return str(resp)

@app.route("/act/gather-reminder-menu/", methods=["POST"])
@validate_twilio_request
def gather_reminder_menu():
    resp = Response()

    with resp.gather(numDigits=1, action=url_for("handle_reminder_menu")) as g:
        g.play(url_for("static", filename="audio/gather_reminder_menu.wav"), loop = 4)

    return str(resp)

@app.route("/act/handle-reminder-menu/", methods=["POST"])
@validate_twilio_request
def handle_reminder_menu():
    digits_pressed = request.values.get("Digits", 0, type=int)
    number = request.values.get("To")
    resp = Response()

    if digits_pressed == 1:
        reminder = db_session.query(Reminder).filter_by(phone_number = number).first()
        reminder.times_forwarded = reminder.times_forwarded + 1
        db_session.commit()

        rep = choice([rep for rep in resp.representatives if rep.team.prettyname == "spy"])
        resp.play(url_for("static", filename="audio/handle_representative_a.wav"))
        resp.say(str(rep), language="de-DE", voice="alice")
        resp.play(url_for("static", filename="audio/handle_representative_c.wav"))

        if not app.debug:
            resp.dial(rep.contact.phone, timelimit=600, callerid=choice(TWILIO_NUMBERS))

    elif digits_pressed == 2:
        pass # hang up
    elif digits_pressed == 3:
        resp.redirect(url_for("reminder_info_tape"))
    elif digits_pressed == 4:
        resp.redirect(url_for("handle_reminder_unsubscribe"))
    else:
        resp.play(url_for("static", filename="audio/invalid.wav"))
        resp.redirect(url_for("gather_reminder_menu"))

    return str(resp)

@app.route("/act/info_tape/", methods=["POST"])
@validate_twilio_request
def info_tape():
    resp = Response()

    with resp.gather(numDigits=1, action=url_for("gather_menu")) as g:
        g.play(url_for("static", filename="audio/info_tape.wav"))

    resp.redirect(url_for("gather_menu"))

    return str(resp)

@app.route("/act/reminder_info_tape/", methods=["POST"])
@validate_twilio_request
def reminder_info_tape():
    resp = Response()

    with resp.gather(numDigits=1, action=url_for("gather_reminder_menu")) as g:
        g.play(url_for("static", filename="audio/info_tape.wav"))

    resp.redirect(url_for("gather_reminder_menu"))

    return str(resp)

@app.errorhandler(404)
def page_not_found(error):
    return render_template('404.html'), 404
<|endoftext|>


<commit_before>from django.test import TestCase, override_settings

from django.db import models
from django.utils import timezone

from .fields import UnixTimeStampField

unix_0 = timezone.datetime.fromtimestamp(0.0)
unix_0_utc = timezone.datetime.fromtimestamp(0.0, timezone.utc)

class ForTestModel(models.Model):

    created = UnixTimeStampField(auto_now_add=True)
    modified = UnixTimeStampField(auto_now=True)
    str_ini = UnixTimeStampField(default='0.0')
    float_ini = UnixTimeStampField(default=0.0)
    int_ini = UnixTimeStampField(default=0.0)
    dt_ini = UnixTimeStampField(default=unix_0_utc)

class TimeStampFieldTest(TestCase):

    @override_settings(USE_TZ=True, TIME_ZONE='UTC')
    def test_init_with_use_tz(self):
        now = timezone.now()
        expected = timezone.make_aware(timezone.datetime.utcfromtimestamp(0.0), timezone.utc)
        t = ForTestModel.objects.create()

        self.assertGreater(t.created, now)
        self.assertGreater(t.modified, now)
        self.assertEqual(t.str_ini, expected)
        self.assertEqual(t.float_ini, expected)
        self.assertEqual(t.int_ini, expected)

    @override_settings(USE_TZ=True, TIME_ZONE='UTC')
    def test_assignment_with_tz(self):
        expected = timezone.make_aware(timezone.datetime.utcfromtimestamp(3.0), timezone.utc)
        t = ForTestModel.objects.create()

        pre_modified = t.modified

        t.str_ini = '3'
        t.float_ini = 3.0
        t.int_ini = 3
        t.dt_ini = timezone.datetime.fromtimestamp(3.0, timezone.utc)
        t.save()

        t.refresh_from_db()

        self.assertGreater(t.modified, pre_modified)
        self.assertEqual(t.str_ini, expected)
        self.assertEqual(t.float_ini, expected)
        self.assertEqual(t.int_ini, expected)

    @override_settings(USE_TZ=True, TIME_ZONE='Asia/Taipei')
    def test_init_with_different_tz(self):
        now = timezone.now()
        expected = timezone.localtime(
            timezone.make_aware(timezone.datetime.utcfromtimestamp(0.0), timezone.utc),
            timezone.pytz.timezone('Asia/Taipei')
        )
        t = ForTestModel.objects.create()

        self.assertGreater(t.created, now)
        self.assertGreater(t.modified, now)
        self.assertEqual(t.str_ini, expected)
        self.assertEqual(t.float_ini, expected)
        self.assertEqual(t.int_ini, expected)

    @override_settings(USE_TZ=False)
    def test_init_without_tz(self):
        now = timezone.datetime.now()
        expected = timezone.datetime.fromtimestamp(0.0)
        t = ForTestModel.objects.create()

        self.assertGreater(t.created, now)
        self.assertGreater(t.modified, now)
        self.assertEqual(t.str_ini, expected)
        self.assertEqual(t.float_ini, expected)
        self.assertEqual(t.int_ini, expected)

    @override_settings(USE_TZ=False)
    def test_assignment_without_tz(self):
        expected = timezone.datetime.fromtimestamp(3.0)
        t = ForTestModel.objects.create()

        pre_modified = t.modified

        t.str_ini = '3'
        t.float_ini = 3.0
        t.int_ini = 3
        t.dt_ini = timezone.datetime.fromtimestamp(3.0)
        t.save()

        t.refresh_from_db()

        self.assertGreater(t.modified, pre_modified)
        self.assertEqual(t.str_ini, expected)
        self.assertEqual(t.float_ini, expected)
        self.assertEqual(t.int_ini, expected)
<commit_msg>Fix refresh_from_db() befroe django1.8<commit_after>from django.test import TestCase, override_settings

from django.db import models
from django.utils import timezone

from .fields import UnixTimeStampField

unix_0 = timezone.datetime.fromtimestamp(0.0)
unix_0_utc = timezone.datetime.fromtimestamp(0.0, timezone.utc)

class ForTestModel(models.Model):

    created = UnixTimeStampField(auto_now_add=True)
    modified = UnixTimeStampField(auto_now=True)
    str_ini = UnixTimeStampField(default='0.0')
    float_ini = UnixTimeStampField(default=0.0)
    int_ini = UnixTimeStampField(default=0.0)
    dt_ini = UnixTimeStampField(default=unix_0_utc)

class TimeStampFieldTest(TestCase):

    @override_settings(USE_TZ=True, TIME_ZONE='UTC')
    def test_init_with_use_tz(self):
        now = timezone.now()
        expected = timezone.make_aware(timezone.datetime.utcfromtimestamp(0.0), timezone.utc)
        t = ForTestModel.objects.create()

        self.assertGreater(t.created, now)
        self.assertGreater(t.modified, now)
        self.assertEqual(t.str_ini, expected)
        self.assertEqual(t.float_ini, expected)
        self.assertEqual(t.int_ini, expected)

    @override_settings(USE_TZ=True, TIME_ZONE='UTC')
    def test_assignment_with_tz(self):
        expected = timezone.make_aware(timezone.datetime.utcfromtimestamp(3.0), timezone.utc)
        t = ForTestModel.objects.create()

        pre_modified = t.modified

        t.str_ini = '3'
        t.float_ini = 3.0
        t.int_ini = 3
        t.dt_ini = timezone.datetime.fromtimestamp(3.0, timezone.utc)
        t.save()

        if hasattr(t, 'refresh_from_db'):
            t.refresh_from_db()
        else:
            t = ForTestModel.objects.get(id=t.id)

        self.assertGreater(t.modified, pre_modified)
        self.assertEqual(t.str_ini, expected)
        self.assertEqual(t.float_ini, expected)
        self.assertEqual(t.int_ini, expected)

    @override_settings(USE_TZ=True, TIME_ZONE='Asia/Taipei')
    def test_init_with_different_tz(self):
        now = timezone.now()
        expected = timezone.localtime(
            timezone.make_aware(timezone.datetime.utcfromtimestamp(0.0), timezone.utc),
            timezone.pytz.timezone('Asia/Taipei')
        )
        t = ForTestModel.objects.create()

        self.assertGreater(t.created, now)
        self.assertGreater(t.modified, now)
        self.assertEqual(t.str_ini, expected)
        self.assertEqual(t.float_ini, expected)
        self.assertEqual(t.int_ini, expected)

    @override_settings(USE_TZ=False)
    def test_init_without_tz(self):
        now = timezone.datetime.now()
        expected = timezone.datetime.fromtimestamp(0.0)
        t = ForTestModel.objects.create()

        self.assertGreater(t.created, now)
        self.assertGreater(t.modified, now)
        self.assertEqual(t.str_ini, expected)
        self.assertEqual(t.float_ini, expected)
        self.assertEqual(t.int_ini, expected)

    @override_settings(USE_TZ=False)
    def test_assignment_without_tz(self):
        expected = timezone.datetime.fromtimestamp(3.0)
        t = ForTestModel.objects.create()

        pre_modified = t.modified

        t.str_ini = '3'
        t.float_ini = 3.0
        t.int_ini = 3
        t.dt_ini = timezone.datetime.fromtimestamp(3.0)
        t.save()

        if hasattr(t, 'refresh_from_db'):
            t.refresh_from_db()
        else:
            t = ForTestModel.objects.get(id=t.id)

        self.assertGreater(t.modified, pre_modified)
        self.assertEqual(t.str_ini, expected)
        self.assertEqual(t.float_ini, expected)
        self.assertEqual(t.int_ini, expected)
<|endoftext|>


<commit_before>"""
    This module defines utilizes the flask-login_ package to implement
    session management for the API.

    .. flask-login_: http://pythonhosted.org/Flask-Login/

"""

__author__ = {
    "ryan faulkner": "rfaulkner@wikimedia.org"
}
__date__ = "2013-03-21"
__license__ = "GPL (version 2 or later)"

from user_metrics.config import logging, settings
from user_metrics.metrics import query_mod

# API User Authentication
# #######################

# With the presence of flask.ext.login module
if settings.__flask_login_exists__:

    from werkzeug.security import generate_password_hash,\
        check_password_hash

    from flask.ext.login import LoginManager, current_user, UserMixin, \
        AnonymousUser, confirm_login

    class APIUser(UserMixin):
        """
            Extends USerMixin.  User class for flask-login.  Implements a way
            to add user credentials with _HMAC and salting.

            .. HMAC_: http://tinyurl.com/d8zbbem

        """
        def __init__(self, username, password, active=True):
            self.name = username
            self.active = active
            self.set_password(password)

        def is_active(self):
            return self.active

        @staticmethod
        def get(uid):
            """
                Used by ``load_user`` to retrieve user session info.
            """
            usr_ref = query_mod.get_api_user(uid)
            if usr_ref:
                try:
                    return APIUser(unicode(str(usr_ref[0])),
                                   int(usr_ref[1]))
                except (KeyError, ValueError):
                    logging.error(__name__ + ' :: Could not get API '
                                             'user info.')
                    return None
            else:
                return None

        def set_password(self, password):
            self.pw_hash = generate_password_hash(password)

        def check_password(self, password):
            return check_password_hash(self.pw_hash, password)

        def register_user(self):
            """ Writes the user credentials to the datastore. """
            # 1. Ensure that the user is unique
            # 2. Write the user / pass to the db
            if not query_mod.get_api_user(self.name, by_id=False):
                query_mod.insert_api_user(self.name, self.pw_hash)
                logging.debug(__name__ + ' :: Added user {0}'.
                    format(self.name))
            else:
                logging.error(__name__ + 'Could not add user {0}'.
                    format(self.name))

    class Anonymous(AnonymousUser):
        name = u'Anonymous'

    login_manager = LoginManager()

    login_manager.anonymous_user = Anonymous
    login_manager.login_view = 'login'
    login_manager.login_message = u'Please log in to access this page.'
    login_manager.refresh_view = 'reauth'

    @login_manager.user_loader
    def load_user(uid):
        return APIUser.get(int(uid))
<commit_msg>fix. ensure that password passed to generate_password_hash is a string.<commit_after>"""
    This module defines utilizes the flask-login_ package to implement
    session management for the API.

    .. flask-login_: http://pythonhosted.org/Flask-Login/

"""

__author__ = {
    "ryan faulkner": "rfaulkner@wikimedia.org"
}
__date__ = "2013-03-21"
__license__ = "GPL (version 2 or later)"

from user_metrics.config import logging, settings
from user_metrics.metrics import query_mod

# API User Authentication
# #######################

# With the presence of flask.ext.login module
if settings.__flask_login_exists__:

    from werkzeug.security import generate_password_hash,\
        check_password_hash

    from flask.ext.login import LoginManager, current_user, UserMixin, \
        AnonymousUser, confirm_login

    class APIUser(UserMixin):
        """
            Extends USerMixin.  User class for flask-login.  Implements a way
            to add user credentials with _HMAC and salting.

            .. HMAC_: http://tinyurl.com/d8zbbem

        """
        def __init__(self, username, password, active=True):
            self.name = username
            self.active = active
            self.set_password(password)

        def is_active(self):
            return self.active

        @staticmethod
        def get(uid):
            """
                Used by ``load_user`` to retrieve user session info.
            """
            usr_ref = query_mod.get_api_user(uid)
            if usr_ref:
                try:
                    return APIUser(unicode(str(usr_ref[0])),
                                   int(usr_ref[1]))
                except (KeyError, ValueError):
                    logging.error(__name__ + ' :: Could not get API '
                                             'user info.')
                    return None
            else:
                return None

        def set_password(self, password):
            self.pw_hash = generate_password_hash(str(password))

        def check_password(self, password):
            return check_password_hash(self.pw_hash, password)

        def register_user(self):
            """ Writes the user credentials to the datastore. """
            # 1. Ensure that the user is unique
            # 2. Write the user / pass to the db
            if not query_mod.get_api_user(self.name, by_id=False):
                query_mod.insert_api_user(self.name, self.pw_hash)
                logging.debug(__name__ + ' :: Added user {0}'.
                    format(self.name))
            else:
                logging.error(__name__ + 'Could not add user {0}'.
                    format(self.name))

    class Anonymous(AnonymousUser):
        name = u'Anonymous'

    login_manager = LoginManager()

    login_manager.anonymous_user = Anonymous
    login_manager.login_view = 'login'
    login_manager.login_message = u'Please log in to access this page.'
    login_manager.refresh_view = 'reauth'

    @login_manager.user_loader
    def load_user(uid):
        return APIUser.get(int(uid))
<|endoftext|>


<commit_before>import datetime as dt

from south.db import db
from django.db import models
from comics.core.models import *

class Migration:
    def forwards(self, orm):
        # Adding field 'Release.fetched'
        db.add_column('comics_release', 'fetched', models.DateTimeField(auto_now_add=True, default=dt.datetime.now), keep_default=False)

    def backwards(self, orm):
        # Deleting field 'Release.fetched'
        db.delete_column('comics_release', 'fetched')

    models = {
        'core.comic': {
            'Meta': {'db_table': "'comics_comic'"},
            'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'language': ('django.db.models.fields.CharField', [], {'max_length': '2'}),
            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
            'number_of_sets': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
            'rights': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100', 'db_index': 'True'}),
            'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
            'url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
        },
        'core.image': {
            'Meta': {'db_table': "'comics_image'"},
            'checksum': ('django.db.models.fields.CharField', [], {'max_length': '64', 'db_index': 'True'}),
            'comic': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['core.Comic']"}),
            'fetched': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
            'file': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
            'height': ('django.db.models.fields.IntegerField', [], {}),
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'text': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
            'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
            'width': ('django.db.models.fields.IntegerField', [], {})
        },
        'core.release': {
            'Meta': {'db_table': "'comics_release'"},
            'comic': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['core.Comic']"}),
            'fetched': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'image': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'releases'", 'to': "orm['core.Image']"}),
            'pub_date': ('django.db.models.fields.DateField', [], {})
        }
    }

    complete_apps = ['core']
<commit_msg>Fix migration to work with sqlite3<commit_after>import datetime as dt

from south.db import db
from django.db import models
from comics.core.models import *

class Migration:
    def forwards(self, orm):
        # Adding field 'Release.fetched'
        db.add_column('comics_release', 'fetched', models.DateTimeField(auto_now_add=True, default=dt.datetime.now), keep_default=False)
        db._populate_current_structure('comics_release', force=True)

    def backwards(self, orm):
        # Deleting field 'Release.fetched'
        db.delete_column('comics_release', 'fetched')

    models = {
        'core.comic': {
            'Meta': {'db_table': "'comics_comic'"},
            'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'language': ('django.db.models.fields.CharField', [], {'max_length': '2'}),
            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
            'number_of_sets': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
            'rights': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100', 'db_index': 'True'}),
            'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
            'url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
        },
        'core.image': {
            'Meta': {'db_table': "'comics_image'"},
            'checksum': ('django.db.models.fields.CharField', [], {'max_length': '64', 'db_index': 'True'}),
            'comic': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['core.Comic']"}),
            'fetched': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
            'file': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
            'height': ('django.db.models.fields.IntegerField', [], {}),
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'text': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
            'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
            'width': ('django.db.models.fields.IntegerField', [], {})
        },
        'core.release': {
            'Meta': {'db_table': "'comics_release'"},
            'comic': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['core.Comic']"}),
            'fetched': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'image': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'releases'", 'to': "orm['core.Image']"}),
            'pub_date': ('django.db.models.fields.DateField', [], {})
        }
    }

    complete_apps = ['core']
<|endoftext|>


<commit_before>#!/usr/bin/env python
import argparse
from Bio import Entrez
from Bio import SeqIO
from Bio.SeqRecord import SeqRecord
from Bio import SeqFeature
from Bio.Seq import Seq
from Bio.Alphabet import IUPAC

# =====================================================
#  Takes input of list of NCBI record IDs to fetch.
#  Downloads these records and parses the CDSs out, putting
#  them into fasta files named by the annotations.
#
#  Matt Gitzendanner
#  University of Florida
#  12/17/14
#
# Version 1.2: 2/10/16
#   -Added option to include a certain number of base pairs upstream and downstream of the annotated gene.
#       Note that in this may include other annotated reagions.
# Version 1.1: 1/5/15
#	-Added handling of multiple sequences with the same annotation.
#		By default genes with the same name in a sample will have a _copy_# added to everything after the 1st copy.
#		Set to 1 to exclude subsequent copies from the results files. Only the first is reported.
#	-Added testing for different cases of gene names. Uses the first one
#		for all subsequent samples, so pick the first sample carefully.
#		e.g. if the first sample has ccmFC and others have ccmFc, they will
#		be added to the ccmFC file.
# =====================================================

#####################
# Options
#
# -i input file with list of NCBI record IDs.
# -e email address used for Entrez
# -n Name sample with description? Takes description field, removes spaces and adds to id field.
# -p parse orfs? Default= 0
# -d exclude duplicate copies? Default=0
# -f Include flanking region +/- # of bp. Default=0
#####################

parser = argparse.ArgumentParser()
parser.add_argument("-i", help="input file with GenBank accession IDs")
parser.add_argument("-e", help="email address")
parser.add_argument("-n", help="Name sample with description? Takes description field, removes spaces and adds to id field. Default= 1 (yes), use 0 for no.", default=1)
parser.add_argument("-p", help="Parse ORFS? Default=0 (no)", default=0)
parser.add_argument("-d", help="Exclude duplicate copies of genes? Default=0 (no)", default=0)
parser.add_argument("-f", help="Include flanking region +/- # of bp. Default=0", default=0)

args = parser.parse_args()

infile = args.i
Entrez.email = args.e
ORFS= args.p
AddDescription= int(args.n)
ExclDups= int(args.d)
Flanking= int(args.f)

# Function to get overlap in intervals. From: http://stackoverflow.com/questions/2953967/built-in-function-for-computing-overlap-in-python
def getOverlap(a, b):
	return max(0, min(a[1], b[1]) - max(a[0], b[0]))

def addDescriptionToName(id, description):
	description_bits=description.split()[0:2] #get 1st 2 words from description (Geneus and species)
	id= "_".join(description_bits) + "_" + id

	return id

try:
	IN=open(infile, 'r')
except IOError:
	print "Can't open file", infile

Gene_dict={} # Keep track of all the genes we've found. Keys are lowercase version,
			 #  values are the case as found in the first sample where the gene is found.

for Line in IN:
	Line.strip('\n')
	print "Getting %s" %(Line)
	GBSeq = Entrez.efetch(db="nucleotide", rettype="gb", retmode="text", id=Line) #Get the sequence

	for Sequence in SeqIO.parse(GBSeq, "gb"):			#Parse though each
		# Print some summary info about the sequence.
		print Sequence.id, Sequence.description[:50] + "..."
		print "Sequence length %i," % len(Sequence),
		print "%i features," % len(Sequence.features),
		print "from: %s" % Sequence.annotations["source"]

		print "Parsing CDSs...\n\n"

		Sample_gene_dict={} #Clear the dict for tracking genes found in each sample.
		# Look at the CDSs and extract them
		for Feature in Sequence.features:
			if Feature.type == 'CDS' :
				try:  # Most CDS have a gene annotation.
					Gene= Feature.qualifiers["gene"]
					Gene= str(Gene[0]) # Gene is actually a list, so convert to string

				except: # But if not, we need to handle them.
					try: # Many that are not annotated as gene are annotated with note
						Gene= Feature.qualifiers["note"]
						if type(Gene) is list:	#Some of these are lists, some are strings...
							Gene=str(Gene[0])
						Gene=Gene.replace("label: ","") #Clean up some where label: is part of the name.

					except: #If we still can't get it, put in unknown.
						Gene= "unknown"
						print "Error parsing gene from CDS: ", Feature

				Gene=Gene.replace(" ", "_") #Clean up the name, replacing any spaces with underscores.

				if Gene.lower() not in Gene_dict.keys():
					Gene_dict[Gene.lower()]=Gene		#if we haven't found this gene yet, add it ot the Gene_dict
														#with key as lowercase version and value as slightly cleaned up version we found.
				try:
					Sample_gene_dict[Gene.lower()] += 1 #Increment if we've already seen this gene in this sample.
				except KeyError:
					Sample_gene_dict[Gene.lower()] = 1 #If we haven't seen this gene in this sample yet, add it to the Sample_gene_dict

				if Gene[:3].lower() != "orf" or ORFS==1: #if the gene name starts with orf, skip it unless user has opted to parse them.
					GeneFile= Gene_dict[Gene.lower()] + '.fna' #Name files by CDS name using the case as found the first time the gene was found.

					GeneFileAA= Gene_dict[Gene.lower()] + '.faa' #Name files by CDS name--Also get the translation

					try:
						OUT=open(GeneFile, 'a')
					except IOError:
						print "Can't open file to append", GeneFile

					try:
						OUTAA=open(GeneFileAA, 'a')
					except IOError:
						print "Can't open file to append", GeneFileAA

					############
					# Manage getting flanking regions.
					############
					#print ("Feature location is: %s" %(Feature.location))

					Flanking_start=Feature.location.start.position - Flanking #Subtract from start
					if Flanking_start < 1:		#Handle going past the beginning of the sequence
						Flanking_start = 1

					Flanking_end=Feature.location.end.position + Flanking #Add to end
					if Flanking_end > len(Sequence):
						Flanking_end = len(Sequence)	#Handle going past the end of the Sequence

					Flanking_location= SeqFeature.FeatureLocation(Flanking_start, Flanking_end, Feature.location.strand)
					Feature.location = Flanking_location
					#print ("With flanking, feature location is: %s" %(Feature.location))

					try: del Add_to_name #Clear the Add_to_name variable
					except: pass

					# Check if the expanded Feature.location now includes another CDS
					for OtherGenes in Sequence.features:
						if OtherGenes.type == 'CDS' :
							try:  # Most CDS have a gene annotation.
								OtherGene= OtherGenes.qualifiers["gene"]
								OtherGene= str(OtherGene[0]) # Gene is actually a list, so convert to string
							except:
								pass

							if not Gene.lower() == OtherGene.lower():

								Overlap= getOverlap([Flanking_start, Flanking_end], [OtherGenes.location.start.position, OtherGenes.location.end.position])

								if Overlap > 0:
									#print ("Expanded flanking region for %s includes %s, adding to name of file" %(Gene.lower(), OtherGene))
									try: Add_to_name=Add_to_name + "_" + OtherGene.lower()
									except: Add_to_name= "_" + Gene + "_with_" + OtherGene.lower()

					#Report what genes were added to the resulting files by expanding the flanking region.
					try:
						print ("For gene %s, flanking region includes %s" %(Gene, Add_to_name))
					except:
						pass

					try:
						SeqNuc=Feature.extract(Sequence)		#Get the nucleotide sequence for the CDS
					except:
						print "Can't get sequence for ", Gene	#Handle problems.

					SeqAA=SeqRecord(Seq(Feature.qualifiers['translation'][0], IUPAC.protein), id=Sequence.id, description=Sequence.description)

					#For some reason many are returning Unknown IDs and Descriptions. Fix these.
					if SeqNuc.id == '<unknown id>':
						SeqNuc.id= Sequence.id
						SeqNuc.description = Sequence.description

					if Gene != "unknown" and (Sample_gene_dict[Gene.lower()] > 1 and ExclDups == 0):	#If there's multiple copies, and we want them reported (skip unknowns since they aren't likely the same gene

						#Add _copy_# to the end of the name
						SeqNuc.id = SeqNuc.id + "_copy_" + str(Sample_gene_dict[Gene.lower()])
						SeqAA.id = SeqAA.id	+ "_copy_" + str(Sample_gene_dict[Gene.lower()])

						SeqNuc.id= addDescriptionToName(SeqNuc.id, SeqNuc.description)
						SeqAA.id= addDescriptionToName(SeqAA.id, SeqAA.description)

						try:		#If we have added other regions vy including flanking region, add these to the name of the sequence so user knows.
									#Only do this for nuclear data as AA data is just the original gene.
							SeqNuc.id = SeqNuc.id + Add_to_name
						except: pass

						SeqIO.write(SeqNuc, OUT, "fasta")	# Write that to the file in fasta format.
						SeqIO.write(SeqAA, OUTAA, "fasta")

					elif Gene != "unknown" and (Sample_gene_dict[Gene.lower()] > 1 and ExclDups == 1):	#If there's multiple copies and we don't want them reported, let the user know.
						print "Copy %s of %s being excluded for %s" %(str(Sample_gene_dict[Gene.lower()]), Gene_dict[Gene.lower()], SeqNuc.id)

					else:

						SeqNuc.id= addDescriptionToName(SeqNuc.id, SeqNuc.description)
						SeqAA.id= addDescriptionToName(SeqAA.id, SeqAA.description)

						try:		#If we have added other regions vy including flanking region, add these to the name of the sequence so user knows.
									#Only do this for nuclear data as AA data is just the original gene.
							SeqNuc.id = SeqNuc.id + Add_to_name
						except: pass

						SeqIO.write(SeqNuc, OUT, "fasta")	# Write that to the file in fasta format.
						SeqIO.write(SeqAA, OUTAA, "fasta")
				else:
					print "Skipping ", Gene #Let the user know an orf was skipped.
<commit_msg>Reduce logging of unknown genes, still displays some info, but doesn't show whole gene and isn't notes as an error<commit_after>#!/usr/bin/env python
import argparse
from Bio import Entrez
from Bio import SeqIO
from Bio.SeqRecord import SeqRecord
from Bio import SeqFeature
from Bio.Seq import Seq
from Bio.Alphabet import IUPAC

# =====================================================
#  Takes input of list of NCBI record IDs to fetch.
#  Downloads these records and parses the CDSs out, putting
#  them into fasta files named by the annotations.
#
#  Matt Gitzendanner
#  University of Florida
#  12/17/14
#
# Version 1.2: 2/10/16
#   -Added option to include a certain number of base pairs upstream and downstream of the annotated gene.
#       Note that in this may include other annotated reagions.
# Version 1.1: 1/5/15
#	-Added handling of multiple sequences with the same annotation.
#		By default genes with the same name in a sample will have a _copy_# added to everything after the 1st copy.
#		Set to 1 to exclude subsequent copies from the results files. Only the first is reported.
#	-Added testing for different cases of gene names. Uses the first one
#		for all subsequent samples, so pick the first sample carefully.
#		e.g. if the first sample has ccmFC and others have ccmFc, they will
#		be added to the ccmFC file.
# =====================================================

#####################
# Options
#
# -i input file with list of NCBI record IDs.
# -e email address used for Entrez
# -n Name sample with description? Takes description field, removes spaces and adds to id field.
# -p parse orfs? Default= 0
# -d exclude duplicate copies? Default=0
# -f Include flanking region +/- # of bp. Default=0
#####################

parser = argparse.ArgumentParser()
parser.add_argument("-i", help="input file with GenBank accession IDs")
parser.add_argument("-e", help="email address")
parser.add_argument("-n", help="Name sample with description? Takes description field, removes spaces and adds to id field. Default= 1 (yes), use 0 for no.", default=1)
parser.add_argument("-p", help="Parse ORFS? Default=0 (no)", default=0)
parser.add_argument("-d", help="Exclude duplicate copies of genes? Default=0 (no)", default=0)
parser.add_argument("-f", help="Include flanking region +/- # of bp. Default=0", default=0)

args = parser.parse_args()

infile = args.i
Entrez.email = args.e
ORFS= args.p
AddDescription= int(args.n)
ExclDups= int(args.d)
Flanking= int(args.f)

# Function to get overlap in intervals. From: http://stackoverflow.com/questions/2953967/built-in-function-for-computing-overlap-in-python
def getOverlap(a, b):
	return max(0, min(a[1], b[1]) - max(a[0], b[0]))

def addDescriptionToName(id, description):
	description_bits=description.split()[0:2] #get 1st 2 words from description (Geneus and species)
	id= "_".join(description_bits) + "_" + id

	return id

try:
	IN=open(infile, 'r')
except IOError:
	print "Can't open file", infile

Gene_dict={} # Keep track of all the genes we've found. Keys are lowercase version,
			 #  values are the case as found in the first sample where the gene is found.

for Line in IN:
	Line.strip('\n')
	print "Getting %s" %(Line)
	GBSeq = Entrez.efetch(db="nucleotide", rettype="gb", retmode="text", id=Line) #Get the sequence

	for Sequence in SeqIO.parse(GBSeq, "gb"):			#Parse though each
		# Print some summary info about the sequence.
		print Sequence.id, Sequence.description[:50] + "..."
		print "Sequence length %i," % len(Sequence),
		print "%i features," % len(Sequence.features),
		print "from: %s" % Sequence.annotations["source"]

		print "Parsing CDSs...\n\n"

		Sample_gene_dict={} #Clear the dict for tracking genes found in each sample.
		# Look at the CDSs and extract them
		for Feature in Sequence.features:
			if Feature.type == 'CDS' :
				try:  # Most CDS have a gene annotation.
					Gene= Feature.qualifiers["gene"]
					Gene= str(Gene[0]) # Gene is actually a list, so convert to string

				except: # But if not, we need to handle them.
					try: # Many that are not annotated as gene are annotated with note
						Gene= Feature.qualifiers["note"]
						if type(Gene) is list:	#Some of these are lists, some are strings...
							Gene=str(Gene[0])
						Gene=Gene.replace("label: ","") #Clean up some where label: is part of the name.

					except: #If we still can't get it, put in unknown.
						Gene= "unknown"
						print "Unable to parse gene name from CDS, putting in unknown file."

				Gene=Gene.replace(" ", "_") #Clean up the name, replacing any spaces with underscores.

				if Gene.lower() not in Gene_dict.keys():
					Gene_dict[Gene.lower()]=Gene		#if we haven't found this gene yet, add it ot the Gene_dict
														#with key as lowercase version and value as slightly cleaned up version we found.
				try:
					Sample_gene_dict[Gene.lower()] += 1 #Increment if we've already seen this gene in this sample.
				except KeyError:
					Sample_gene_dict[Gene.lower()] = 1 #If we haven't seen this gene in this sample yet, add it to the Sample_gene_dict

				if Gene[:3].lower() != "orf" or ORFS==1: #if the gene name starts with orf, skip it unless user has opted to parse them.
					GeneFile= Gene_dict[Gene.lower()] + '.fna' #Name files by CDS name using the case as found the first time the gene was found.

					GeneFileAA= Gene_dict[Gene.lower()] + '.faa' #Name files by CDS name--Also get the translation

					try:
						OUT=open(GeneFile, 'a')
					except IOError:
						print "Can't open file to append", GeneFile

					try:
						OUTAA=open(GeneFileAA, 'a')
					except IOError:
						print "Can't open file to append", GeneFileAA

					############
					# Manage getting flanking regions.
					############
					#print ("Feature location is: %s" %(Feature.location))

					Flanking_start=Feature.location.start.position - Flanking #Subtract from start
					if Flanking_start < 1:		#Handle going past the beginning of the sequence
						Flanking_start = 1

					Flanking_end=Feature.location.end.position + Flanking #Add to end
					if Flanking_end > len(Sequence):
						Flanking_end = len(Sequence)	#Handle going past the end of the Sequence

					Flanking_location= SeqFeature.FeatureLocation(Flanking_start, Flanking_end, Feature.location.strand)
					Feature.location = Flanking_location
					#print ("With flanking, feature location is: %s" %(Feature.location))

					try: del Add_to_name #Clear the Add_to_name variable
					except: pass

					# Check if the expanded Feature.location now includes another CDS
					for OtherGenes in Sequence.features:
						if OtherGenes.type == 'CDS' :
							try:  # Most CDS have a gene annotation.
								OtherGene= OtherGenes.qualifiers["gene"]
								OtherGene= str(OtherGene[0]) # Gene is actually a list, so convert to string
							except:
								pass

							if not Gene.lower() == OtherGene.lower():

								Overlap= getOverlap([Flanking_start, Flanking_end], [OtherGenes.location.start.position, OtherGenes.location.end.position])

								if Overlap > 0:
									#print ("Expanded flanking region for %s includes %s, adding to name of file" %(Gene.lower(), OtherGene))
									try: Add_to_name=Add_to_name + "_" + OtherGene.lower()
									except: Add_to_name= "_" + Gene + "_with_" + OtherGene.lower()

					#Report what genes were added to the resulting files by expanding the flanking region.
					try:
						print ("For gene %s, flanking region includes %s" %(Gene, Add_to_name))
					except:
						pass

					try:
						SeqNuc=Feature.extract(Sequence)		#Get the nucleotide sequence for the CDS
					except:
						print "Can't get sequence for ", Gene	#Handle problems.

					SeqAA=SeqRecord(Seq(Feature.qualifiers['translation'][0], IUPAC.protein), id=Sequence.id, description=Sequence.description)

					#For some reason many are returning Unknown IDs and Descriptions. Fix these.
					if SeqNuc.id == '<unknown id>':
						SeqNuc.id= Sequence.id
						SeqNuc.description = Sequence.description

					if Gene != "unknown" and (Sample_gene_dict[Gene.lower()] > 1 and ExclDups == 0):	#If there's multiple copies, and we want them reported (skip unknowns since they aren't likely the same gene

						#Add _copy_# to the end of the name
						SeqNuc.id = SeqNuc.id + "_copy_" + str(Sample_gene_dict[Gene.lower()])
						SeqAA.id = SeqAA.id	+ "_copy_" + str(Sample_gene_dict[Gene.lower()])

						SeqNuc.id= addDescriptionToName(SeqNuc.id, SeqNuc.description)
						SeqAA.id= addDescriptionToName(SeqAA.id, SeqAA.description)

						try:		#If we have added other regions vy including flanking region, add these to the name of the sequence so user knows.
									#Only do this for nuclear data as AA data is just the original gene.
							SeqNuc.id = SeqNuc.id + Add_to_name
						except: pass

						SeqIO.write(SeqNuc, OUT, "fasta")	# Write that to the file in fasta format.
						SeqIO.write(SeqAA, OUTAA, "fasta")

					elif Gene != "unknown" and (Sample_gene_dict[Gene.lower()] > 1 and ExclDups == 1):	#If there's multiple copies and we don't want them reported, let the user know.
						print "Copy %s of %s being excluded for %s" %(str(Sample_gene_dict[Gene.lower()]), Gene_dict[Gene.lower()], SeqNuc.id)

					else:

						SeqNuc.id= addDescriptionToName(SeqNuc.id, SeqNuc.description)
						SeqAA.id= addDescriptionToName(SeqAA.id, SeqAA.description)

						try:		#If we have added other regions vy including flanking region, add these to the name of the sequence so user knows.
									#Only do this for nuclear data as AA data is just the original gene.
							SeqNuc.id = SeqNuc.id + Add_to_name
						except: pass

						SeqIO.write(SeqNuc, OUT, "fasta")	# Write that to the file in fasta format.
						SeqIO.write(SeqAA, OUTAA, "fasta")
				else:
					print "Skipping ", Gene #Let the user know an orf was skipped.
<|endoftext|>