<commit_before>import datetime
import logging
import random
from textwrap import dedent

from simple_settings import settings

from telegram.ext import Updater, CommandHandler, Job
import pytz
import emoji

import logging
logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')

DEFAULT_TZ = pytz.timezone(settings.DEFAULT_TIMEZONE)

def tznow(tz=None):
    utcnow = datetime.datetime.utcnow().replace(tzinfo=pytz.UTC)
    if tz is None:
        tz = DEFAULT_TZ
    else:
        tz = pytz.timezone(tz)
    return utcnow.astimezone(tz)

def get_days_left_in_summer(tz=None):
    tznow_date = tznow().date()
    first_day = datetime.date(tznow_date.year, 6, 1)
    last_day = datetime.date(tznow_date.year, 9, 1)
    if first_day <= tznow_date <= last_day:
        return (last_day - tznow_date).days
    else:
        return 0

RESPONSES = '''\
It is certain
It is decidedly so
Without a doubt
Yes definitely
You may rely on it
As I see it, yes
Most likely
Outlook good
Yes
Signs point to yes
Reply hazy try again
Ask again later
Better not tell you now
Cannot predict now
Concentrate and ask again
Don't count on it
My reply is no
My sources say no
Outlook not so good
Very doubtful
'''.split('\n')

def start(bot, update):
    bot.send_message(
        chat_id=update.message.chat_id,
        text=dedent("""\
                Yo yo yo!!! I am summer bot and I can:
                /summerdays - I will write to the chat how many days left
                /magicball - Ask me something
                """
            )
        )

def magic_8_ball(bot, update):
    answer = random.choice(RESPONSES)
    bot.send_message(
            chat_id=update.message.chat_id,
            reply_to_message_id=update.message.message_id,
            text='🎱 {}'.format(answer)
            )

def days_left(bot, update):
    days_left = get_days_left_in_summer()
    if days_left == 0:
        bot.send_message(
            chat_id=update.message.chat_id,
            text=(
                'лето кончилось :('
                )
            )
        return
    days_left_100 = days_left % 100
    days_left_10 = days_left % 10
    if (
            (days_left_100 < 10 or days_left_100 > 20) and
            1 <= days_left_10 < 5
             ):
        if days_left_10 == 1:
            days_text = '{}день'.format(days_left)
        else:
            days_text = '{}дня'.format(days_left)
    else:
        days_text = '{}дней'.format(days_left)
    bot.send_message(
        chat_id=update.message.chat_id,
        text=(
            '#ровноцелых{} 🌞'.format(days_text)
            )
        )

def callback_1900(bot, job):
    bot.send_message(
            chat_id=settings.SVOBODA_CHAT_ID,
            text='Го в Свобода'
            )
    next_run = 24 * 60 * 60
    logging.info("next run in {} seconds".format(next_run))
    job.interval = next_run

def main():
    updater = Updater(token=settings.API_KEY)
    dispatcher = updater.dispatcher
    jq = updater.job_queue

    start_handler = CommandHandler('start', start)
    dispatcher.add_handler(start_handler)

    days_handler = CommandHandler('summerdays', days_left)
    dispatcher.add_handler(days_handler)

    magic_ball_handler = CommandHandler('magicball', magic_8_ball)
    dispatcher.add_handler(magic_ball_handler)

    if settings.SVOBODA_CHAT_ID:
        moscow_now = tznow()
        cb_time = datetime.time(19, 0)
        if moscow_now.time() > cb_time:
            day = moscow_now.date() + datetime.timedelta(days=1)
        else:
            day = moscow_now.date()
        cb_dtime = DEFAULT_TZ.localize(datetime.datetime.combine(day, cb_time))
        delta = cb_dtime - moscow_now
        logging.info('Cb dtime {} now is {}'.format(cb_dtime, moscow_now))
        logging.info('Set job after {} seconds'.format(delta.total_seconds()))
        jq.put(Job(callback_1900, delta.total_seconds()))

    updater.start_polling()

if __name__ == '__main__':
    main()
<commit_msg>Add more magic answers<commit_after>import datetime
import logging
import random
from textwrap import dedent

from simple_settings import settings

from telegram.ext import Updater, CommandHandler, Job
import pytz
import emoji

import logging
logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')

DEFAULT_TZ = pytz.timezone(settings.DEFAULT_TIMEZONE)

def tznow(tz=None):
    utcnow = datetime.datetime.utcnow().replace(tzinfo=pytz.UTC)
    if tz is None:
        tz = DEFAULT_TZ
    else:
        tz = pytz.timezone(tz)
    return utcnow.astimezone(tz)

def get_days_left_in_summer(tz=None):
    tznow_date = tznow().date()
    first_day = datetime.date(tznow_date.year, 6, 1)
    last_day = datetime.date(tznow_date.year, 9, 1)
    if first_day <= tznow_date <= last_day:
        return (last_day - tznow_date).days
    else:
        return 0

RESPONSES_EN = '''\
It is certain
It is decidedly so
Without a doubt
Yes definitely
You may rely on it
As I see it, yes
Most likely
Outlook good
Yes
Signs point to yes
Reply hazy try again
Ask again later
Better not tell you now
Cannot predict now
Concentrate and ask again
Don't count on it
My reply is no
My sources say no
Outlook not so good
Very doubtful\
'''.split('\n')

RESPONSES_ES = '''\
En mi opinión, sí
Es cierto
Es decididamente así
Probablemente
Buen pronóstico
Todo apunta a que sí
Sin duda
Sí
Sí - definitivamente
Debes confiar en ello
Respuesta vaga, vuelve a intentarlo
Pregunta en otro momento
Será mejor que no te lo diga ahora
No puedo predecirlo ahora
Concéntrate y vuelve a preguntar
No cuentes con ello
Mi respuesta es no
Mis fuentes me dicen que no
Las perspectivas no son buenas
Muy dudoso\
'''.split('\n')
RESPONSES_DE = '''\
'''.split('\n')

RESPONSES_RU = '''\
Бесспорно
Предрешено
Никаких сомнений
Определённо да
Можешь быть уверен в этом
Мне кажется — «да»
Вероятнее всего
Хорошие перспективы
Знаки говорят — «да»
Да
Пока не ясно, попробуй снова
Спроси позже
Лучше не рассказывать
Сейчас нельзя предсказать
Сконцентрируйся и спроси опять
Даже не думай
Мой ответ — «нет»
По моим данным — «нет»
Перспективы не очень хорошие
Весьма сомнительно\
'''.split('\n')
RESPONSES_MAX='иди на хуй'.split('\n')

def start(bot, update):
    bot.send_message(
        chat_id=update.message.chat_id,
        text=dedent("""\
                Yo yo yo!!! I am summer bot and I can:
                /summerdays - I will write to the chat how many days left
                /magicball - спроси меня
                /magicballen - ask me
                /magicballmax - спроси Макса
                /magicballes - pregunta a mí
                /magicballru - спроси меня
                """
            )
        )

def magic_8_ball(responses):
    def f(bot, update):
        answer = random.choice(responses)
        bot.send_message(
                chat_id=update.message.chat_id,
                reply_to_message_id=update.message.message_id,
                text='🎱 {}'.format(answer)
                )
    return f

def days_left(bot, update):
    days_left = get_days_left_in_summer()
    if days_left == 0:
        bot.send_message(
            chat_id=update.message.chat_id,
            text=(
                'лето кончилось :('
                )
            )
        return
    days_left_100 = days_left % 100
    days_left_10 = days_left % 10
    if (
            (days_left_100 < 10 or days_left_100 > 20) and
            1 <= days_left_10 < 5
             ):
        if days_left_10 == 1:
            days_text = '{}день'.format(days_left)
        else:
            days_text = '{}дня'.format(days_left)
    else:
        days_text = '{}дней'.format(days_left)
    bot.send_message(
        chat_id=update.message.chat_id,
        text=(
            '#ровноцелых{} 🌞'.format(days_text)
            )
        )

def callback_1900(bot, job):
    bot.send_message(
            chat_id=settings.SVOBODA_CHAT_ID,
            text='Го в Свобода'
            )
    next_run = 24 * 60 * 60
    logging.info("next run in {} seconds".format(next_run))
    job.interval = next_run

def main():
    updater = Updater(token=settings.API_KEY)
    dispatcher = updater.dispatcher
    jq = updater.job_queue

    start_handler = CommandHandler('start', start)
    dispatcher.add_handler(start_handler)

    days_handler = CommandHandler('summerdays', days_left)
    dispatcher.add_handler(days_handler)

    for postfix, responses in (
            ('en', RESPONSES_EN),
            ('es', RESPONSES_ES),
            ('ru', RESPONSES_RU),
            ('max', RESPONSES_MAX)
            ):
        dispatcher.add_handler(CommandHandler(
                'magicball{}'.format(postfix),
                magic_8_ball(responses)
                ))
    dispatcher.add_handler(CommandHandler(
            'magicball',
            magic_8_ball(RESPONSES_RU)
            ))

    if settings.SVOBODA_CHAT_ID:
        moscow_now = tznow()
        cb_time = datetime.time(19, 0)
        if moscow_now.time() > cb_time:
            day = moscow_now.date() + datetime.timedelta(days=1)
        else:
            day = moscow_now.date()
        cb_dtime = DEFAULT_TZ.localize(datetime.datetime.combine(day, cb_time))
        delta = cb_dtime - moscow_now
        logging.info('Cb dtime {} now is {}'.format(cb_dtime, moscow_now))
        logging.info('Set job after {} seconds'.format(delta.total_seconds()))
        jq.put(Job(callback_1900, delta.total_seconds()))

    updater.start_polling()

if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before>from itertools import chain
from collections import Counter
from typing import List, Iterable, Tuple, Mapping

from common.models.task import TaskStruct
from util.config import Config, ConfigField, create_dict_field_type, create_list_field_type, StrListConfigField

class UnknownTasksInDeps(Exception):
    def __init__(self, tasks: 'Iterable[str]'):
        self.tasks = tasks

    def __str__(self):
        return 'Unknown tasks found in deps graph: {}'.format(', '.join(self.tasks))

class DuplicateTasksFound(Exception):
    def __init__(self, task_dups: 'Iterable[Tuple[str, int]]'):
        self.task_dups = task_dups

    def __str__(self):
        return 'Duplicate tasks found in graph: {}'.format(', '.join(k for k, v in self.task_dups))

class UnknownClusters(Exception):
    def __init__(self, clusters: 'Iterable[str]'):
        self.clusters = clusters

    def __str__(self):
        return 'Unknown clusters mentioned: {}'.format(', '.join(self.clusters))

class ExtendedTaskStruct(Config):
    task_name = ConfigField(type=str, required=True, default=None)
    task = TaskStruct()
    hosts = StrListConfigField()

class ExtendedTaskList(create_list_field_type(ExtendedTaskStruct)):
    def __init__(self, clusters: 'Mapping[str, List[str]]'):
        self.clusters = clusters

    def verify(self, path_to_node: str = ''):
        if not path_to_node:
            path_to_node = '{}.'.format(self.__class__.__name__, self._type_fabric.__class__.__name__)
        super().verify(path_to_node)
        assert all(isinstance(_, ExtendedTaskStruct) for _ in self)
        dups = [(k, v) for k, v in Counter(_.task.task_id for _ in self).items() if v > 1]
        if dups:
            raise DuplicateTasksFound(dups)
        needed_clusters = set(chain.from_iterable(_.hosts for _ in self))
        not_found_clusters = needed_clusters - set(self.clusters.keys())
        if not_found_clusters:
            raise UnknownClusters(not_found_clusters)

class TaskDependencies(create_dict_field_type(StrListConfigField)):
    def __init__(self, tasks: 'List[ExtendedTaskStruct]'):
        self.tasks = tasks

    def verify(self, path_to_node: str = ''):
        if not path_to_node:
            path_to_node = '{}.'.format(self.__class__.__name__, self._type_fabric.__class__.__name__)
        super().verify(path_to_node)
        value_tasks = set(chain.from_iterable(self.values()))
        key_tasks = set(self.keys())
        all_tasks = set(_.task_name for _ in self.tasks)
        not_found_tasks = (key_tasks - all_tasks) + (value_tasks - all_tasks)
        if not_found_tasks:
            raise UnknownTasksInDeps(not_found_tasks)

class GraphStruct(Config):
    graph_name = ConfigField(type=str, required=True, default='graph00')
    revision = ConfigField(type=int, required=True, default=0)

    clusters = create_dict_field_type(StrListConfigField)
    tasks = ExtendedTaskList(clusters)
    deps = TaskDependencies(tasks)

class GraphInstanceInfo(Config):
    instance_id = ConfigField(type=str, required=True, default=None)
    structure = GraphStruct()

    def __init__(self, instance_id: str, graph_structure: GraphStruct):
        super().__init__()
        self.instance_id = instance_id
        self.structure = graph_structure
<commit_msg>Fix of models usage.<commit_after>from itertools import chain
from collections import Counter
from typing import List, Iterable, Tuple, Mapping

from common.models.task import TaskStruct
from util.config import Config, ConfigField, create_dict_field_type, create_list_field_type, StrListConfigField

class UnknownTasksInDeps(Exception):
    def __init__(self, tasks: 'Iterable[str]'):
        self.tasks = tasks

    def __str__(self):
        return 'Unknown tasks found in deps graph: {}'.format(', '.join(self.tasks))

class DuplicateTasksFound(Exception):
    def __init__(self, task_dups: 'Iterable[Tuple[str, int]]'):
        self.task_dups = task_dups

    def __str__(self):
        return 'Duplicate tasks found in graph: {}'.format(', '.join(k for k, v in self.task_dups))

class UnknownClusters(Exception):
    def __init__(self, clusters: 'Iterable[str]'):
        self.clusters = clusters

    def __str__(self):
        return 'Unknown clusters mentioned: {}'.format(', '.join(self.clusters))

class ExtendedTaskStruct(Config):
    task_name = ConfigField(type=str, required=True, default=None)
    task = TaskStruct()
    hosts = StrListConfigField()

class ExtendedTaskList(create_list_field_type(ExtendedTaskStruct)):
    def __init__(self, clusters: 'Mapping[str, List[str]]'):
        self.clusters = clusters

    def verify(self, path_to_node: str = ''):
        if not path_to_node:
            path_to_node = '{}.'.format(self.__class__.__name__, self._type_fabric.__class__.__name__)
        super().verify(path_to_node)
        assert all(isinstance(_, ExtendedTaskStruct) for _ in self)
        dups = [(k, v) for k, v in Counter(_.task_name for _ in self).items() if v > 1]
        if dups:
            raise DuplicateTasksFound(dups)
        needed_clusters = set(chain.from_iterable(_.hosts for _ in self))
        not_found_clusters = needed_clusters - set(self.clusters.keys())
        if not_found_clusters:
            raise UnknownClusters(not_found_clusters)

class TaskDependencies(create_dict_field_type(StrListConfigField)):
    def __init__(self, tasks: 'List[ExtendedTaskStruct]'):
        self.tasks = tasks

    def verify(self, path_to_node: str = ''):
        if not path_to_node:
            path_to_node = '{}.'.format(self.__class__.__name__, self._type_fabric.__class__.__name__)
        super().verify(path_to_node)
        value_tasks = set(chain.from_iterable(self.values()))
        key_tasks = set(self.keys())
        all_tasks = set(_.task_name for _ in self.tasks)
        not_found_tasks = key_tasks - all_tasks
        not_found_tasks.update(value_tasks - all_tasks)
        if not_found_tasks:
            raise UnknownTasksInDeps(not_found_tasks)

class GraphStruct(Config):
    graph_name = ConfigField(type=str, required=True, default='graph00')
    revision = ConfigField(type=int, required=True, default=0)

    clusters = create_dict_field_type(StrListConfigField)()
    tasks = ExtendedTaskList(clusters)
    deps = TaskDependencies(tasks)

class GraphInstanceInfo(Config):
    instance_id = ConfigField(type=str, required=True, default=None)
    structure = GraphStruct()

    def __init__(self, instance_id: str, graph_structure: GraphStruct):
        super().__init__()
        self.instance_id = instance_id
        self.structure = graph_structure
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
###############################################################################
#
#  $Id$
#  Project:  RX Cadre Data Visualization
#  Purpose:  Simple tk GUI.
#  Author:   Kyle Shannon <kyle at pobox dot com>
#
###############################################################################
#
#  This is free and unencumbered software released into the public domain.
#
#  Anyone is free to copy, modify, publish, use, compile, sell, or
#  distribute this software, either in source code form or as a compiled
#  binary, for any purpose, commercial or non-commercial, and by any
#  means.
#
#  In jurisdictions that recognize copyright laws, the author or authors
#  of this software dedicate any and all copyright interest in the
#  software to the public domain. We make this dedication for the benefit
#  of the public at large and to the detriment of our heirs and
#  successors. We intend this dedication to be an overt act of
#  relinquishment in perpetuity of all present and future rights to this
#  software under copyright law.
#
#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
#  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
#  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
#  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
#  OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
#  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
#  OTHER DEALINGS IN THE SOFTWARE.
#
#  For more information, please refer to <http://unlicense.org/>
#
###############################################################################

from Tkinter import *
from tkFileDialog import askopenfilename, asksaveasfilename, askdirectory
import tkMessageBox

from rxcadre import RxCadre
from rxcadre_except import RxCadreError

HAVE_OGR = True
try:
    from osgeo import ogr
except ImportError:
    HAVE_OGR = False

class RxCadreTk(Frame):

    def messagebox(self, message, btype='warning'):
        bt_dict = {'info':tkMessageBox.showinfo,
                   'warning':tkMessageBox.showwarning}
        if not message:
            return
        try:
            bt_dict[btype]('RxCadre', message)
        except:
            pass
        return

    def update_listboxes(self):
        event_data = self.cadre.get_event_data()
        if not event_data:
            self.messagebox('There are no events associated with this db')
            return
        for event in event_data.keys():
            self.event_listbox.insert(END, event)
        plot_data = self.cadre.get_plot_data()
        for plot in plot_data:
            self.plot_listbox.insert(END, plot[0])

    def connect_db(self):

        self.plot_listbox.delete(0, END)
        self.event_listbox.delete(0, END)
        fname = askopenfilename(filetypes=(('SQLite files', '*.db *.sqlite'),
                                           ('All files', '*.*')),
                                initialdir='../data')
        if not fname:
            return
        try:
            self.cadre = RxCadre(fname)
        except RxCadreError as e:
            print(e)
        self.update_listboxes()

    def create_db(self):

        fname = asksaveasfilename(filetypes=(('SQLite files', '*.db *.sqlite'),))
        if not fname:
            return
        self.cadre.init_new_db(fname)
        self.cadre = RxCadre(fname)

    def import_db(self):

        fname = askopenfilename(filetypes=(('CSV files', '*.txt *.csv'),),
                                initialdir='../data')
        if not fname:
            return
        try:
            self.cadre.import_wind_data(fname, volatile=True)
        except RxCadreError as e:
            messagebox(e)
        self.cadre_thread.join()
        self.update_listboxes()

    def read_sql_file(self):

        fname = askopenfilename(filetypes=(('SQL files', '*.sql *.txt'),))
        if not fname:
            return
        self.cadre.read_sql(fname)
        self.update_listboxes()

    def load_event_data(self):
        '''
        Load pertinent information from a specific event

        This is primarily the date and time, although we do filter the plot
        list based on name (currently the start of plots is the event name).
        This should possibly be made optional.
        '''
        if not self.cadre:
            return
        event = self.event_listbox.get(ACTIVE)
        if not event:
            return
        data = self.cadre.get_event_data(event)
        start, end = data.items()[0][1]
        self.event_start_entry.delete(0, END)
        self.event_start_entry.insert(0, start)
        self.event_end_entry.delete(0, END)
        self.event_end_entry.insert(0, end)
        if self.filter_plots:
            plots = self.cadre.get_plot_data()
            self.plot_listbox.delete(0, END)
            for plot in plots:
                if plot[0].startswith(event):
                    self.plot_listbox.insert(END, plot[0])

    def create_ts_image(self):
        '''
        Read the plot id and start/stop time from the GUI and create an image.
        '''
        if not self.cadre:
            return
        items = map(int, self.plot_listbox.curselection())
        data = self.plot_listbox.get(0, END)
        plots = [data[int(item)] for item in items]
        start = self.event_start_entry.get()
        end = self.event_end_entry.get()
        if not plots:# or not start or not end:
            return
        pname = askdirectory(initialdir='.')
        if not pname:
            return
        gmax = float(self.gmax_spinbox.get())
        self.cadre.create_time_series_image(plots, 'TEST', start, end, pname, gmax)

    def create_wr_image(self):
        '''
        Read the plot id and start/stop time from the GUI and create an image.
        '''
        if not self.cadre:
            return
        items = map(int, self.plot_listbox.curselection())
        data = self.plot_listbox.get(0, END)
        plots = [data[int(item)] for item in items]
        start = self.event_start_entry.get()
        end = self.event_end_entry.get()
        if not plots or not start or not end:
            return
        pname = askdirectory(initialdir='.')
        if not pname:
            return
        self.cadre.create_windrose_image(plots, 'TEST', start, end, pname)

    def export_ogr(self):
        '''
        Export to an OGR datasource.
        '''

        if not self.cadre or not HAVE_OGR:
            return
        items = map(int, self.plot_listbox.curselection())
        data = self.plot_listbox.get(0, END)
        plots = [data[int(item)] for item in items]
        start = self.event_start_entry.get()
        end = self.event_end_entry.get()
        if not plots or not start or not end:
            return
        fname = asksaveasfilename(filetypes=(('ESRI Shapefile', '*.shp'),),
                                  initialdir='.')
        if not fname:
            return
        self.cadre.export_ogr(plots, start, end, fname, 'ESRI Shapefile',
                              self.summary_only)

    def export_csv(self):

        if not self.cadre:
            return
        items = map(int, self.plot_listbox.curselection())
        data = self.plot_listbox.get(0, END)
        plots = [data[int(item)] for item in items]
        start = self.event_start_entry.get()
        end = self.event_end_entry.get()
        if not plots or not start or not end:
            return
        pname = askdirectory(initialdir='.')
        if not pname:
            return
        self.cadre.export_csv(plots, start, end, pname)

    def export_kmz(self):

        if not self.cadre:
            return
        items = map(int, self.plot_listbox.curselection())
        data = self.plot_listbox.get(0, END)
        plots = [data[int(item)] for item in items]
        start = self.event_start_entry.get()
        end = self.event_end_entry.get()
        if not plots or not start or not end:
            return
        fname = asksaveasfilename(filetypes=(('Google Earth', '*.kmz'),),
                                  initialdir='.')
        if not fname:
            return
        self.cadre.export_kmz(plots, start, end, fname)
        return 1

    def create_menus(self):
        self.menubar = Menu(self)
        self.filemenu = Menu(self.menubar, tearoff=0)
        self.filemenu.add_command(label="Connect", command=self.connect_db)
        self.filemenu.add_command(label="Create", command=self.create_db)
        self.filemenu.add_command(label="Read sql", command=self.read_sql_file)
        #self.filemenu.add_command(label="Add 'ALL' event", command=self.add_all)
        self.filemenu.add_command(label="Import wind data", command=self.import_db)
        self.filemenu.add_separator()
        self.filemenu.add_command(label="Exit", command=self.quit)
        self.menubar.add_cascade(label="File", menu=self.filemenu)
        self.master.config(menu=self.menubar)

    def create_plot_listbox(self):
        self.plot_label = Label(self.plot_frame, text="Plot id:")
        self.plot_label.pack(side=TOP)
        self.plot_name = StringVar(self)
        self.plot_scrollbar = Scrollbar(self.plot_frame, orient=VERTICAL)
        self.plot_listbox = Listbox(self.plot_frame,
                                    yscrollcommand=self.plot_scrollbar.set,
                                    selectmode=EXTENDED)
        self.plot_scrollbar.config(command=self.plot_listbox.yview)
        self.plot_scrollbar.pack(side=RIGHT, fill=Y)
        self.plot_listbox.pack(side=LEFT, fill=BOTH, expand=1)

    def create_event_listbox(self):

        self.event_label = Label(self.event_frame, text="Event:")
        self.event_label.pack(side=TOP)
        self.event_name = StringVar(self)
        self.event_scrollbar = Scrollbar(self.event_frame, orient=VERTICAL)
        self.event_listbox = Listbox(self.event_frame,
                                     yscrollcommand=self.event_scrollbar.set,
                                     selectmode=BROWSE)
        self.event_scrollbar.config(command=self.event_listbox.yview)
        self.event_scrollbar.pack(side=RIGHT, fill=Y)
        self.event_listbox.pack(side=LEFT, fill=BOTH, expand=1)

    def create_event_time_entries(self):

        self.event_start_label = Label(self.event_time_frame, text='Start Time:')
        self.event_start_label.pack()
        self.event_start_entry = Entry(self.event_time_frame)
        self.event_start_entry.pack()
        self.event_end_label = Label(self.event_time_frame, text='End Time:')
        self.event_end_label.pack()
        self.event_end_entry = Entry(self.event_time_frame)
        self.event_end_entry.pack()
        self.event_query_button = Button(self.event_time_frame,
                                         text='Load Event',
                                         command=self.load_event_data)
        self.event_query_button.pack()

    def set_filter(self):
        '''
        Hack for 'broken' check box
        '''
        if self.filter_plots == 0:
            self.filter_plots = 1
        else:
            self.filter_plots = 0

    def set_summary(self):
        '''
        Hack for 'broken' check box
        '''
        if self.summary_only == 0:
            self.summary_only = 1
        else:
            self.summary_only = 0

    def set_gmax(self):
        if self.use_gmax == 0:
            self.use_gmax = 1
        else:
            self.use_gmax = 0

    def create_checkboxes(self):
        '''
        Create various checkboxes for output options.
        '''
        self.plot_checkbox = Checkbutton(self.event_time_frame,
                                         text="Filter Plots by Event",
                                         variable=self.filter_plots,
                                         command=self.set_filter)
        self.plot_checkbox.pack(side=BOTTOM)
        self.plot_checkbox.toggle()
        self.filter_plots = 1
        self.summary_checkbox = Checkbutton(self.event_time_frame,
                                            text="Summarize data",
                                            variable=self.summary_only,
                                            command=self.set_summary)
        self.summary_checkbox.pack(side=BOTTOM)
        self.summary_checkbox.toggle()
        self.summary_only = 1

    def create_gmax_spinbox(self):

        self.gmax_label = Label(self.event_time_frame, text='Y maximum:')
        self.gmax_label.pack()
        self.gmax_spinbox = Spinbox(self.event_time_frame, from_=0, to_=100)
        self.gmax_spinbox.pack()

    def create_out_buttons(self):
        '''
        Create a button that creates a time series image.
        '''
        self.ts_button = Button(self.ts_frame, text='Create Time Series',
                                command=self.create_ts_image)
        self.ts_button.pack()
        self.wr_button = Button(self.ts_frame, text='Create Wind Rose',
                                command=self.create_wr_image)
        self.wr_button.pack()

        if HAVE_OGR:
            self.ogr_button = Button(self.ts_frame, text='Export to OGR',
                                     command=self.export_ogr)
            self.ogr_button.pack()

        self.csv_button = Button(self.ts_frame, text='Export to CSV',
                                 command=self.export_csv)
        self.csv_button.pack()
        self.kmz_button = Button(self.ts_frame, text='Export to KMZ',
                                 command=self.export_kmz)
        self.kmz_button.pack()

    def create(self):
        '''
        Build and pack the entire tk GUI.
        '''

        # Variables
        self.filter_plots = 0
        self.summary_only = 1

        # Menu bar
        self.create_menus()

        # Plot data
        self.plot_frame = Frame(self)

        # Event data
        self.event_frame = Frame(self)
        self.create_plot_listbox()
        self.event_frame.pack(side=LEFT)
        self.create_event_listbox()
        self.event_time_frame = Frame(self)
        self.event_time_frame.pack(side=LEFT)
        self.create_event_time_entries()

        # Pack the plot frame
        self.plot_frame.pack(side=LEFT)

        # Checkable options
        self.create_checkboxes()
        # Global max.
        self.create_gmax_spinbox()

        # Timeseries Image
        self.ts_frame = Frame(self)
        self.ts_frame.pack()
        self.create_out_buttons()

    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.cadre = RxCadre()
        self.pack()
        self.create()

def _quit():
    root.quit()
    root.destroy()

root = Tk()
root.protocol("WM_DELETE_WINDOW", _quit)
app = RxCadreTk(master=root)
app.mainloop()

<commit_msg>fix plot filter<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
###############################################################################
#
#  $Id$
#  Project:  RX Cadre Data Visualization
#  Purpose:  Simple tk GUI.
#  Author:   Kyle Shannon <kyle at pobox dot com>
#
###############################################################################
#
#  This is free and unencumbered software released into the public domain.
#
#  Anyone is free to copy, modify, publish, use, compile, sell, or
#  distribute this software, either in source code form or as a compiled
#  binary, for any purpose, commercial or non-commercial, and by any
#  means.
#
#  In jurisdictions that recognize copyright laws, the author or authors
#  of this software dedicate any and all copyright interest in the
#  software to the public domain. We make this dedication for the benefit
#  of the public at large and to the detriment of our heirs and
#  successors. We intend this dedication to be an overt act of
#  relinquishment in perpetuity of all present and future rights to this
#  software under copyright law.
#
#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
#  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
#  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
#  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
#  OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
#  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
#  OTHER DEALINGS IN THE SOFTWARE.
#
#  For more information, please refer to <http://unlicense.org/>
#
###############################################################################

from Tkinter import *
from tkFileDialog import askopenfilename, asksaveasfilename, askdirectory
import tkMessageBox

from rxcadre import RxCadre
from rxcadre_except import RxCadreError

HAVE_OGR = True
try:
    from osgeo import ogr
except ImportError:
    HAVE_OGR = False

class RxCadreTk(Frame):

    def messagebox(self, message, btype='warning'):
        bt_dict = {'info':tkMessageBox.showinfo,
                   'warning':tkMessageBox.showwarning}
        if not message:
            return
        try:
            bt_dict[btype]('RxCadre', message)
        except:
            pass
        return

    def update_listboxes(self):
        event_data = self.cadre.get_event_data()
        if not event_data:
            self.messagebox('There are no events associated with this db')
            return
        for event in event_data.keys():
            self.event_listbox.insert(END, event)
        plot_data = self.cadre.get_plot_data()
        for plot in plot_data:
            self.plot_listbox.insert(END, plot[0])

    def connect_db(self):

        self.plot_listbox.delete(0, END)
        self.event_listbox.delete(0, END)
        fname = askopenfilename(filetypes=(('SQLite files', '*.db *.sqlite'),
                                           ('All files', '*.*')),
                                initialdir='../data')
        if not fname:
            return
        try:
            self.cadre = RxCadre(fname)
        except RxCadreError as e:
            print(e)
        self.update_listboxes()

    def create_db(self):

        fname = asksaveasfilename(filetypes=(('SQLite files', '*.db *.sqlite'),))
        if not fname:
            return
        self.cadre.init_new_db(fname)
        self.cadre = RxCadre(fname)

    def import_db(self):

        fname = askopenfilename(filetypes=(('CSV files', '*.txt *.csv'),),
                                initialdir='../data')
        if not fname:
            return
        try:
            self.cadre.import_wind_data(fname, volatile=True)
        except RxCadreError as e:
            messagebox(e)
        self.cadre_thread.join()
        self.update_listboxes()

    def read_sql_file(self):

        fname = askopenfilename(filetypes=(('SQL files', '*.sql *.txt'),))
        if not fname:
            return
        self.cadre.read_sql(fname)
        self.update_listboxes()

    def load_event_data(self):
        '''
        Load pertinent information from a specific event

        This is primarily the date and time, although we do filter the plot
        list based on name (currently the start of plots is the event name).
        This should possibly be made optional.
        '''
        if not self.cadre:
            return
        event = self.event_listbox.get(ACTIVE)
        if not event:
            return
        data = self.cadre.get_event_data(event)
        start, end = data.items()[0][1]
        self.event_start_entry.delete(0, END)
        self.event_start_entry.insert(0, start)
        self.event_end_entry.delete(0, END)
        self.event_end_entry.insert(0, end)
        if self.filter_plots:
            plots = self.cadre.get_plot_data()
            self.plot_listbox.delete(0, END)
            for plot in plots:
                if plot[0].startswith(event):
                    self.plot_listbox.insert(END, plot[0])
        else:
            plots = self.cadre.get_plot_data()
            self.plot_listbox.delete(0, END)
            for plot in plots:
                self.plot_listbox.insert(END, plot[0])

    def create_ts_image(self):
        '''
        Read the plot id and start/stop time from the GUI and create an image.
        '''
        if not self.cadre:
            return
        items = map(int, self.plot_listbox.curselection())
        data = self.plot_listbox.get(0, END)
        plots = [data[int(item)] for item in items]
        start = self.event_start_entry.get()
        end = self.event_end_entry.get()
        if not plots:# or not start or not end:
            return
        pname = askdirectory(initialdir='.')
        if not pname:
            return
        gmax = float(self.gmax_spinbox.get())
        self.cadre.create_time_series_image(plots, 'TEST', start, end, pname, gmax)

    def create_wr_image(self):
        '''
        Read the plot id and start/stop time from the GUI and create an image.
        '''
        if not self.cadre:
            return
        items = map(int, self.plot_listbox.curselection())
        data = self.plot_listbox.get(0, END)
        plots = [data[int(item)] for item in items]
        start = self.event_start_entry.get()
        end = self.event_end_entry.get()
        if not plots or not start or not end:
            return
        pname = askdirectory(initialdir='.')
        if not pname:
            return
        self.cadre.create_windrose_image(plots, 'TEST', start, end, pname)

    def export_ogr(self):
        '''
        Export to an OGR datasource.
        '''

        if not self.cadre or not HAVE_OGR:
            return
        items = map(int, self.plot_listbox.curselection())
        data = self.plot_listbox.get(0, END)
        plots = [data[int(item)] for item in items]
        start = self.event_start_entry.get()
        end = self.event_end_entry.get()
        if not plots or not start or not end:
            return
        fname = asksaveasfilename(filetypes=(('ESRI Shapefile', '*.shp'),),
                                  initialdir='.')
        if not fname:
            return
        self.cadre.export_ogr(plots, start, end, fname, 'ESRI Shapefile',
                              self.summary_only)

    def export_csv(self):

        if not self.cadre:
            return
        items = map(int, self.plot_listbox.curselection())
        data = self.plot_listbox.get(0, END)
        plots = [data[int(item)] for item in items]
        start = self.event_start_entry.get()
        end = self.event_end_entry.get()
        if not plots or not start or not end:
            return
        pname = askdirectory(initialdir='.')
        if not pname:
            return
        self.cadre.export_csv(plots, start, end, pname)

    def export_kmz(self):

        if not self.cadre:
            return
        items = map(int, self.plot_listbox.curselection())
        data = self.plot_listbox.get(0, END)
        plots = [data[int(item)] for item in items]
        start = self.event_start_entry.get()
        end = self.event_end_entry.get()
        if not plots or not start or not end:
            return
        fname = asksaveasfilename(filetypes=(('Google Earth', '*.kmz'),),
                                  initialdir='.')
        if not fname:
            return
        self.cadre.export_kmz(plots, start, end, fname)
        return 1

    def create_menus(self):
        self.menubar = Menu(self)
        self.filemenu = Menu(self.menubar, tearoff=0)
        self.filemenu.add_command(label="Connect", command=self.connect_db)
        self.filemenu.add_command(label="Create", command=self.create_db)
        self.filemenu.add_command(label="Read sql", command=self.read_sql_file)
        #self.filemenu.add_command(label="Add 'ALL' event", command=self.add_all)
        self.filemenu.add_command(label="Import wind data", command=self.import_db)
        self.filemenu.add_separator()
        self.filemenu.add_command(label="Exit", command=self.quit)
        self.menubar.add_cascade(label="File", menu=self.filemenu)
        self.master.config(menu=self.menubar)

    def create_plot_listbox(self):
        self.plot_label = Label(self.plot_frame, text="Plot id:")
        self.plot_label.pack(side=TOP)
        self.plot_name = StringVar(self)
        self.plot_scrollbar = Scrollbar(self.plot_frame, orient=VERTICAL)
        self.plot_listbox = Listbox(self.plot_frame,
                                    yscrollcommand=self.plot_scrollbar.set,
                                    selectmode=EXTENDED)
        self.plot_scrollbar.config(command=self.plot_listbox.yview)
        self.plot_scrollbar.pack(side=RIGHT, fill=Y)
        self.plot_listbox.pack(side=LEFT, fill=BOTH, expand=1)

    def create_event_listbox(self):

        self.event_label = Label(self.event_frame, text="Event:")
        self.event_label.pack(side=TOP)
        self.event_name = StringVar(self)
        self.event_scrollbar = Scrollbar(self.event_frame, orient=VERTICAL)
        self.event_listbox = Listbox(self.event_frame,
                                     yscrollcommand=self.event_scrollbar.set,
                                     selectmode=BROWSE)
        self.event_scrollbar.config(command=self.event_listbox.yview)
        self.event_scrollbar.pack(side=RIGHT, fill=Y)
        self.event_listbox.pack(side=LEFT, fill=BOTH, expand=1)

    def create_event_time_entries(self):

        self.event_start_label = Label(self.event_time_frame, text='Start Time:')
        self.event_start_label.pack()
        self.event_start_entry = Entry(self.event_time_frame)
        self.event_start_entry.pack()
        self.event_end_label = Label(self.event_time_frame, text='End Time:')
        self.event_end_label.pack()
        self.event_end_entry = Entry(self.event_time_frame)
        self.event_end_entry.pack()
        self.event_query_button = Button(self.event_time_frame,
                                         text='Load Event',
                                         command=self.load_event_data)
        self.event_query_button.pack()

    def set_filter(self):
        '''
        Hack for 'broken' check box
        '''
        if self.filter_plots == 0:
            self.filter_plots = 1
        else:
            self.filter_plots = 0

    def set_summary(self):
        '''
        Hack for 'broken' check box
        '''
        if self.summary_only == 0:
            self.summary_only = 1
        else:
            self.summary_only = 0

    def set_gmax(self):
        if self.use_gmax == 0:
            self.use_gmax = 1
        else:
            self.use_gmax = 0

    def create_checkboxes(self):
        '''
        Create various checkboxes for output options.
        '''
        self.plot_checkbox = Checkbutton(self.event_time_frame,
                                         text="Filter Plots by Event",
                                         variable=self.filter_plots,
                                         command=self.set_filter)
        self.plot_checkbox.pack(side=BOTTOM)
        self.plot_checkbox.toggle()
        self.filter_plots = 1
        self.summary_checkbox = Checkbutton(self.event_time_frame,
                                            text="Summarize data",
                                            variable=self.summary_only,
                                            command=self.set_summary)
        self.summary_checkbox.pack(side=BOTTOM)
        self.summary_checkbox.toggle()
        self.summary_only = 1

    def create_gmax_spinbox(self):

        self.gmax_label = Label(self.event_time_frame, text='Y maximum:')
        self.gmax_label.pack()
        self.gmax_spinbox = Spinbox(self.event_time_frame, from_=0, to_=100)
        self.gmax_spinbox.pack()

    def create_out_buttons(self):
        '''
        Create a button that creates a time series image.
        '''
        self.ts_button = Button(self.ts_frame, text='Create Time Series',
                                command=self.create_ts_image)
        self.ts_button.pack()
        self.wr_button = Button(self.ts_frame, text='Create Wind Rose',
                                command=self.create_wr_image)
        self.wr_button.pack()

        if HAVE_OGR:
            self.ogr_button = Button(self.ts_frame, text='Export to OGR',
                                     command=self.export_ogr)
            self.ogr_button.pack()

        self.csv_button = Button(self.ts_frame, text='Export to CSV',
                                 command=self.export_csv)
        self.csv_button.pack()
        self.kmz_button = Button(self.ts_frame, text='Export to KMZ',
                                 command=self.export_kmz)
        self.kmz_button.pack()

    def create(self):
        '''
        Build and pack the entire tk GUI.
        '''

        # Variables
        self.filter_plots = 0
        self.summary_only = 1

        # Menu bar
        self.create_menus()

        # Plot data
        self.plot_frame = Frame(self)

        # Event data
        self.event_frame = Frame(self)
        self.create_plot_listbox()
        self.event_frame.pack(side=LEFT)
        self.create_event_listbox()
        self.event_time_frame = Frame(self)
        self.event_time_frame.pack(side=LEFT)
        self.create_event_time_entries()

        # Pack the plot frame
        self.plot_frame.pack(side=LEFT)

        # Checkable options
        self.create_checkboxes()
        # Global max.
        self.create_gmax_spinbox()

        # Timeseries Image
        self.ts_frame = Frame(self)
        self.ts_frame.pack()
        self.create_out_buttons()

    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.cadre = RxCadre()
        self.pack()
        self.create()

def _quit():
    root.quit()
    root.destroy()

root = Tk()
root.protocol("WM_DELETE_WINDOW", _quit)
app = RxCadreTk(master=root)
app.mainloop()

<|endoftext|>


<commit_before>#!/usr/bin/env python
# Copyright (c) 2014 Eugene Zhuk.
# Use of this source code is governed by the MIT license that can be found
# in the LICENSE file.

"""Compresses an S3 object.

A simple tool to streamline compression of one or more S3 objects. Note
that a full path to an S3 object is required (e.g., s3://foo/bar).

Usage:
    ./compress_object.py <args>
"""

import boto.s3
import gzip
import optparse
import os
import sys

class Error(Exception):
    pass

def compress_file(name, out):
    """Compresses an existing file..
    """
    with open(name, 'rb') as i, gzip.open(out, 'wb') as o:
        o.writelines(i)

def upload_file(bucket, key, name):
    """Uploads an existing file to S3.
    """
    with bucket.new_key(key) as k:
        k.set_contents_from_filename(name)

def main():
    parser = optparse.OptionParser('Usage: %prog <args>...')
    (opts, args) = parser.parse_args()

    if 0 == len(args):
        parser.print_help()
        return 1

    try:
        s3 = boto.connect_s3()

        for a in args:
            if not a.startswith('s3://'):
                raise Error('unsupported object path!')
            parts = a[5:].split('/')
            b = parts[0]
            k = '/'.join(parts[1:]) if 1 < len(parts) else ''

            bucket = s3.get_bucket(b)
            key = bucket.get_key(k)
            _, name = os.path.split(key.name)
            key.get_contents_to_filename(name)

            out = name + '.gz'
            compress_file(name, out)
            os.remove(name)

            upload_file(bucket, key.name + '.gz', out)
            os.remove(out)
    except (Error, Exception), err:
        sys.stderr.write('[ERROR] {0}\n'.format(err))
        return 1

    return 0

if __name__ == '__main__':
    sys.exit(main())

<commit_msg>Better parsing.<commit_after>#!/usr/bin/env python
# Copyright (c) 2014 Eugene Zhuk.
# Use of this source code is governed by the MIT license that can be found
# in the LICENSE file.

"""Compresses an S3 object.

A simple tool to streamline compression of one or more S3 objects. Note
that a full path to an S3 object is required (e.g., s3://foo/bar).

Usage:
    ./compress_object.py <args>
"""

import boto.s3
import gzip
import optparse
import os
import sys

class Error(Exception):
    pass

def compress_file(name, out):
    """Compresses an existing file..
    """
    with open(name, 'rb') as i, gzip.open(out, 'wb') as o:
        o.writelines(i)

def upload_file(bucket, key, name):
    """Uploads an existing file to S3.
    """
    with bucket.new_key(key) as k:
        k.set_contents_from_filename(name)

def main():
    parser = optparse.OptionParser('Usage: %prog <args>...')
    (opts, args) = parser.parse_args()

    if 0 == len(args):
        parser.print_help()
        return 1

    try:
        s3 = boto.connect_s3()

        for a in args:
            if not a.startswith('s3://'):
                raise Error('unsupported object path!')
            parts = a[5:].split('/')
            bucket = s3.get_bucket(parts[0])
            key = bucket.get_key('/'.join(parts[1:]) if 1 < len(parts) else '')
            _, name = os.path.split(key.name)
            key.get_contents_to_filename(name)

            src = name + '.gz'
            compress_file(name, src)
            os.remove(name)

            dst = key.name + '.gz'
            upload_file(bucket, dst, src)
            os.remove(src)
    except (Error, Exception), err:
        sys.stderr.write('[ERROR] {0}\n'.format(err))
        return 1

    return 0

if __name__ == '__main__':
    sys.exit(main())

<|endoftext|>


<commit_before>import logging

from django.conf import settings
from django.contrib import messages
from django.db import transaction
from django.http import Http404, HttpResponseForbidden
from django.shortcuts import get_object_or_404, redirect
from django.utils.translation import ugettext as _
from django.template.response import TemplateResponse
from payments import RedirectNeeded

from .forms import PaymentDeleteForm, PaymentMethodsForm, PasswordForm
from .models import Order, Payment
from ..core.utils import get_client_ip
from .utils import check_order_status

logger = logging.getLogger(__name__)

def details(request, token):
    orders = Order.objects.prefetch_related('groups__items')
    order = get_object_or_404(orders, token=token)
    groups = order.groups.all()
    return TemplateResponse(request, 'order/details.html',
                            {'order': order, 'groups': groups})

def payment(request, token):
    orders = Order.objects.prefetch_related('groups__items')
    order = get_object_or_404(orders, token=token)
    groups = order.groups.all()
    payments = order.payments.all()
    form_data = request.POST or None
    try:
        waiting_payment = order.payments.get(status='waiting')
    except Payment.DoesNotExist:
        waiting_payment = None
        waiting_payment_form = None
    else:
        form_data = None
        waiting_payment_form = PaymentDeleteForm(
            None, order=order, initial={'payment_id': waiting_payment.id})
    if order.is_fully_paid():
        form_data = None
    payment_form = None
    if not order.is_pre_authorized():
        payment_form = PaymentMethodsForm(form_data)
        # FIXME: redirect if there is only one payment method
        if payment_form.is_valid():
            payment_method = payment_form.cleaned_data['method']
            return redirect('order:payment', token=order.token,
                            variant=payment_method)
    return TemplateResponse(request, 'order/payment.html',
                            {'order': order, 'groups': groups,
                             'payment_form': payment_form,
                             'waiting_payment': waiting_payment,
                             'waiting_payment_form': waiting_payment_form,
                             'payments': payments})

@check_order_status
def start_payment(request, order, variant):
    waiting_payments = order.payments.filter(status='waiting').exists()
    if waiting_payments:
        return redirect('order:payment', token=order.token)
    billing = order.billing_address
    total = order.get_total()
    defaults = {'total': total.gross,
                'tax': total.tax, 'currency': total.currency,
                'delivery': order.get_delivery_total().gross,
                'billing_first_name': billing.first_name,
                'billing_last_name': billing.last_name,
                'billing_address_1': billing.street_address_1,
                'billing_address_2': billing.street_address_2,
                'billing_city': billing.city,
                'billing_postcode': billing.postal_code,
                'billing_country_code': billing.country,
                'billing_email': order.user_email,
                'description': _('Order %(order_number)s') % {
                    'order_number': order},
                'billing_country_area': billing.country_area,
                'customer_ip_address': get_client_ip(request)}
    variant_choices = settings.CHECKOUT_PAYMENT_CHOICES
    if variant not in [code for code, dummy_name in variant_choices]:
        raise Http404('%r is not a valid payment variant' % (variant,))
    with transaction.atomic():
        order.change_status('payment-pending')
        payment, dummy_created = Payment.objects.get_or_create(
            variant=variant, status='waiting', order=order, defaults=defaults)
        try:
            form = payment.get_form(data=request.POST or None)
        except RedirectNeeded as redirect_to:
            return redirect(str(redirect_to))
        except Exception:
            logger.exception('Error communicating with the payment gateway')
            messages.error(
                request,
                _('Oops, it looks like we were unable to contact the selected'
                  ' payment service'))
            payment.change_status('error')
            return redirect('order:payment', token=order.token)
    template = 'order/payment/%s.html' % variant
    return TemplateResponse(request, [template, 'order/payment/default.html'],
                            {'form': form, 'payment': payment})

@check_order_status
def cancel_payment(request, order):
    form = PaymentDeleteForm(request.POST or None, order=order)
    if form.is_valid():
        with transaction.atomic():
            form.save()
        return redirect('order:payment', token=order.token)
    return HttpResponseForbidden()

def create_password(request, token):
    if request.user.is_authenticated():
        return redirect('order:details', kwargs={'token': token})
    order = get_object_or_404(Order, token=token)
    email = order.user_email
    form_data = request.POST.copy()
    form_data.update({'email': email})
    form = PasswordForm(form_data or None)
    if form.is_valid():
        with transaction.atomic():
            user = form.save(request)
            order.user = user
            order.save(update_fields=['user'])
    ctx = {'form': form, 'email': email}
    return TemplateResponse(request, 'order/create_password.html', ctx)
<commit_msg>Update copy of post data only when they contain something<commit_after>import logging

from django.conf import settings
from django.contrib import messages
from django.db import transaction
from django.http import Http404, HttpResponseForbidden
from django.shortcuts import get_object_or_404, redirect
from django.utils.translation import ugettext as _
from django.template.response import TemplateResponse
from payments import RedirectNeeded

from .forms import PaymentDeleteForm, PaymentMethodsForm, PasswordForm
from .models import Order, Payment
from ..core.utils import get_client_ip
from .utils import check_order_status

logger = logging.getLogger(__name__)

def details(request, token):
    orders = Order.objects.prefetch_related('groups__items')
    order = get_object_or_404(orders, token=token)
    groups = order.groups.all()
    return TemplateResponse(request, 'order/details.html',
                            {'order': order, 'groups': groups})

def payment(request, token):
    orders = Order.objects.prefetch_related('groups__items')
    order = get_object_or_404(orders, token=token)
    groups = order.groups.all()
    payments = order.payments.all()
    form_data = request.POST or None
    try:
        waiting_payment = order.payments.get(status='waiting')
    except Payment.DoesNotExist:
        waiting_payment = None
        waiting_payment_form = None
    else:
        form_data = None
        waiting_payment_form = PaymentDeleteForm(
            None, order=order, initial={'payment_id': waiting_payment.id})
    if order.is_fully_paid():
        form_data = None
    payment_form = None
    if not order.is_pre_authorized():
        payment_form = PaymentMethodsForm(form_data)
        # FIXME: redirect if there is only one payment method
        if payment_form.is_valid():
            payment_method = payment_form.cleaned_data['method']
            return redirect('order:payment', token=order.token,
                            variant=payment_method)
    return TemplateResponse(request, 'order/payment.html',
                            {'order': order, 'groups': groups,
                             'payment_form': payment_form,
                             'waiting_payment': waiting_payment,
                             'waiting_payment_form': waiting_payment_form,
                             'payments': payments})

@check_order_status
def start_payment(request, order, variant):
    waiting_payments = order.payments.filter(status='waiting').exists()
    if waiting_payments:
        return redirect('order:payment', token=order.token)
    billing = order.billing_address
    total = order.get_total()
    defaults = {'total': total.gross,
                'tax': total.tax, 'currency': total.currency,
                'delivery': order.get_delivery_total().gross,
                'billing_first_name': billing.first_name,
                'billing_last_name': billing.last_name,
                'billing_address_1': billing.street_address_1,
                'billing_address_2': billing.street_address_2,
                'billing_city': billing.city,
                'billing_postcode': billing.postal_code,
                'billing_country_code': billing.country,
                'billing_email': order.user_email,
                'description': _('Order %(order_number)s') % {
                    'order_number': order},
                'billing_country_area': billing.country_area,
                'customer_ip_address': get_client_ip(request)}
    variant_choices = settings.CHECKOUT_PAYMENT_CHOICES
    if variant not in [code for code, dummy_name in variant_choices]:
        raise Http404('%r is not a valid payment variant' % (variant,))
    with transaction.atomic():
        order.change_status('payment-pending')
        payment, dummy_created = Payment.objects.get_or_create(
            variant=variant, status='waiting', order=order, defaults=defaults)
        try:
            form = payment.get_form(data=request.POST or None)
        except RedirectNeeded as redirect_to:
            return redirect(str(redirect_to))
        except Exception:
            logger.exception('Error communicating with the payment gateway')
            messages.error(
                request,
                _('Oops, it looks like we were unable to contact the selected'
                  ' payment service'))
            payment.change_status('error')
            return redirect('order:payment', token=order.token)
    template = 'order/payment/%s.html' % variant
    return TemplateResponse(request, [template, 'order/payment/default.html'],
                            {'form': form, 'payment': payment})

@check_order_status
def cancel_payment(request, order):
    form = PaymentDeleteForm(request.POST or None, order=order)
    if form.is_valid():
        with transaction.atomic():
            form.save()
        return redirect('order:payment', token=order.token)
    return HttpResponseForbidden()

def create_password(request, token):
    if request.user.is_authenticated():
        return redirect('order:details', kwargs={'token': token})
    order = get_object_or_404(Order, token=token)
    email = order.user_email
    form_data = request.POST.copy()
    if form_data:
        form_data.update({'email': email})
    form = PasswordForm(form_data or None)

    if form.is_valid():
        with transaction.atomic():
            user = form.save(request)
            order.user = user
            order.save(update_fields=['user'])
    ctx = {'form': form, 'email': email}
    return TemplateResponse(request, 'order/create_password.html', ctx)
<|endoftext|>


<commit_before>'''
Salt module to manage unix mounts and the fstab file
'''

import logging
import os

from salt._compat import string_types

# Set up logger
log = logging.getLogger(__name__)

def active():
    '''
    List the active mounts.

    CLI Example::

        salt '*' mount.active
    '''
    ret = {}
    with open('/proc/self/mountinfo') as fh:
        for line in fh:
            comps = line.split()
            device = comps[2].split(':')
            ret[comps[4]] = {'mountid': comps[0],
                             'parentid': comps[1],
                             'major': device[0],
                             'minor': device[1],
                             'root': comps[3],
                             'opts': comps[5].split(','),
                             'fstype': comps[7],
                             'device': comps[8],
                             'superopts': comps[9].split(',')}
    return ret

def fstab(config='/etc/fstab'):
    '''
    List the contents of the fstab

    CLI Example::

        salt '*' mount.fstab
    '''
    ret = {}
    if not os.path.isfile(config):
        return ret
    for line in open(config).readlines():
        if line.startswith('#'):
            # Commented
            continue
        if not line.strip():
            # Blank line
            continue
        comps = line.split()
        if not len(comps) == 6:
            # Invalid entry
            continue
        ret[comps[1]] = {'device': comps[0],
                         'fstype': comps[2],
                         'opts': comps[3].split(','),
                         'dump': comps[4],
                         'pass': comps[5]}
    return ret

def rm_fstab(name, config='/etc/fstab'):
    '''
    Remove the mount point from the fstab

    CLI Example::

        salt '*' mount.rm_fstab /mnt/foo
    '''
    contents = fstab(config)
    if name not in contents:
        return True
    # The entry is present, get rid of it
    lines = []
    for line in open(config).readlines():
        if line.startswith('#'):
            # Commented
            lines.append(line)
            continue
        if not line.strip():
            # Blank line
            lines.append(line)
            continue
        comps = line.split()
        if not len(comps) == 6:
            # Invalid entry
            lines.append(line)
            continue
        comps = line.split()
        if comps[1] == name:
            continue
        lines.append(line)
    open(config, 'w+').writelines(lines)
    return True

def set_fstab(
        name,
        device,
        fstype,
        opts='defaults',
        dump=0,
        pass_num=0,
        config='/etc/fstab',
        ):
    '''
    Verify that this mount is represented in the fstab, chage the mount point
    to match the data passed, or add the mount if it is not present.

    CLI Example::

        salt '*' mount.set_fstab /mnt/foo /dev/sdz1 ext4
    '''
    # Fix the opts type if it is a list
    if isinstance(opts, list):
        opts = ','.join(opts)
    lines = []
    change = False
    present = False
    if not os.path.isfile(config):
        return 'bad config'
    for line in open(config).readlines():
        if line.startswith('#'):
            # Commented
            lines.append(line)
            continue
        if not line.strip():
            # Blank line
            lines.append(line)
            continue
        comps = line.split()
        if not len(comps) == 6:
            # Invalid entry
            lines.append(line)
            continue
        if comps[1] == name:
            # check to see if there are changes and fix them if there are
            present = True
            if comps[0] != device:
                change = True
                comps[0] = device
            if comps[2] != fstype:
                change = True
                comps[2] = fstype
            if comps[3] != opts:
                change = True
                comps[3] = opts
            if comps[4] != str(dump):
                change = True
                comps[4] = str(dump)
            if comps[5] != str(pass_num):
                change = True
                comps[5] = str(pass_num)
            if change:
                log.debug('fstab entry for mount point {0} is being updated'
                          .format(name))
                newline = ('{0}\t\t{1}\t{2}\t{3}\t{4} {5}\n'
                           .format(device, name, fstype, opts, dump, pass_num))
                lines.append(newline)
        else:
            lines.append(line)
    if change:
        # The line was changed, commit it!
        open(config, 'w+').writelines(lines)
        return 'change'
    if not change and not present:
        # The entry is new, add it to the end of the fstab
        newline = '{0}\t\t{1}\t{2}\t{3}\t{4} {5}\n'.format(
                device,
                name,
                fstype,
                opts,
                dump,
                pass_num)
        lines.append(newline)
        open(config, 'w+').writelines(lines)
    if present and not change:
        # The right entry is already here
        return 'present'
    return 'new'

def mount(name, device, mkmnt=False, fstype='', opts='defaults'):
    '''
    Mount a device

    CLI Example::

        salt '*' mount.mount /mnt/foo /dev/sdz1 True
    '''
    if isinstance(opts, string_types):
        opts = opts.split(',')
    if not os.path.exists(name) and mkmnt:
        os.makedirs(name)
    lopts = ','.join(opts)
    cmd = 'mount -o {0} {1} {2} '.format(lopts, device, name)
    if fstype:
        cmd += ' -t {0}'.format(fstype)
    out = __salt__['cmd.run_all'](cmd)
    if out['retcode']:
        return out['stderr']
    return True

def remount(name, device, mkmnt=False, fstype='', opts='defaults'):
    '''
    Attempt to remount a device, if the device is not already mounted, mount
    is called

    CLI Example::

        salt '*' mount.remount /mnt/foo /dev/sdz1 True
    '''
    if isinstance(opts, string_types):
        opts = opts.split(',')
    mnts = active()
    if name in mnts:
        # The mount point is mounted, attempt to remount it with the given data
        if 'remount' not in opts:
            opts.append('remount')
        lopts = ','.join(opts)
        cmd = 'mount -o {0} {1} {2} '.format(lopts, device, name)
        if fstype:
            cmd += ' -t {0}'.format(fstype)
        out = __salt__['cmd.run_all'](cmd)
        if out['retcode']:
            return out['stderr']
        return True
    else:
        return mount(name, device, mkmnt, fstype, opts)

def is_fuse_exec(cmd):
    '''
    Returns true if the command passed is a fuse mountable application.

    CLI Example::

        salt '*' mount.is_fuse_exec sshfs
    '''
    if not __salt__['cmd.has_exec'](cmd):
        return False
    for path in os.environ['PATH'].split(os.pathsep):
        if not __salt__['cmd.has_exec'](path):
            continue
        out = __salt__['cmd.run']('ldd {0}'.format(path))
        for line in out.split('\n'):
            if 'libfuse' in line:
                return True
    return False
<commit_msg>Fix the mount module in certain cases<commit_after>'''
Salt module to manage unix mounts and the fstab file
'''

import logging
import os

from salt._compat import string_types

# Set up logger
log = logging.getLogger(__name__)

def _active_mountinfo(ret):
    with open('/proc/self/mountinfo') as fh:
        for line in fh:
            comps = line.split()
            device = comps[2].split(':')
            ret[comps[4]] = {'mountid': comps[0],
                             'parentid': comps[1],
                             'major': device[0],
                             'minor': device[1],
                             'root': comps[3],
                             'opts': comps[5].split(','),
                             'fstype': comps[7],
                             'device': comps[8],
                             'superopts': comps[9].split(',')}
    return ret

def _active_mounts(ret):
    with open('/proc/self/mounts') as fh:
        for line in fh:
            comps.split()
            ret[comps[1]] = {'device': comps[0],
                             'fstype': comps[2],
                             'opts': comps[3].split(',')}
    return ret

def active():
    '''
    List the active mounts.

    CLI Example::

        salt '*' mount.active
    '''
    ret = {}
    try:
        _active_mountinfo(ret)
    except IOError:
        _active_mounts(ret)
    return ret

def fstab(config='/etc/fstab'):
    '''
    List the contents of the fstab

    CLI Example::

        salt '*' mount.fstab
    '''
    ret = {}
    if not os.path.isfile(config):
        return ret
    for line in open(config).readlines():
        if line.startswith('#'):
            # Commented
            continue
        if not line.strip():
            # Blank line
            continue
        comps = line.split()
        if not len(comps) == 6:
            # Invalid entry
            continue
        ret[comps[1]] = {'device': comps[0],
                         'fstype': comps[2],
                         'opts': comps[3].split(','),
                         'dump': comps[4],
                         'pass': comps[5]}
    return ret

def rm_fstab(name, config='/etc/fstab'):
    '''
    Remove the mount point from the fstab

    CLI Example::

        salt '*' mount.rm_fstab /mnt/foo
    '''
    contents = fstab(config)
    if name not in contents:
        return True
    # The entry is present, get rid of it
    lines = []
    for line in open(config).readlines():
        if line.startswith('#'):
            # Commented
            lines.append(line)
            continue
        if not line.strip():
            # Blank line
            lines.append(line)
            continue
        comps = line.split()
        if not len(comps) == 6:
            # Invalid entry
            lines.append(line)
            continue
        comps = line.split()
        if comps[1] == name:
            continue
        lines.append(line)
    open(config, 'w+').writelines(lines)
    return True

def set_fstab(
        name,
        device,
        fstype,
        opts='defaults',
        dump=0,
        pass_num=0,
        config='/etc/fstab',
        ):
    '''
    Verify that this mount is represented in the fstab, chage the mount point
    to match the data passed, or add the mount if it is not present.

    CLI Example::

        salt '*' mount.set_fstab /mnt/foo /dev/sdz1 ext4
    '''
    # Fix the opts type if it is a list
    if isinstance(opts, list):
        opts = ','.join(opts)
    lines = []
    change = False
    present = False
    if not os.path.isfile(config):
        return 'bad config'
    for line in open(config).readlines():
        if line.startswith('#'):
            # Commented
            lines.append(line)
            continue
        if not line.strip():
            # Blank line
            lines.append(line)
            continue
        comps = line.split()
        if not len(comps) == 6:
            # Invalid entry
            lines.append(line)
            continue
        if comps[1] == name:
            # check to see if there are changes and fix them if there are
            present = True
            if comps[0] != device:
                change = True
                comps[0] = device
            if comps[2] != fstype:
                change = True
                comps[2] = fstype
            if comps[3] != opts:
                change = True
                comps[3] = opts
            if comps[4] != str(dump):
                change = True
                comps[4] = str(dump)
            if comps[5] != str(pass_num):
                change = True
                comps[5] = str(pass_num)
            if change:
                log.debug('fstab entry for mount point {0} is being updated'
                          .format(name))
                newline = ('{0}\t\t{1}\t{2}\t{3}\t{4} {5}\n'
                           .format(device, name, fstype, opts, dump, pass_num))
                lines.append(newline)
        else:
            lines.append(line)
    if change:
        # The line was changed, commit it!
        open(config, 'w+').writelines(lines)
        return 'change'
    if not change and not present:
        # The entry is new, add it to the end of the fstab
        newline = '{0}\t\t{1}\t{2}\t{3}\t{4} {5}\n'.format(
                device,
                name,
                fstype,
                opts,
                dump,
                pass_num)
        lines.append(newline)
        open(config, 'w+').writelines(lines)
    if present and not change:
        # The right entry is already here
        return 'present'
    return 'new'

def mount(name, device, mkmnt=False, fstype='', opts='defaults'):
    '''
    Mount a device

    CLI Example::

        salt '*' mount.mount /mnt/foo /dev/sdz1 True
    '''
    if isinstance(opts, string_types):
        opts = opts.split(',')
    if not os.path.exists(name) and mkmnt:
        os.makedirs(name)
    lopts = ','.join(opts)
    cmd = 'mount -o {0} {1} {2} '.format(lopts, device, name)
    if fstype:
        cmd += ' -t {0}'.format(fstype)
    out = __salt__['cmd.run_all'](cmd)
    if out['retcode']:
        return out['stderr']
    return True

def remount(name, device, mkmnt=False, fstype='', opts='defaults'):
    '''
    Attempt to remount a device, if the device is not already mounted, mount
    is called

    CLI Example::

        salt '*' mount.remount /mnt/foo /dev/sdz1 True
    '''
    if isinstance(opts, string_types):
        opts = opts.split(',')
    mnts = active()
    if name in mnts:
        # The mount point is mounted, attempt to remount it with the given data
        if 'remount' not in opts:
            opts.append('remount')
        lopts = ','.join(opts)
        cmd = 'mount -o {0} {1} {2} '.format(lopts, device, name)
        if fstype:
            cmd += ' -t {0}'.format(fstype)
        out = __salt__['cmd.run_all'](cmd)
        if out['retcode']:
            return out['stderr']
        return True
    else:
        return mount(name, device, mkmnt, fstype, opts)

def is_fuse_exec(cmd):
    '''
    Returns true if the command passed is a fuse mountable application.

    CLI Example::

        salt '*' mount.is_fuse_exec sshfs
    '''
    if not __salt__['cmd.has_exec'](cmd):
        return False
    for path in os.environ['PATH'].split(os.pathsep):
        if not __salt__['cmd.has_exec'](path):
            continue
        out = __salt__['cmd.run']('ldd {0}'.format(path))
        for line in out.split('\n'):
            if 'libfuse' in line:
                return True
    return False
<|endoftext|>