<commit_before># coding=UTF-8
from django.db import models
from django.contrib.sites.models import Site
from django.contrib.auth.models import User
from django.template.defaultfilters import slugify
from django.utils.translation import ugettext as _
from django.template import loader, Context
from django.core.urlresolvers import reverse
from django.core.mail import send_mail
from django.conf import settings
from userprofile.countries import CountryField
import datetime
import cPickle as pickle
import base64
import os.path
try:
    from PIL import Image, ImageFilter
except ImportError:
    import Image, ImageFilter

AVATAR_SIZES = (128, 96, 64, 48, 32, 24, 16)

class BaseProfile(models.Model):
    """
    User profile model
    """

    user = models.ForeignKey(User, unique=True)
    date = models.DateTimeField(default=datetime.datetime.now)
    country = CountryField(null=True, blank=True)
    latitude = models.DecimalField(max_digits=10, decimal_places=6, blank=True, null=True)
    longitude = models.DecimalField(max_digits=10, decimal_places=6, blank=True, null=True)
    location = models.CharField(max_length=255, blank=True)

    class Meta:
        abstract = True

    def has_avatar(self):
        return Avatar.objects.filter(user=self.user, valid=True).count()

    def __unicode__(self):
        return _("%s's profile") % self.user

    def get_absolute_url(self):
        return reverse("profile_public", args=[self.user])

class Avatar(models.Model):
    """
    Avatar model
    """
    image = models.ImageField(upload_to="avatars/%Y/%b/%d")
    user = models.ForeignKey(User)
    date = models.DateTimeField(auto_now_add=True)
    valid = models.BooleanField()

    class Meta:
        unique_together = (('user', 'valid'),)

    def __unicode__(self):
        return _("%s's Avatar") % self.user

    def delete(self):
        base, filename = os.path.split(self.image.path)
        name, extension = os.path.splitext(filename)
        for key in AVATAR_SIZES:
            try:
                os.remove(os.path.join(base, "%s.%s%s" % (name, key, extension)))
            except:
                pass

        super(Avatar, self).delete()

    def save(self):
        for avatar in Avatar.objects.filter(user=self.user, valid=self.valid).exclude(id=self.id):
            base, filename = os.path.split(avatar.image.path)
            name, extension = os.path.splitext(filename)
            for key in AVATAR_SIZES:
                try:
                    os.remove(os.path.join(base, "%s.%s%s" % (name, key, extension)))
                except:
                    pass
            avatar.delete()

        super(Avatar, self).save()

class EmailValidationManager(models.Manager):
    """
    Email validation manager
    """
    def verify(self, key):
        try:
            verify = self.get(key=key)
            if not verify.is_expired():
                verify.user.email = verify.email
                if hasattr(settings, "REQUIRE_EMAIL_CONFIRMATION") and settings.REQUIRE_EMAIL_CONFIRMATION:
                    verify.user.is_active = True
                verify.user.save()
                verify.delete()
                return True
            else:
                verify.delete()
                return False
        except:
            return False

    def getuser(self, key):
        try:
            return self.get(key=key).user
        except:
            return False

    def add(self, user, email):
        """
        Add a new validation process entry
        """
        while True:
            key = User.objects.make_random_password(70)
            try:
                EmailValidation.objects.get(key=key)
            except EmailValidation.DoesNotExist:
                self.key = key
                break

        template_body = "userprofile/email/validation.txt"
        template_subject = "userprofile/email/validation_subject.txt"
        site_name, domain = Site.objects.get_current().name, Site.objects.get_current().domain
        body = loader.get_template(template_body).render(Context(locals()))
        subject = loader.get_template(template_subject).render(Context(locals())).strip()
        send_mail(subject=subject, message=body, from_email=None, recipient_list=[email])
        user = User.objects.get(username=str(user))
        self.filter(user=user).delete()
        return self.create(user=user, key=key, email=email)

class EmailValidation(models.Model):
    """
    Email Validation model
    """
    user = models.ForeignKey(User, unique=True)
    email = models.EmailField(blank=True)
    key = models.CharField(max_length=70, unique=True, db_index=True)
    created = models.DateTimeField(auto_now_add=True)
    objects = EmailValidationManager()

    def __unicode__(self):
        return _("Email validation process for %(user)s") % { 'user': self.user }

    def is_expired(self):
        return (datetime.datetime.today() - self.created).days > 0

    def resend(self):
        """
        Resend validation email
        """
        template_body = "userprofile/email/validation.txt"
        template_subject = "userprofile/email/validation_subject.txt"
        site_name, domain = Site.objects.get_current().name, Site.objects.get_current().domain
        key = self.key
        body = loader.get_template(template_body).render(Context(locals()))
        subject = loader.get_template(template_subject).render(Context(locals())).strip()
        send_mail(subject=subject, message=body, from_email=None, recipient_list=[self.email])
        self.created = datetime.datetime.now()
        self.save()
        return True

class UserProfileMediaNotFound(Exception):
    pass

class GoogleDataAPINotFound(Exception):
    pass
<commit_msg>Changed the UserProfile "date" field to "creation_date" to solve a problem with Oracle databases.<commit_after># coding=UTF-8
from django.db import models
from django.contrib.sites.models import Site
from django.contrib.auth.models import User
from django.template.defaultfilters import slugify
from django.utils.translation import ugettext as _
from django.template import loader, Context
from django.core.urlresolvers import reverse
from django.core.mail import send_mail
from django.conf import settings
from userprofile.countries import CountryField
import datetime
import cPickle as pickle
import base64
import os.path
try:
    from PIL import Image, ImageFilter
except ImportError:
    import Image, ImageFilter

AVATAR_SIZES = (128, 96, 64, 48, 32, 24, 16)

class BaseProfile(models.Model):
    """
    User profile model
    """

    user = models.ForeignKey(User, unique=True)
    creation_date = models.DateTimeField(default=datetime.datetime.now)
    country = CountryField(null=True, blank=True)
    latitude = models.DecimalField(max_digits=10, decimal_places=6, blank=True, null=True)
    longitude = models.DecimalField(max_digits=10, decimal_places=6, blank=True, null=True)
    location = models.CharField(max_length=255, blank=True)

    class Meta:
        abstract = True

    def has_avatar(self):
        return Avatar.objects.filter(user=self.user, valid=True).count()

    def __unicode__(self):
        return _("%s's profile") % self.user

    def get_absolute_url(self):
        return reverse("profile_public", args=[self.user])

class Avatar(models.Model):
    """
    Avatar model
    """
    image = models.ImageField(upload_to="avatars/%Y/%b/%d")
    user = models.ForeignKey(User)
    date = models.DateTimeField(auto_now_add=True)
    valid = models.BooleanField()

    class Meta:
        unique_together = (('user', 'valid'),)

    def __unicode__(self):
        return _("%s's Avatar") % self.user

    def delete(self):
        base, filename = os.path.split(self.image.path)
        name, extension = os.path.splitext(filename)
        for key in AVATAR_SIZES:
            try:
                os.remove(os.path.join(base, "%s.%s%s" % (name, key, extension)))
            except:
                pass

        super(Avatar, self).delete()

    def save(self):
        for avatar in Avatar.objects.filter(user=self.user, valid=self.valid).exclude(id=self.id):
            base, filename = os.path.split(avatar.image.path)
            name, extension = os.path.splitext(filename)
            for key in AVATAR_SIZES:
                try:
                    os.remove(os.path.join(base, "%s.%s%s" % (name, key, extension)))
                except:
                    pass
            avatar.delete()

        super(Avatar, self).save()

class EmailValidationManager(models.Manager):
    """
    Email validation manager
    """
    def verify(self, key):
        try:
            verify = self.get(key=key)
            if not verify.is_expired():
                verify.user.email = verify.email
                if hasattr(settings, "REQUIRE_EMAIL_CONFIRMATION") and settings.REQUIRE_EMAIL_CONFIRMATION:
                    verify.user.is_active = True
                verify.user.save()
                verify.delete()
                return True
            else:
                verify.delete()
                return False
        except:
            return False

    def getuser(self, key):
        try:
            return self.get(key=key).user
        except:
            return False

    def add(self, user, email):
        """
        Add a new validation process entry
        """
        while True:
            key = User.objects.make_random_password(70)
            try:
                EmailValidation.objects.get(key=key)
            except EmailValidation.DoesNotExist:
                self.key = key
                break

        template_body = "userprofile/email/validation.txt"
        template_subject = "userprofile/email/validation_subject.txt"
        site_name, domain = Site.objects.get_current().name, Site.objects.get_current().domain
        body = loader.get_template(template_body).render(Context(locals()))
        subject = loader.get_template(template_subject).render(Context(locals())).strip()
        send_mail(subject=subject, message=body, from_email=None, recipient_list=[email])
        user = User.objects.get(username=str(user))
        self.filter(user=user).delete()
        return self.create(user=user, key=key, email=email)

class EmailValidation(models.Model):
    """
    Email Validation model
    """
    user = models.ForeignKey(User, unique=True)
    email = models.EmailField(blank=True)
    key = models.CharField(max_length=70, unique=True, db_index=True)
    created = models.DateTimeField(auto_now_add=True)
    objects = EmailValidationManager()

    def __unicode__(self):
        return _("Email validation process for %(user)s") % { 'user': self.user }

    def is_expired(self):
        return (datetime.datetime.today() - self.created).days > 0

    def resend(self):
        """
        Resend validation email
        """
        template_body = "userprofile/email/validation.txt"
        template_subject = "userprofile/email/validation_subject.txt"
        site_name, domain = Site.objects.get_current().name, Site.objects.get_current().domain
        key = self.key
        body = loader.get_template(template_body).render(Context(locals()))
        subject = loader.get_template(template_subject).render(Context(locals())).strip()
        send_mail(subject=subject, message=body, from_email=None, recipient_list=[self.email])
        self.created = datetime.datetime.now()
        self.save()
        return True

class UserProfileMediaNotFound(Exception):
    pass

class GoogleDataAPINotFound(Exception):
    pass
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-

# This file is part of PyBOSSA.
#
# PyBOSSA is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PyBOSSA 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with PyBOSSA.  If not, see <http://www.gnu.org/licenses/>.

import json
from optparse import OptionParser
import pbclient
from get_images import get_flickr_photos
import random
import logging
from requests import exceptions

def contents(filename):
    return file(filename).read()

def handle_arguments():
    # Arguments for the application
    usage = "usage: %prog [options]"
    parser = OptionParser(usage)
    # URL where PyBossa listens
    parser.add_option("-s", "--server", dest="api_url",
                      help="PyBossa URL http://domain.com/", metavar="URL",
                      default="http://localhost:5000/")
    # API-KEY
    parser.add_option("-k", "--api-key", dest="api_key",
                      help="PyBossa User API-KEY to interact with PyBossa",
                      metavar="API-KEY")
    # Create App
    parser.add_option("-c", "--create-app", action="store_true",
                      dest="create_app",
                      help="Create the application",
                      metavar="CREATE-APP")
    # Update template for tasks and long_description for app
    parser.add_option("-t", "--update-template", action="store_true",
                      dest="update_template",
                      help="Update Tasks template",
                      metavar="UPDATE-TEMPLATE")

    # Update tasks question
    parser.add_option("-q", "--update-tasks",
                      type="int",
                      dest="update_tasks",
                      help="Update Tasks n_answers",
                      metavar="UPDATE-TASKS")

    parser.add_option("-x", "--extra-task", action="store_true",
                      dest="add_more_tasks",
                      help="Add more tasks",
                      metavar="ADD-MORE-TASKS")

    # Modify the number of TaskRuns per Task
    # (default 30)
    parser.add_option("-n", "--number-answers",
                      type="int",
                      dest="n_answers",
                      help="Number of answers per task",
                      metavar="N-ANSWERS",
                      default=30)

    parser.add_option("-a", "--application-config",
                      dest="app_config",
                      help="Application config file",
                      metavar="APP-CONFIG",
                      default="app.json")

    parser.add_option("-v", "--verbose", action="store_true", dest="verbose")
    (options, args) = parser.parse_args()

    if not options.create_app and not options.update_template\
            and not options.add_more_tasks and not options.update_tasks:
        parser.error("Please check --help or -h for the available options")

    if not options.api_key:
        parser.error("You must supply an API-KEY to create an \
                      application and tasks in PyBossa")

    return options

def get_configuration():
    options = handle_arguments()

    # Load app details
    try:
        with file(options.app_config) as app_json:
            app_config = json.load(app_json)
    except IOError:
        print "application config file is missing! Please create a new one"
        exit(1)

    return (app_config, options)

def run(app_config, options):
    def check_api_error(api_response):
        """Check if returned API response contains an error"""
        if type(api_response) == dict and (api_response.get('status') == 'failed'):
            raise exceptions.HTTPError

    def format_error(module, error):
        """Format the error for the given module"""
        logging.error(module)
        # Beautify JSON error
        if type(error) == list:
            print "Application not found"
        else:
            print json.dumps(error, sort_keys=True, indent=4, separators=(',', ': '))
        exit(1)

    def find_app_by_short_name():
        try:
            response = pbclient.find_app(short_name=app_config['short_name'])
            check_api_error(response)
            return response[0]
        except:
            format_error("pbclient.find_app", response)

    def setup_app():
        app = find_app_by_short_name()
        app.long_description = contents('long_description.html')
        app.info['task_presenter'] = contents('template.html')
        app.info['thumbnail'] = app_config['thumbnail']
        app.info['tutorial'] = contents('tutorial.html')

        try:
            response = pbclient.update_app(app)
            check_api_error(response)
            return app
        except:
            format_error("pbclient.update_app", response)

    def create_photo_task(app, photo, question, priority=0):
        # Data for the tasks
        task_info = dict(question=question,
                         n_answers=options.n_answers,
                         link=photo['link'],
                         url_m=photo['url_m'],
                         url_b=photo['url_b'])
        try:
            response = pbclient.create_task(app.id, task_info, priority_0=priority)
            check_api_error(response)
        except:
            format_error("pbclient.create_task", response)

    def add_photo_tasks(app):
        # First of all we get the URL photos
        # Then, we have to create a set of tasks for the application
        # For this, we get first the photo URLs from Flickr
        photos = get_flickr_photos()
        question = app_config['question']
        [create_photo_task(app, p, question, priority=random.random()) for p in photos]

    pbclient.set('api_key', options.api_key)
    pbclient.set('endpoint', options.api_url)

    if options.verbose:
        print('Running against PyBosssa instance at: %s' % options.api_url)
        print('Using API-KEY: %s' % options.api_key)

    if options.create_app or options.add_more_tasks:
        if options.create_app:
            try:
                response = pbclient.create_app(app_config['name'],
                                               app_config['short_name'],
                                               app_config['description'])

                check_api_error(response)
                app = setup_app()
            except:
                format_error("pbclient.create_app", response)
        else:
            app = find_app_by_short_name()
        add_photo_tasks(app)

    if options.update_template:
        print "Updating app template"
        # discard return value
        setup_app()

    if options.update_tasks:
        def tasks(app):
            offset = 0
            limit = 100
            while True:
                try:
                    tasks = pbclient.get_tasks(app.id, offset=offset, limit=limit)
                    check_api_error(tasks)
                    if len(tasks) == 0:
                        break
                    for task in tasks:
                        yield task
                    offset += len(tasks)
                except:
                    format_error("pbclient.get_tasks", response)

        def update_task(task, count):
            print "Updating task: %s" % task.id
            if 'n_answers' in task.info:
                del(task.info['n_answers'])
            task.n_answers = options.update_tasks
            try:
                response = pbclient.update_task(task)
                check_api_error(response)
                count[0] += 1
            except:
                format_error("pbclient.update_task", response)

        print "Updating task n_answers"
        app = find_app_by_short_name()

        n_tasks = [0]
        [update_task(t, n_tasks) for t in tasks(app)]
        print "%s Tasks have been updated!" % n_tasks[0]

if __name__ == "__main__":
    app_config, options = get_configuration()
    run(app_config, options)
<commit_msg>Fixed default server for local vagrant installations<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

# This file is part of PyBOSSA.
#
# PyBOSSA is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PyBOSSA 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with PyBOSSA.  If not, see <http://www.gnu.org/licenses/>.

import json
from optparse import OptionParser
import pbclient
from get_images import get_flickr_photos
import random
import logging
from requests import exceptions

def contents(filename):
    return file(filename).read()

def handle_arguments():
    # Arguments for the application
    usage = "usage: %prog [options]"
    parser = OptionParser(usage)
    # URL where PyBossa listens
    parser.add_option("-s", "--server", dest="api_url",
                      help="PyBossa URL http://domain.com", metavar="URL",
                      default="http://localhost:5000")
    # API-KEY
    parser.add_option("-k", "--api-key", dest="api_key",
                      help="PyBossa User API-KEY to interact with PyBossa",
                      metavar="API-KEY")
    # Create App
    parser.add_option("-c", "--create-app", action="store_true",
                      dest="create_app",
                      help="Create the application",
                      metavar="CREATE-APP")
    # Update template for tasks and long_description for app
    parser.add_option("-t", "--update-template", action="store_true",
                      dest="update_template",
                      help="Update Tasks template",
                      metavar="UPDATE-TEMPLATE")

    # Update tasks question
    parser.add_option("-q", "--update-tasks",
                      type="int",
                      dest="update_tasks",
                      help="Update Tasks n_answers",
                      metavar="UPDATE-TASKS")

    parser.add_option("-x", "--extra-task", action="store_true",
                      dest="add_more_tasks",
                      help="Add more tasks",
                      metavar="ADD-MORE-TASKS")

    # Modify the number of TaskRuns per Task
    # (default 30)
    parser.add_option("-n", "--number-answers",
                      type="int",
                      dest="n_answers",
                      help="Number of answers per task",
                      metavar="N-ANSWERS",
                      default=30)

    parser.add_option("-a", "--application-config",
                      dest="app_config",
                      help="Application config file",
                      metavar="APP-CONFIG",
                      default="app.json")

    parser.add_option("-v", "--verbose", action="store_true", dest="verbose")
    (options, args) = parser.parse_args()

    if not options.create_app and not options.update_template\
            and not options.add_more_tasks and not options.update_tasks:
        parser.error("Please check --help or -h for the available options")

    if not options.api_key:
        parser.error("You must supply an API-KEY to create an \
                      application and tasks in PyBossa")

    return options

def get_configuration():
    options = handle_arguments()

    # Load app details
    try:
        with file(options.app_config) as app_json:
            app_config = json.load(app_json)
    except IOError:
        print "application config file is missing! Please create a new one"
        exit(1)

    return (app_config, options)

def run(app_config, options):
    def check_api_error(api_response):
        """Check if returned API response contains an error"""
        if type(api_response) == dict and (api_response.get('status') == 'failed'):
            raise exceptions.HTTPError

    def format_error(module, error):
        """Format the error for the given module"""
        logging.error(module)
        # Beautify JSON error
        if type(error) == list:
            print "Application not found"
        else:
            print json.dumps(error, sort_keys=True, indent=4, separators=(',', ': '))
        exit(1)

    def find_app_by_short_name():
        try:
            response = pbclient.find_app(short_name=app_config['short_name'])
            check_api_error(response)
            return response[0]
        except:
            format_error("pbclient.find_app", response)

    def setup_app():
        app = find_app_by_short_name()
        app.long_description = contents('long_description.html')
        app.info['task_presenter'] = contents('template.html')
        app.info['thumbnail'] = app_config['thumbnail']
        app.info['tutorial'] = contents('tutorial.html')

        try:
            response = pbclient.update_app(app)
            check_api_error(response)
            return app
        except:
            format_error("pbclient.update_app", response)

    def create_photo_task(app, photo, question, priority=0):
        # Data for the tasks
        task_info = dict(question=question,
                         n_answers=options.n_answers,
                         link=photo['link'],
                         url_m=photo['url_m'],
                         url_b=photo['url_b'])
        try:
            response = pbclient.create_task(app.id, task_info, priority_0=priority)
            check_api_error(response)
        except:
            format_error("pbclient.create_task", response)

    def add_photo_tasks(app):
        # First of all we get the URL photos
        # Then, we have to create a set of tasks for the application
        # For this, we get first the photo URLs from Flickr
        photos = get_flickr_photos()
        question = app_config['question']
        [create_photo_task(app, p, question, priority=random.random()) for p in photos]

    pbclient.set('api_key', options.api_key)
    pbclient.set('endpoint', options.api_url)

    if options.verbose:
        print('Running against PyBosssa instance at: %s' % options.api_url)
        print('Using API-KEY: %s' % options.api_key)

    if options.create_app or options.add_more_tasks:
        if options.create_app:
            try:
                response = pbclient.create_app(app_config['name'],
                                               app_config['short_name'],
                                               app_config['description'])

                check_api_error(response)
                app = setup_app()
            except:
                format_error("pbclient.create_app", response)
        else:
            app = find_app_by_short_name()
        add_photo_tasks(app)

    if options.update_template:
        print "Updating app template"
        # discard return value
        setup_app()

    if options.update_tasks:
        def tasks(app):
            offset = 0
            limit = 100
            while True:
                try:
                    tasks = pbclient.get_tasks(app.id, offset=offset, limit=limit)
                    check_api_error(tasks)
                    if len(tasks) == 0:
                        break
                    for task in tasks:
                        yield task
                    offset += len(tasks)
                except:
                    format_error("pbclient.get_tasks", response)

        def update_task(task, count):
            print "Updating task: %s" % task.id
            if 'n_answers' in task.info:
                del(task.info['n_answers'])
            task.n_answers = options.update_tasks
            try:
                response = pbclient.update_task(task)
                check_api_error(response)
                count[0] += 1
            except:
                format_error("pbclient.update_task", response)

        print "Updating task n_answers"
        app = find_app_by_short_name()

        n_tasks = [0]
        [update_task(t, n_tasks) for t in tasks(app)]
        print "%s Tasks have been updated!" % n_tasks[0]

if __name__ == "__main__":
    app_config, options = get_configuration()
    run(app_config, options)
<|endoftext|>


<commit_before>#!/usr/bin/env python
"""Menu bar and menus for the TUI application.

To Do:
- See about Windows conventions, for example should we be using
  the system menu for the TUI menu? Is the quit command Exit
  and do we need to specifically specify it, or is it automatic
  the way Quit is on MacOS X.

History:
2002-12-05 ROwen    Added the Help menu.
2002-12-23 ROwen    Removed unneded local variable; thanks to pychecker.
2003-02-27 ROwen    Changed connect to use the new connection dialog
                    (which is supplied as a normal window) and to disable
                    Disconnect when the connection is already closed.
2003-03-20 ROwen    Added Inst menu.
2003-03-21 ROwen    Modified help to use urlparse.urljoin.
2003-03-25 ROwen    Added the ability to rebuild the automatic menus
2003-06-09 ROwen    Removed most arguments.
2003-10-10 ROwen    Modified to use RO.Comm.HubConnection.
2003-10-14 ROwen    Modified help menu to reflect Overview->Introduction.
2003-12-04 ROwen    Changed doCall to callNow in call to addStateCallback.
2003-12-17 ROwen    Renamed to MainMenu.
2004-02-04 ROwen    Modified _HelpURL to match minor help reorg.
2004-02-17 ROwen    Changed addTUIMenu to support extra windows (a few have
                    predefined positions; the rest are listed alphabetically).
                    Changed buildAutoMenus to buildMenus and made it
                    also build the TUI menu.
2004-07-19 ROwen    Added Scripts menu. Made sure Quit always quits.
2004-08-11 ROwen    .
2004-08-11 ROwen    Modified for updated RO.Wdg.CtxMenu and new RO.Wdg.Constants
2004-08-25 ROwen    Bug fix: help was broken due to misuse of new RO.Wdg.Constants.
2004-09-03 ROwen    Modified for RO.Wdg._joinHelpURL -> RO.Constants._joinHelpURL.
2004-10-06 ROwen    Modified to not tie up the event loop while opening html help.
                    Renamed from MainMenu and totally overhauled. In progress!
2005-03-30 ROwen    Added Guide menu.
2005-06-08 ROwen    Changed MenuBar to a new-style class.
2005-07-07 ROwen    Modified for moved RO.TkUtil.
2006-03-09 ROwen    Modified to avoid "improper exit" complaints
                    on Windows by explicitly destroying root on quit.
2009-03-31 ROwen    Modified for tuiModel.root -> tuiModel.tkRoot.
"""
import Tkinter
import RO.Alg
import RO.Comm.BrowseURL
import RO.Constants
import RO.OS
import RO.TkUtil
import RO.Wdg
import TUI.ScriptMenu

class MenuBar(object):
    """Create TUI's application menu bar.

    Call only after all windows have been created
    (else the auto menus Inst, etc. will be missing entries).

    Note: if MacOS X Aqua, then the root["menu"] is set
    so that the menu bar applies to all windows.
    Otherwise the menu bar appears in the Status window
    and thus has no Edit menu (since it would only apply to widgets
    in the Status window).
    """
    def __init__(self):
        self.tuiModel = TUI.TUIModel.Model()
        self.tlSet = self.tuiModel.tlSet
        self.connection = self.tuiModel.dispatcher.connection

        self.wsys = RO.TkUtil.getWindowingSystem()

        # determine parent toplevel and create menu for it
        if self.wsys == RO.TkUtil.WSysAqua:
            parentTL = self.tuiModel.tkRoot
        else:
            parentTL = self.tlSet.getToplevel("None.Status")
        self.parentMenu = Tkinter.Menu(parentTL)
        parentTL["menu"] = self.parentMenu

        self.tuiMenu = None
        self.connectMenuIndex = None

        # add the TUI menu
        self.addTUIMenu()

        self.connection.addStateCallback(self._connStateFunc, callNow = True)

        # if Mac Aqua, add an edit menu
        if self.wsys == RO.TkUtil.WSysAqua:
            self.addMacEditMenu()

        # add the automatic menus
        for menuTitle in ("TCC", "Inst", "Guide", "Misc"):
            self.addAutoMenu(menuTitle)

        # add the script menu
        self.addScriptMenu()

        # add the help menu
        self.addHelpMenu()

    def addAutoMenu(self, name):
        """Add automatically built menu
        """
        mnu = Tkinter.Menu(self.parentMenu, tearoff=False)
        tlNames = self.tlSet.getNames(name + ".")
        for tlName in tlNames:
            self._addWindow(tlName, mnu)
        self.parentMenu.add_cascade(label=name, menu=mnu)

    def addHelpMenu(self):
        mnu = Tkinter.Menu(self.parentMenu, name = "help", tearoff=False)
        for itemName, url in (
            ("TUI Help", "index.html"),
            ("Introduction", "Introduction.html"),
            ("Version History", "VersionHistory.html"),
        ):
            mnu.add_command (
                label=itemName,
                command=RO.Alg.GenericCallback(self.doHelp, url),
            )
        self.parentMenu.add_cascade(label="Help", menu=mnu)

    def addMacEditMenu(self):
        mnu = Tkinter.Menu(self.parentMenu)
        for label, accelLet in (
            ("Cut", "X"),
            ("Copy", "C"),
            ("Paste", "V"),
            ("Clear", None),
            ("Select All", "A"),
        ):
            if accelLet:
                accel = "Command-%s" % accelLet
            else:
                accel = None
            if label:
                mnu.add_command(
                    label = label,
                    accelerator = accel,
                    command = RO.Alg.GenericCallback(self.doEditItem, label)
                )
            else:
                mnu.add_separator()
        self.parentMenu.add_cascade(label="Edit", menu=mnu)

    def addScriptMenu(self):
        mnu = TUI.ScriptMenu.getScriptMenu(self.parentMenu)
        self.parentMenu.add_cascade(label="Scripts", menu=mnu)

    def addTUIMenu(self):
        if self.wsys == RO.TkUtil.WSysAqua:
            name = "apple"
        else:
            name = None
        mnu = Tkinter.Menu(self.parentMenu, name=name, tearoff=0)

        # predefined windows: titles of windows
        # whose positions in the TUI menu are predefined
        predef = ["About TUI", "Connect", "Preferences"]
        predef = ["TUI." + name for name in predef]

        # add first batch of predefined entries
        self._addWindow("TUI.About TUI", mnu)
        mnu.add_separator()
        self._addWindow("TUI.Connect", mnu)
        self.connectMenuIndex = mnu.index("end")
        mnu.add_command(label="Disconnect", command=self.doDisconnect)
        mnu.add_command(label="Refresh Display", command=self.doRefresh)
        mnu.add_separator()

        # add non-predefined windows here
        tlNames = self.tlSet.getNames("TUI.")
        for tlName in tlNames:
            if tlName in predef:
                continue
            self._addWindow(tlName, mnu)

        # add the remaining predefined entries
        mnu.add_separator()
        self._addWindow("TUI.Preferences", mnu)
        mnu.add_command(label="Save Window Positions", command=self.doSaveWindowPos)
        if self.wsys == RO.TkUtil.WSysX11:
            mnu.add_separator()
            mnu.add_command(label="Quit", command=self.doQuit)
        elif self.wsys == RO.TkUtil.WSysWin:
            mnu.add_separator()
            mnu.add_command(label="Exit", command=self.doQuit)
        else:
            # Mac already has a Quit item, but when using Twisted it must be
            # manually set to Do The Right Thing...how?
            pass

        self.tuiMenu = mnu
        self.parentMenu.add_cascade(label = "TUI", menu = mnu)

    def doDisconnect(self, *args):
        self.connection.disconnect()
        self.tuiMenu.entryconfigure(self.connectMenuIndex, state="normal")

    def doEditItem(self, name):
        wdg = self.tuiModel.tkRoot.focus_get()
        if not wdg:
            return
        evtStr = "<<%s>>" % (name,)
#       print "do Edit item %s by sending %s to %s" % (name, evtStr, wdg)
        wdg.event_generate(evtStr)

    def doHelp(self, urlSuffix):
        helpURL = RO.Constants._joinHelpURL(urlSuffix)

        RO.Comm.BrowseURL.browseURL(helpURL)

    def doQuit(self):
        try:
            self.doDisconnect()
        finally:
            self.tuiModel.reactor.stop()
            if RO.OS.PlatformName == "win":
                # avoid "improper exit" complaints
                self.tuiModel.tkRoot.destroy()

    def doRefresh(self):
        """Refresh all automatic variables.
        """
        self.tuiModel.dispatcher.refreshAllVar(startOver=True)

    def doSaveWindowPos(self):
        self.tlSet.writeGeomVisFile()

    def showToplevel(self, tlName):
        self.tlSet.makeVisible(tlName)

    def _addWindow(self, tlName, mnu):
        """Add a toplevel named tlName to the specified menu.
        tlName must be of the form menu.title
        """
        title = tlName.split(".")[-1]
        mnu.add_command(label=title, command=RO.Alg.GenericCallback(self.showToplevel, tlName))

    def _connStateFunc(self, conn):
        """Called whenever the connection changes state"""
        if conn.isConnected():
            self.tuiMenu.entryconfigure(self.connectMenuIndex, state="disabled")
            self.tuiMenu.entryconfigure(self.connectMenuIndex+1, state="normal")
            self.tuiMenu.entryconfigure(self.connectMenuIndex+2, state="normal")
        else:
            self.tuiMenu.entryconfigure(self.connectMenuIndex, state="normal")
            self.tuiMenu.entryconfigure(self.connectMenuIndex+1, state="disabled")
            self.tuiMenu.entryconfigure(self.connectMenuIndex+2, state="disabled")

if __name__ == "__main__":
    import TUI.Base.TestDispatcher

    testDispatcher = TUI.Base.TestDispatcher.TestDispatcher("tcc")
    tuiModel = testDispatcher.tuiModel

    menuBar = MenuBar()

    tuiModel.reactor.run()
<commit_msg>Fixed Quit on MacOS X using a trick provided by Kevin Walzer.<commit_after>#!/usr/bin/env python
"""Menu bar and menus for the TUI application.

To Do:
- See about Windows conventions, for example should we be using
  the system menu for the TUI menu? Is the quit command Exit
  and do we need to specifically specify it, or is it automatic
  the way Quit is on MacOS X.

History:
2002-12-05 ROwen    Added the Help menu.
2002-12-23 ROwen    Removed unneded local variable; thanks to pychecker.
2003-02-27 ROwen    Changed connect to use the new connection dialog
                    (which is supplied as a normal window) and to disable
                    Disconnect when the connection is already closed.
2003-03-20 ROwen    Added Inst menu.
2003-03-21 ROwen    Modified help to use urlparse.urljoin.
2003-03-25 ROwen    Added the ability to rebuild the automatic menus
2003-06-09 ROwen    Removed most arguments.
2003-10-10 ROwen    Modified to use RO.Comm.HubConnection.
2003-10-14 ROwen    Modified help menu to reflect Overview->Introduction.
2003-12-04 ROwen    Changed doCall to callNow in call to addStateCallback.
2003-12-17 ROwen    Renamed to MainMenu.
2004-02-04 ROwen    Modified _HelpURL to match minor help reorg.
2004-02-17 ROwen    Changed addTUIMenu to support extra windows (a few have
                    predefined positions; the rest are listed alphabetically).
                    Changed buildAutoMenus to buildMenus and made it
                    also build the TUI menu.
2004-07-19 ROwen    Added Scripts menu. Made sure Quit always quits.
2004-08-11 ROwen    .
2004-08-11 ROwen    Modified for updated RO.Wdg.CtxMenu and new RO.Wdg.Constants
2004-08-25 ROwen    Bug fix: help was broken due to misuse of new RO.Wdg.Constants.
2004-09-03 ROwen    Modified for RO.Wdg._joinHelpURL -> RO.Constants._joinHelpURL.
2004-10-06 ROwen    Modified to not tie up the event loop while opening html help.
                    Renamed from MainMenu and totally overhauled. In progress!
2005-03-30 ROwen    Added Guide menu.
2005-06-08 ROwen    Changed MenuBar to a new-style class.
2005-07-07 ROwen    Modified for moved RO.TkUtil.
2006-03-09 ROwen    Modified to avoid "improper exit" complaints
                    on Windows by explicitly destroying root on quit.
2009-03-31 ROwen    Modified for tuiModel.root -> tuiModel.tkRoot.
"""
import Tkinter
import RO.Alg
import RO.Comm.BrowseURL
import RO.Constants
import RO.OS
import RO.TkUtil
import RO.Wdg
import TUI.ScriptMenu

class MenuBar(object):
    """Create TUI's application menu bar.

    Call only after all windows have been created
    (else the auto menus Inst, etc. will be missing entries).

    Note: if MacOS X Aqua, then the root["menu"] is set
    so that the menu bar applies to all windows.
    Otherwise the menu bar appears in the Status window
    and thus has no Edit menu (since it would only apply to widgets
    in the Status window).
    """
    def __init__(self):
        self.tuiModel = TUI.TUIModel.Model()
        self.tlSet = self.tuiModel.tlSet
        self.connection = self.tuiModel.dispatcher.connection

        self.wsys = RO.TkUtil.getWindowingSystem()

        # determine parent toplevel and create menu for it
        if self.wsys == RO.TkUtil.WSysAqua:
            parentTL = self.tuiModel.tkRoot
        else:
            parentTL = self.tlSet.getToplevel("None.Status")
        self.parentMenu = Tkinter.Menu(parentTL)
        parentTL["menu"] = self.parentMenu

        self.tuiMenu = None
        self.connectMenuIndex = None

        # add the TUI menu
        self.addTUIMenu()

        self.connection.addStateCallback(self._connStateFunc, callNow = True)

        # if Mac Aqua, add an edit menu
        if self.wsys == RO.TkUtil.WSysAqua:
            self.addMacEditMenu()

        # add the automatic menus
        for menuTitle in ("TCC", "Inst", "Guide", "Misc"):
            self.addAutoMenu(menuTitle)

        # add the script menu
        self.addScriptMenu()

        # add the help menu
        self.addHelpMenu()

    def addAutoMenu(self, name):
        """Add automatically built menu
        """
        mnu = Tkinter.Menu(self.parentMenu, tearoff=False)
        tlNames = self.tlSet.getNames(name + ".")
        for tlName in tlNames:
            self._addWindow(tlName, mnu)
        self.parentMenu.add_cascade(label=name, menu=mnu)

    def addHelpMenu(self):
        mnu = Tkinter.Menu(self.parentMenu, name = "help", tearoff=False)
        for itemName, url in (
            ("TUI Help", "index.html"),
            ("Introduction", "Introduction.html"),
            ("Version History", "VersionHistory.html"),
        ):
            mnu.add_command (
                label=itemName,
                command=RO.Alg.GenericCallback(self.doHelp, url),
            )
        self.parentMenu.add_cascade(label="Help", menu=mnu)

    def addMacEditMenu(self):
        mnu = Tkinter.Menu(self.parentMenu)
        for label, accelLet in (
            ("Cut", "X"),
            ("Copy", "C"),
            ("Paste", "V"),
            ("Clear", None),
            ("Select All", "A"),
        ):
            if accelLet:
                accel = "Command-%s" % accelLet
            else:
                accel = None
            if label:
                mnu.add_command(
                    label = label,
                    accelerator = accel,
                    command = RO.Alg.GenericCallback(self.doEditItem, label)
                )
            else:
                mnu.add_separator()
        self.parentMenu.add_cascade(label="Edit", menu=mnu)

    def addScriptMenu(self):
        mnu = TUI.ScriptMenu.getScriptMenu(self.parentMenu)
        self.parentMenu.add_cascade(label="Scripts", menu=mnu)

    def addTUIMenu(self):
        if self.wsys == RO.TkUtil.WSysAqua:
            name = "apple"
        else:
            name = None
        mnu = Tkinter.Menu(self.parentMenu, name=name, tearoff=0)

        # predefined windows: titles of windows
        # whose positions in the TUI menu are predefined
        predef = ["About TUI", "Connect", "Preferences"]
        predef = ["TUI." + name for name in predef]

        # add first batch of predefined entries
        self._addWindow("TUI.About TUI", mnu)
        mnu.add_separator()
        self._addWindow("TUI.Connect", mnu)
        self.connectMenuIndex = mnu.index("end")
        mnu.add_command(label="Disconnect", command=self.doDisconnect)
        mnu.add_command(label="Refresh Display", command=self.doRefresh)
        mnu.add_separator()

        # add non-predefined windows here
        tlNames = self.tlSet.getNames("TUI.")
        for tlName in tlNames:
            if tlName in predef:
                continue
            self._addWindow(tlName, mnu)

        # add the remaining predefined entries
        mnu.add_separator()
        self._addWindow("TUI.Preferences", mnu)
        mnu.add_command(label="Save Window Positions", command=self.doSaveWindowPos)
        if self.wsys == RO.TkUtil.WSysX11:
            mnu.add_separator()
            mnu.add_command(label="Quit", command=self.doQuit)
        elif self.wsys == RO.TkUtil.WSysWin:
            mnu.add_separator()
            mnu.add_command(label="Exit", command=self.doQuit)
        else:
            # Mac already has a Quit item. Unfortunately, when using Twisted it has no effect and it cannot be
            # programmed in the usual tcl/tk way. However, it can be caught as follows, with thanks to
            # Kevin Walzer for this nice trick:
            self.tuiModel.tkRoot.createcommand("exit", self.doQuit)

        self.tuiMenu = mnu
        self.parentMenu.add_cascade(label = "TUI", menu = mnu)

    def doDisconnect(self, *args):
        self.connection.disconnect()
        self.tuiMenu.entryconfigure(self.connectMenuIndex, state="normal")

    def doEditItem(self, name):
        wdg = self.tuiModel.tkRoot.focus_get()
        if not wdg:
            return
        evtStr = "<<%s>>" % (name,)
#       print "do Edit item %s by sending %s to %s" % (name, evtStr, wdg)
        wdg.event_generate(evtStr)

    def doHelp(self, urlSuffix):
        helpURL = RO.Constants._joinHelpURL(urlSuffix)

        RO.Comm.BrowseURL.browseURL(helpURL)

    def doQuit(self):
        try:
            self.doDisconnect()
        finally:
            self.tuiModel.reactor.stop()
            if RO.OS.PlatformName == "win":
                # avoid "improper exit" complaints
                self.tuiModel.tkRoot.destroy()

    def doRefresh(self):
        """Refresh all automatic variables.
        """
        self.tuiModel.dispatcher.refreshAllVar(startOver=True)

    def doSaveWindowPos(self):
        self.tlSet.writeGeomVisFile()

    def showToplevel(self, tlName):
        self.tlSet.makeVisible(tlName)

    def _addWindow(self, tlName, mnu):
        """Add a toplevel named tlName to the specified menu.
        tlName must be of the form menu.title
        """
        title = tlName.split(".")[-1]
        mnu.add_command(label=title, command=RO.Alg.GenericCallback(self.showToplevel, tlName))

    def _connStateFunc(self, conn):
        """Called whenever the connection changes state"""
        if conn.isConnected():
            self.tuiMenu.entryconfigure(self.connectMenuIndex, state="disabled")
            self.tuiMenu.entryconfigure(self.connectMenuIndex+1, state="normal")
            self.tuiMenu.entryconfigure(self.connectMenuIndex+2, state="normal")
        else:
            self.tuiMenu.entryconfigure(self.connectMenuIndex, state="normal")
            self.tuiMenu.entryconfigure(self.connectMenuIndex+1, state="disabled")
            self.tuiMenu.entryconfigure(self.connectMenuIndex+2, state="disabled")

if __name__ == "__main__":
    import TUI.Base.TestDispatcher

    testDispatcher = TUI.Base.TestDispatcher.TestDispatcher("tcc")
    tuiModel = testDispatcher.tuiModel

    menuBar = MenuBar()

    tuiModel.reactor.run()
<|endoftext|>


<commit_before>#
#   Pyrex - Errors
#

import sys
from Cython.Utils import open_new_file

class PyrexError(Exception):
    pass

class PyrexWarning(Exception):
    pass

def context(position):
    source = position[0]
    assert not (isinstance(source, unicode) or isinstance(source, str)), (
        "Please replace filename strings with Scanning.FileSourceDescriptor instances %r" % source)
    F = list(source.get_lines())
    s = ''.join(F[min(0, position[1]-6):position[1]])
    s += ' '*(position[2]-1) + '^'
    s = '-'*60 + '\n...\n' + s + '\n' + '-'*60 + '\n'
    return s

class CompileError(PyrexError):

    def __init__(self, position = None, message = ""):
        self.position = position
        self.message = message
        if position:
            pos_str = "%s:%d:%d: " % (position[0].get_description(), position[1], position[2])
            cont = context(position)
        else:
            pos_str = ""
            cont = ''
        Exception.__init__(self, '\nError converting Pyrex file to C:\n' + cont + '\n' + pos_str + message )

class CompileWarning(PyrexWarning):

    def __init__(self, position = None, message = ""):
        self.position = position
        self.message = message
        if position:
            pos_str = "%s:%d:%d: " % position
        else:
            pos_str = ""
        Exception.__init__(self, pos_str + message)

class InternalError(Exception):
    # If this is ever raised, there is a bug in the compiler.

    def __init__(self, message):
        Exception.__init__(self, "Internal compiler error: %s"
            % message)

listing_file = None
num_errors = 0
echo_file = None

def open_listing_file(path, echo_to_stderr = 1):
    # Begin a new error listing. If path is None, no file
    # is opened, the error counter is just reset.
    global listing_file, num_errors, echo_file
    if path is not None:
        listing_file = open_new_file(path)
    else:
        listing_file = None
    if echo_to_stderr:
        echo_file = sys.stderr
    else:
        echo_file = None
    num_errors = 0

def close_listing_file():
    global listing_file
    if listing_file:
        listing_file.close()
        listing_file = None

def error(position, message):
    #print "Errors.error:", repr(position), repr(message) ###
    global num_errors
    err = CompileError(position, message)
    line = "%s\n" % err
    if listing_file:
        listing_file.write(line)
    if echo_file:
        echo_file.write(line)
    num_errors = num_errors + 1
    return err

LEVEL=1 # warn about all errors level 1 or higher

def warning(position, message, level=0):
    if level < LEVEL:
        return
    warn = CompileWarning(position, message)
    line = "warning: %s\n" % warn
    if listing_file:
        listing_file.write(line)
    if echo_file:
        echo_file.write(line)
    return warn
<commit_msg>SourceDescriptor-related bug<commit_after>#
#   Pyrex - Errors
#

import sys
from Cython.Utils import open_new_file

class PyrexError(Exception):
    pass

class PyrexWarning(Exception):
    pass

def context(position):
    source = position[0]
    assert not (isinstance(source, unicode) or isinstance(source, str)), (
        "Please replace filename strings with Scanning.FileSourceDescriptor instances %r" % source)
    F = list(source.get_lines())
    s = ''.join(F[min(0, position[1]-6):position[1]])
    s += ' '*(position[2]-1) + '^'
    s = '-'*60 + '\n...\n' + s + '\n' + '-'*60 + '\n'
    return s

class CompileError(PyrexError):

    def __init__(self, position = None, message = ""):
        self.position = position
        self.message = message
        if position:
            pos_str = "%s:%d:%d: " % (position[0].get_description(), position[1], position[2])
            cont = context(position)
        else:
            pos_str = ""
            cont = ''
        Exception.__init__(self, '\nError converting Pyrex file to C:\n' + cont + '\n' + pos_str + message )

class CompileWarning(PyrexWarning):

    def __init__(self, position = None, message = ""):
        self.position = position
        self.message = message
        if position:
            pos_str = "%s:%d:%d: " % (position[0].get_description(), position[1], position[2])
        else:
            pos_str = ""
        Exception.__init__(self, pos_str + message)

class InternalError(Exception):
    # If this is ever raised, there is a bug in the compiler.

    def __init__(self, message):
        Exception.__init__(self, "Internal compiler error: %s"
            % message)

listing_file = None
num_errors = 0
echo_file = None

def open_listing_file(path, echo_to_stderr = 1):
    # Begin a new error listing. If path is None, no file
    # is opened, the error counter is just reset.
    global listing_file, num_errors, echo_file
    if path is not None:
        listing_file = open_new_file(path)
    else:
        listing_file = None
    if echo_to_stderr:
        echo_file = sys.stderr
    else:
        echo_file = None
    num_errors = 0

def close_listing_file():
    global listing_file
    if listing_file:
        listing_file.close()
        listing_file = None

def error(position, message):
    #print "Errors.error:", repr(position), repr(message) ###
    global num_errors
    err = CompileError(position, message)
    line = "%s\n" % err
    if listing_file:
        listing_file.write(line)
    if echo_file:
        echo_file.write(line)
    num_errors = num_errors + 1
    return err

LEVEL=1 # warn about all errors level 1 or higher

def warning(position, message, level=0):
    if level < LEVEL:
        return
    warn = CompileWarning(position, message)
    line = "warning: %s\n" % warn
    if listing_file:
        listing_file.write(line)
    if echo_file:
        echo_file.write(line)
    return warn
<|endoftext|>


<commit_before>VersionName = "1.6"
VersionDate = "2009-07-06"

VersionStr = " ".join((VersionName, VersionDate))
<commit_msg>Corrected version date.<commit_after>VersionName = "1.6"
VersionDate = "2009-07-09"

VersionStr = " ".join((VersionName, VersionDate))
<|endoftext|>


<commit_before>#!/usr/bin/env python

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

"""
The script can be used to setup a virtual environment for running Firefox UI Tests.
It will automatically install the firefox ui test package, all its dependencies,
and optional packages if specified.

"""

import argparse
import os
import shutil
import subprocess
import sys
import urllib2
import zipfile

# Link to the folder, which contains the zip archives of virtualenv
VIRTUALENV_URL = 'https://github.com/pypa/virtualenv/archive/%(VERSION)s.zip'
VIRTUALENV_VERSION = '12.1.1'

here = os.path.dirname(os.path.abspath(__file__))

venv_script_path = 'Scripts' if sys.platform == 'win32' else 'bin'
venv_activate = os.path.join(venv_script_path, 'activate')
venv_activate_this = os.path.join(venv_script_path, 'activate_this.py')
venv_python_bin = os.path.join(venv_script_path, 'python')

usage_message = """
***********************************************************************
To run the Firefox UI Tests, activate the virtual environment:
    {}{}

See firefox-ui-tests --help for all options

***********************************************************************
"""

def download(url, target):
    """Downloads the specified url to the given target."""
    response = urllib2.urlopen(url)
    with open(target, 'wb') as f:
        f.write(response.read())

    return target

def create_virtualenv(target, python_bin=None):
    script_path = os.path.join(here, 'virtualenv-%s' % VIRTUALENV_VERSION,
                               'virtualenv.py')

    print 'Downloading virtualenv %s' % VIRTUALENV_VERSION
    zip_path = download(VIRTUALENV_URL % {'VERSION': VIRTUALENV_VERSION},
                        os.path.join(here, 'virtualenv.zip'))

    try:
        with zipfile.ZipFile(zip_path, 'r') as f:
            f.extractall(here)

        print 'Creating new virtual environment'
        cmd_args = [sys.executable, script_path, target]

        if python_bin:
            cmd_args.extend(['-p', python_bin])

        subprocess.check_call(cmd_args)
    finally:
        try:
            os.remove(zip_path)
        except OSError:
            pass

        shutil.rmtree(os.path.dirname(script_path), ignore_errors=True)

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-p', '--python',
                        dest='python',
                        metavar='BINARY',
                        help='The Python interpreter to use.')
    parser.add_argument('--strict',
                        dest='strict',
                        default=False,
                        action='store_true',
                        help='Installs exact versions of mozbase packages as'
                             ' listed in requirements.txt ')
    parser.add_argument('--with-optional-packages',
                        dest='with_optional',
                        default=False,
                        action='store_true',
                        help='Installs optional packages for enhanced usability.')
    parser.add_argument('venv',
                        metavar='PATH',
                        help='Path to the environment to be created.')
    args = parser.parse_args()

    # Remove an already existent virtual environment
    if os.path.exists(args.venv):
        print 'Removing already existent virtual environment at: %s' % args.venv
        shutil.rmtree(args.venv, True)

    create_virtualenv(args.venv, python_bin=args.python)

    # Activate the environment
    tps_env = os.path.join(args.venv, venv_activate_this)
    execfile(tps_env, dict(__file__=tps_env))

    # Install Firefox UI tests, dependencies and optional packages
    command = ['pip', 'install', here]
    if args.strict:
        command.extend(['-r', 'requirements.txt'])
    if args.with_optional:
        command.extend(['-r', 'requirements_optional.txt'])

    print 'Installing Firefox UI Tests and dependencies...'
    print 'Command: %s' % command
    subprocess.check_call(command)

    # Print the user instructions
    print usage_message.format('' if sys.platform == 'win32' else 'source ',
                               os.path.join(args.venv, venv_activate))

if __name__ == "__main__":
    main()
<commit_msg>Bug 1209981 - Ensure that create_venv.py uses the requirement files from the script dir. r=automatedtester<commit_after>#!/usr/bin/env python

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

"""
The script can be used to setup a virtual environment for running Firefox UI Tests.
It will automatically install the firefox ui test package, all its dependencies,
and optional packages if specified.

"""

import argparse
import os
import shutil
import subprocess
import sys
import urllib2
import zipfile

# Link to the folder, which contains the zip archives of virtualenv
VIRTUALENV_URL = 'https://github.com/pypa/virtualenv/archive/%(VERSION)s.zip'
VIRTUALENV_VERSION = '12.1.1'

here = os.path.dirname(os.path.abspath(__file__))

venv_script_path = 'Scripts' if sys.platform == 'win32' else 'bin'
venv_activate = os.path.join(venv_script_path, 'activate')
venv_activate_this = os.path.join(venv_script_path, 'activate_this.py')
venv_python_bin = os.path.join(venv_script_path, 'python')

usage_message = """
***********************************************************************
To run the Firefox UI Tests, activate the virtual environment:
    {}{}

See firefox-ui-tests --help for all options

***********************************************************************
"""

def download(url, target):
    """Downloads the specified url to the given target."""
    response = urllib2.urlopen(url)
    with open(target, 'wb') as f:
        f.write(response.read())

    return target

def create_virtualenv(target, python_bin=None):
    script_path = os.path.join(here, 'virtualenv-%s' % VIRTUALENV_VERSION,
                               'virtualenv.py')

    print 'Downloading virtualenv %s' % VIRTUALENV_VERSION
    zip_path = download(VIRTUALENV_URL % {'VERSION': VIRTUALENV_VERSION},
                        os.path.join(here, 'virtualenv.zip'))

    try:
        with zipfile.ZipFile(zip_path, 'r') as f:
            f.extractall(here)

        print 'Creating new virtual environment'
        cmd_args = [sys.executable, script_path, target]

        if python_bin:
            cmd_args.extend(['-p', python_bin])

        subprocess.check_call(cmd_args)
    finally:
        try:
            os.remove(zip_path)
        except OSError:
            pass

        shutil.rmtree(os.path.dirname(script_path), ignore_errors=True)

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-p', '--python',
                        dest='python',
                        metavar='BINARY',
                        help='The Python interpreter to use.')
    parser.add_argument('--strict',
                        dest='strict',
                        default=False,
                        action='store_true',
                        help='Installs exact versions of mozbase packages as'
                             ' listed in requirements.txt ')
    parser.add_argument('--with-optional-packages',
                        dest='with_optional',
                        default=False,
                        action='store_true',
                        help='Installs optional packages for enhanced usability.')
    parser.add_argument('venv',
                        metavar='PATH',
                        help='Path to the environment to be created.')
    args = parser.parse_args()

    # Remove an already existent virtual environment
    if os.path.exists(args.venv):
        print 'Removing already existent virtual environment at: %s' % args.venv
        shutil.rmtree(args.venv, True)

    create_virtualenv(args.venv, python_bin=args.python)

    # Activate the environment
    tps_env = os.path.join(args.venv, venv_activate_this)
    execfile(tps_env, dict(__file__=tps_env))

    # Install Firefox UI tests, dependencies and optional packages
    command = ['pip', 'install', here]
    if args.strict:
        command.extend(['-r', os.path.join(here, 'requirements.txt')])
    if args.with_optional:
        command.extend(['-r', os.path.join(here, 'requirements_optional.txt')])

    print 'Installing Firefox UI Tests and dependencies...'
    print 'Command: %s' % command
    subprocess.check_call(command)

    # Print the user instructions
    print usage_message.format('' if sys.platform == 'win32' else 'source ',
                               os.path.join(args.venv, venv_activate))

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


<commit_before>import elementary
import evas
import ecore
import psutil
import os
import getpass
import sortedlist as sl

EXPAND_BOTH = evas.EVAS_HINT_EXPAND, evas.EVAS_HINT_EXPAND
FILL_BOTH = evas.EVAS_HINT_FILL, evas.EVAS_HINT_FILL

class TaskManager(elementary.Box):
    def __init__(self, parent):
        elementary.Box.__init__(self, parent.mainWindow)
        self.win = win = parent.mainWindow
        self.rent = parent
        self.appstokill = []
        self.process = {}

        self.loop = ecore.timer_add(0.5, self.update)

        lbl = elementary.Label(self.win)
        lbl.text = "Running Processes:"
        lbl.show()

        scr = elementary.Scroller(self.win)
        scr.size_hint_weight = EXPAND_BOTH
        scr.size_hint_align = FILL_BOTH

        titles = [("PID", True), ("User", True), ("CPU", True), ("Memory", True), ("Process Name", True), ("", False)]

        self.slist = slist = sl.SortedList(self, titles=titles,   size_hint_weight=EXPAND_BOTH,
            size_hint_align=FILL_BOTH, homogeneous=True)
        scr.content = slist
        scr.show()

        slist.show()

        self.processes_build()

        kills = elementary.Button(self.win)
        kills.text = "Kill Selected Applications"
        kills.callback_clicked_add(self.kill_selected)
        kills.show()

        sep = elementary.Separator(self.win)
        sep.show()

        bck = elementary.Button(win)
        bck.text = "Back"
        bck.callback_clicked_add(lambda x: parent.nf.item_pop())
        bck.show()

        bbox = elementary.Box(win)
        bbox.horizontal = True
        bbox.pack_end(kills)
        bbox.pack_end(sep)
        bbox.pack_end(bck)
        bbox.show()

        self.pack_end(lbl)
        self.pack_end(scr)
        self.pack_end(bbox)

    def update(self):
        self.processes_build()
        for p in self.process:
            self.process[p].update()
        self.slist.update()
        return 1

    def run_command(self, bnt, window, command):
        if window:
            window.hide()
        cmd = ecore.Exe(command)
        cmd.on_del_event_add(self.processes_build)

    def kill_selected( self, bt ):
        for pid in self.appstokill:
            self.kill_process(False, pid)

    def check_sel( self, ck ):
        if ck.state_get():
            self.appstokill.append(ck.text)
        else:
            self.appstokill.remove(ck.text)
        #print self.appstokill

    def kill_process( self, bt, pid ):
        self.run_command(False, False, "kill -9 %s"%pid)
        self.slist.row_unpack(self.process[pid], True)
        self.process.pop(pid, None)

    def processes_build( self, cmd=False, arg=False ):
        #print "cmd %s , arg %s"%(cmd, arg)

        tmp = psutil.get_process_list()
        currentpids = []
        pidstoremove = []
        for p in tmp:
            if p.username == getpass.getuser():
                currentpids.append(p.pid)
                if p.pid not in self.process:
                    cess = Process(self, p)
                    self.process[p.pid] = cess
                    self.slist.row_pack(cess, sort=False)
        for pid in self.process:
            if pid not in currentpids:
                self.slist.row_unpack(self.process[pid], True)
                pidstoremove.append(pid)
        for pid in pidstoremove:
            self.process.pop(pid, None)

class Process(list):
    def __init__(self, parent, data):
        self.win = parent.win
        self.dt = data

        pd = str(data.pid)
        #while len(pd) < 8:
        #    pd = " %s"%pd

        pid = elementary.Check(self.win)
        pid.text = pd
        pid.callback_changed_add(parent.check_sel)
        pid.show()

        pname = elementary.Label(self.win)
        pname.text = data.name[0:25]
        pname.show()

        user = elementary.Label(self.win)
        user.text = data.username
        user.show()

        self.cpu = cpu = elementary.Label(self.win)
        cpu.text = str(data.get_cpu_percent(interval=0))
        cpu.show()

        self.mem = mem = elementary.Label(self.win)
        mem.text = "%.2f"%data.get_memory_percent()
        mem.show()

        bt = elementary.Button(self.win)
        bt.text = "Kill Process"
        bt.callback_pressed_add(parent.kill_process, data.pid)
        bt.show()

        self.append(pid)
        self.append(user)
        self.append(cpu)
        self.append(mem)
        self.append(pname)
        self.append(bt)

    def update(self):
        #print str(self.dt.get_cpu_percent(interval=0))
        self.cpu.text = str(self.dt.get_cpu_percent(interval=0))
        #print self.dt.get_memory_percent()
        self.mem.text = "%.2f"%self.dt.get_memory_percent()
<commit_msg>Fixed a issue with kill all selected.<commit_after>import elementary
import evas
import ecore
import psutil
import os
import getpass
import sortedlist as sl

EXPAND_BOTH = evas.EVAS_HINT_EXPAND, evas.EVAS_HINT_EXPAND
FILL_BOTH = evas.EVAS_HINT_FILL, evas.EVAS_HINT_FILL

class TaskManager(elementary.Box):
    def __init__(self, parent):
        elementary.Box.__init__(self, parent.mainWindow)
        self.win = win = parent.mainWindow
        self.rent = parent
        self.appstokill = []
        self.process = {}

        self.loop = ecore.timer_add(0.5, self.update)

        lbl = elementary.Label(self.win)
        lbl.text = "Running Processes:"
        lbl.show()

        scr = elementary.Scroller(self.win)
        scr.size_hint_weight = EXPAND_BOTH
        scr.size_hint_align = FILL_BOTH

        titles = [("PID", True), ("User", True), ("CPU", True), ("Memory", True), ("Process Name", True), ("", False)]

        self.slist = slist = sl.SortedList(self, titles=titles,   size_hint_weight=EXPAND_BOTH,
            size_hint_align=FILL_BOTH, homogeneous=True)
        scr.content = slist
        scr.show()

        slist.show()

        self.processes_build()

        kills = elementary.Button(self.win)
        kills.text = "Kill Selected Applications"
        kills.callback_clicked_add(self.kill_selected)
        kills.show()

        sep = elementary.Separator(self.win)
        sep.show()

        bck = elementary.Button(win)
        bck.text = "Back"
        bck.callback_clicked_add(lambda x: parent.nf.item_pop())
        bck.show()

        bbox = elementary.Box(win)
        bbox.horizontal = True
        bbox.pack_end(kills)
        bbox.pack_end(sep)
        bbox.pack_end(bck)
        bbox.show()

        self.pack_end(lbl)
        self.pack_end(scr)
        self.pack_end(bbox)

    def update(self):
        self.processes_build()
        for p in self.process:
            self.process[p].update()
        self.slist.update()
        return 1

    def run_command(self, bnt, window, command):
        if window:
            window.hide()
        cmd = ecore.Exe(command)
        cmd.on_del_event_add(self.processes_build)

    def kill_selected( self, bt ):
        for pid in self.appstokill:
            self.kill_process(False, pid)

    def check_sel( self, ck ):
        if ck.state_get():
            self.appstokill.append(ck.text)
        else:
            self.appstokill.remove(ck.text)
        #print self.appstokill

    def kill_process( self, bt, pid ):
        self.run_command(False, False, "kill -9 %s"%pid)

    def processes_build( self, cmd=False, arg=False ):
        #print "cmd %s , arg %s"%(cmd, arg)

        tmp = psutil.get_process_list()
        currentpids = []
        pidstoremove = []
        try:
            for p in tmp:
                if p.username == getpass.getuser():
                    currentpids.append(p.pid)
                    if p.pid not in self.process:
                        cess = Process(self, p)
                        self.process[p.pid] = cess
                        self.slist.row_pack(cess, sort=False)
        except:
            print "Hit an exception. Might want to look into that if stuff isn't working right"
        for pid in self.process:
            if pid not in currentpids:
                self.slist.row_unpack(self.process[pid], True)
                pidstoremove.append(pid)
        for pid in pidstoremove:
            self.process.pop(pid, None)

class Process(list):
    def __init__(self, parent, data):
        self.win = parent.win
        self.dt = data

        pd = str(data.pid)
        #while len(pd) < 8:
        #    pd = " %s"%pd

        pid = elementary.Check(self.win)
        pid.text = pd
        pid.callback_changed_add(parent.check_sel)
        pid.show()

        pname = elementary.Label(self.win)
        pname.text = data.name[0:25]
        pname.show()

        user = elementary.Label(self.win)
        user.text = data.username
        user.show()

        self.cpu = cpu = elementary.Label(self.win)
        cpu.text = str(data.get_cpu_percent(interval=0))
        cpu.show()

        self.mem = mem = elementary.Label(self.win)
        mem.text = "%.2f"%data.get_memory_percent()
        mem.show()

        bt = elementary.Button(self.win)
        bt.text = "Kill Process"
        bt.callback_pressed_add(parent.kill_process, data.pid)
        bt.show()

        self.append(pid)
        self.append(user)
        self.append(cpu)
        self.append(mem)
        self.append(pname)
        self.append(bt)

    def update(self):
        #print str(self.dt.get_cpu_percent(interval=0))
        self.cpu.text = str(self.dt.get_cpu_percent(interval=0))
        #print self.dt.get_memory_percent()
        self.mem.text = "%.2f"%self.dt.get_memory_percent()
<|endoftext|>


<commit_before>import logging

from django.core.management.base import BaseCommand

import django.conf
django.conf.settings.CELERY_ALWAYS_EAGER = True

import mysite.search.tasks
import mysite.customs.bugtrackers.roundup_general
import mysite.customs.bugtrackers
import mysite.search.tasks.launchpad_tasks

import mysite.customs.miro
import mysite.customs.bugtrackers.trac
import mysite.customs.bugtrackers.gnome_love
import mysite.customs.bugtrackers.fedora_fitfinish
import mysite.customs.bugtrackers.mozilla
import mysite.customs.bugtrackers.wikimedia
import mysite.customs.bugtrackers.kde
import mysite.customs.bugtrackers.opensolaris

### All this code runs synchronously once a day.
### For now, we can crawl all the bug trackers in serial.

### One day, though, we will crawl so many bug trackers that it will take
### too long.

### I suggest that, at that point, we fork a number of worker processes, and
### turn these lists into a queue or something. That should be easy with the
### multiprocessing module. Then we can do N at once.

### We could do something smart with statistics, detecting the average
### refresh time within the bug tracker of a bug, then polling at some
### approximation of that rate. (But, really, why bother?)

### Since most of the time we're waiting on the network, we could also use
### Twisted or Stackless Python or something. That would be super cool, too.
### If somone can show me how to migrate this codebase to it, that'd be neat.
### I'm unlikely to look into it myself, though.

### (If at some point we start indexing absolutely every bug in free and open
### source software, then the above ideas will actually become meaningful.)

### -- New Age Asheesh, 2010-05-31.

class Command(BaseCommand):
    help = "Call this once a day to make sure we run Bug search-related nightly jobs."

    def update_bugzilla_trackers(self):
        bugzilla_trackers = {
            'Miro':
                mysite.customs.miro.grab_miro_bugs,
            'KDE junior jobs':
                mysite.customs.bugtrackers.kde.grab,
            'Wikimedia easy bugs':
                mysite.customs.bugtrackers.wikimedia.grab,
            'GNOME Love':
                mysite.customs.bugtrackers.gnome_love.grab,
            'Mozilla "good first bug"s':
                mysite.customs.bugtrackers.mozilla.grab,

            # FIXME
            # Really, the Bugzilla import code should be reworked to be as
            # clean and tidy as the Mercurial/Python/Roundup stuff, with
            # an abstract class with a .update() method.
            # Then simple sub-classes can handle each of the different projects'
            # details.

            # What the heck is up with the Fedora code being
            # special-cased like this? Well, I'll clean it up another day,
            # so long as it seems to work right now.
            'Fedora "fit and finish" new bugs':
                mysite.search.tasks.bugzilla_instances.learn_about_new_fedora_fit_and_finish_bugs,

            'Fedora "fit and finish" refreshing old bugs':
                mysite.search.tasks.bugzilla_instances.refresh_all_fedora_fit_and_finish_bugs,
            }

        for bugzilla_tracker in bugzilla_trackers:
            logging.info("Refreshing bugs from %s." % bugzilla_tracker)
            call_me = bugzilla_trackers[bugzilla_tracker]
            call_me()

    def find_and_update_enabled_roundup_trackers(self):
        enabled_roundup_trackers = []

        ### First, the "find" step
        for thing_name in dir(mysite.customs.bugtrackers.roundup_general):
            thing = getattr(mysite.customs.bugtrackers.roundup_general,
                            thing_name)
            if hasattr(thing, 'enabled'):
                if getattr(thing, 'enabled'):
                    enabled_roundup_trackers.append(thing)

        ### Okay, now update!
        for thing in enabled_roundup_trackers:
            logging.info("[Roundup] About to update %s" % thing)
            instantiated = thing()
            instantiated.update()

    def update_trac_instances(self):
        # Trac instances' update functions
        # Note that each Trac instance has two such functions for now. It would be
        # good to rework the Trac code so it looks more like the RoundupTracker
        # code, with just one .update() method. Another day.
        trac_instance_functions_to_call = [
            # Sugar
            mysite.search.tasks.trac_instances.learn_about_new_sugar_easy_bugs,
            mysite.search.tasks.trac_instances.refresh_all_sugar_easy_bugs,
            # Twisted
            mysite.search.tasks.trac_instances.learn_about_new_easy_twisted_bugs,
            mysite.search.tasks.trac_instances.refresh_all_twisted_bugs,
        ]
        for callable in trac_instance_functions_to_call:
            callable()

    def update_launchpad_hosted_projects(self):
        ### For Launchpad:
        # First, we ask the projects' bug trackers if there are new bugs we should know about
        mysite.search.tasks.launchpad_tasks.refresh_bugs_from_all_indexed_launchpad_projects()
        # Second, we go through our *own* database of Launchpad-sourced bugs, and make sure they are all up to date
        mysite.search.tasks.launchpad_tasks.refresh_all_launchpad_bugs()

    def update_opensolaris_osnet(self):
        mysite.customs.bugtrackers.opensolaris.grab()

    def handle(self, *args, **options):
        self.update_opensolaris_osnet()
        self.update_launchpad_hosted_projects()
        self.update_trac_instances()
        self.find_and_update_enabled_roundup_trackers()
        self.update_bugzilla_trackers()

<commit_msg>Add new-style Trac instance(s) to search_daily_tasks.<commit_after>import logging

from django.core.management.base import BaseCommand

import django.conf
django.conf.settings.CELERY_ALWAYS_EAGER = True

import mysite.search.tasks
import mysite.customs.bugtrackers.roundup_general
import mysite.customs.bugtrackers
import mysite.search.tasks.launchpad_tasks

import mysite.customs.miro
import mysite.customs.bugtrackers.trac
import mysite.customs.bugtrackers.gnome_love
import mysite.customs.bugtrackers.fedora_fitfinish
import mysite.customs.bugtrackers.mozilla
import mysite.customs.bugtrackers.wikimedia
import mysite.customs.bugtrackers.kde
import mysite.customs.bugtrackers.opensolaris

### All this code runs synchronously once a day.
### For now, we can crawl all the bug trackers in serial.

### One day, though, we will crawl so many bug trackers that it will take
### too long.

### I suggest that, at that point, we fork a number of worker processes, and
### turn these lists into a queue or something. That should be easy with the
### multiprocessing module. Then we can do N at once.

### We could do something smart with statistics, detecting the average
### refresh time within the bug tracker of a bug, then polling at some
### approximation of that rate. (But, really, why bother?)

### Since most of the time we're waiting on the network, we could also use
### Twisted or Stackless Python or something. That would be super cool, too.
### If somone can show me how to migrate this codebase to it, that'd be neat.
### I'm unlikely to look into it myself, though.

### (If at some point we start indexing absolutely every bug in free and open
### source software, then the above ideas will actually become meaningful.)

### -- New Age Asheesh, 2010-05-31.

class Command(BaseCommand):
    help = "Call this once a day to make sure we run Bug search-related nightly jobs."

    def update_bugzilla_trackers(self):
        bugzilla_trackers = {
            'Miro':
                mysite.customs.miro.grab_miro_bugs,
            'KDE junior jobs':
                mysite.customs.bugtrackers.kde.grab,
            'Wikimedia easy bugs':
                mysite.customs.bugtrackers.wikimedia.grab,
            'GNOME Love':
                mysite.customs.bugtrackers.gnome_love.grab,
            'Mozilla "good first bug"s':
                mysite.customs.bugtrackers.mozilla.grab,

            # FIXME
            # Really, the Bugzilla import code should be reworked to be as
            # clean and tidy as the Mercurial/Python/Roundup stuff, with
            # an abstract class with a .update() method.
            # Then simple sub-classes can handle each of the different projects'
            # details.

            # What the heck is up with the Fedora code being
            # special-cased like this? Well, I'll clean it up another day,
            # so long as it seems to work right now.
            'Fedora "fit and finish" new bugs':
                mysite.search.tasks.bugzilla_instances.learn_about_new_fedora_fit_and_finish_bugs,

            'Fedora "fit and finish" refreshing old bugs':
                mysite.search.tasks.bugzilla_instances.refresh_all_fedora_fit_and_finish_bugs,
            }

        for bugzilla_tracker in bugzilla_trackers:
            logging.info("Refreshing bugs from %s." % bugzilla_tracker)
            call_me = bugzilla_trackers[bugzilla_tracker]
            call_me()

    def find_and_update_enabled_roundup_trackers(self):
        enabled_roundup_trackers = []

        ### First, the "find" step
        for thing_name in dir(mysite.customs.bugtrackers.roundup_general):
            thing = getattr(mysite.customs.bugtrackers.roundup_general,
                            thing_name)
            if hasattr(thing, 'enabled'):
                if getattr(thing, 'enabled'):
                    enabled_roundup_trackers.append(thing)

        ### Okay, now update!
        for thing in enabled_roundup_trackers:
            logging.info("[Roundup] About to update %s" % thing)
            instantiated = thing()
            instantiated.update()

    def update_trac_instances(self):
        # Trac instances' update functions
        # Note that each Trac instance has two such functions for now. It would be
        # good to rework the Trac code so it looks more like the RoundupTracker
        # code, with just one .update() method. Another day.
        trac_instance_functions_to_call = [
            # Sugar
            mysite.search.tasks.trac_instances.learn_about_new_sugar_easy_bugs,
            mysite.search.tasks.trac_instances.refresh_all_sugar_easy_bugs,
            # Twisted
            mysite.search.tasks.trac_instances.learn_about_new_easy_twisted_bugs,
            mysite.search.tasks.trac_instances.refresh_all_twisted_bugs,
        ]
        for callable in trac_instance_functions_to_call:
            callable()

        ### And for my next trick...  discover the new-style Trac instances
        enabled_ones = []

        ### First, the "find" step
        for thing_name in dir(mysite.search.tasks.trac_instances):
            thing = getattr(mysite.search.tasks.trac_instances,
                            thing_name)
            if hasattr(thing, 'enabled'):
                if getattr(thing, 'enabled'):
                    enabled_ones.append(thing)

        ### Okay, now update!
        for thing in enabled_ones:
            logging.info("[Trac] About to update %s" % thing)
            instantiated = thing()
            instantiated.update()

    def update_launchpad_hosted_projects(self):
        ### For Launchpad:
        # First, we ask the projects' bug trackers if there are new bugs we should know about
        mysite.search.tasks.launchpad_tasks.refresh_bugs_from_all_indexed_launchpad_projects()
        # Second, we go through our *own* database of Launchpad-sourced bugs, and make sure they are all up to date
        mysite.search.tasks.launchpad_tasks.refresh_all_launchpad_bugs()

    def update_opensolaris_osnet(self):
        mysite.customs.bugtrackers.opensolaris.grab()

    def handle(self, *args, **options):
        self.update_opensolaris_osnet()
        self.update_launchpad_hosted_projects()
        self.update_trac_instances()
        self.find_and_update_enabled_roundup_trackers()
        self.update_bugzilla_trackers()

<|endoftext|>


<commit_before>from flask_admin.contrib.sqla import ModelView
from . import lastuser

class SiteAdminModelView(ModelView):
    def is_accessible(self):
        return lastuser.has_permission('siteadmin')

class OrganizationModelView(SiteAdminModelView):
    can_delete = False
    column_display_pk = True
    column_list = ('id', 'title')
    form_list = ('id', 'userid', 'title')
    form_excluded_columns = ['userid', 'item_collections', 'discount_policies', 'orders', 'created_at', 'updated_at']

class ItemCollectionModelView(SiteAdminModelView):
    can_delete = False
    column_display_pk = True
    column_filters = ['organization']
    column_list = ('id', 'title')
    form_excluded_columns = ['parent', 'items', 'orders', 'categories', 'created_at', 'updated_at']

class CategoryModelView(SiteAdminModelView):
    can_delete = False
    column_display_pk = True
    column_filters = ['item_collection']
    column_list = ('id', 'title')
    form_excluded_columns = ['parent', 'items', 'created_at', 'updated_at']

class ItemModelView(SiteAdminModelView):
    can_delete = False
    column_display_pk = True
    column_filters = ['item_collection']
    column_searchable_list = ['title']
    column_list = ('id', 'title')
    form_excluded_columns = ['parent', 'line_items', 'created_at', 'updated_at']

class PriceModelView(SiteAdminModelView):
    can_delete = False
    column_display_pk = True
    column_filters = ['item']
    column_list = ('id', 'item', 'title', 'start_at', 'end_at', 'currency', 'amount')
    form_excluded_columns = ['parent', 'created_at', 'updated_at']

class DiscountPolicyModelView(SiteAdminModelView):
    can_delete = False
    column_display_pk = True
    column_filters = ['organization']
    column_list = ('id', 'title')
    column_searchable_list = ['title']
    form_excluded_columns = ['parent', 'line_items', 'created_at', 'updated_at', 'discount_coupons']

class DiscountCouponModelView(SiteAdminModelView):
    can_delete = False
    column_filters = ['discount_policy']
    column_searchable_list = ['code']
    column_list = ('code', 'discount_policy')
    form_excluded_columns = ['line_items', 'created_at', 'updated_at']
<commit_msg>render assignee_details as a JSONField<commit_after>from flask_admin.contrib.sqla import ModelView
from . import lastuser
from flask_admin.form.fields import JSONField

class SiteAdminModelView(ModelView):
    def is_accessible(self):
        return lastuser.has_permission('siteadmin')

class OrganizationModelView(SiteAdminModelView):
    can_delete = False
    column_display_pk = True
    column_list = ('id', 'title')
    form_list = ('id', 'userid', 'title')
    form_excluded_columns = ['userid', 'item_collections', 'discount_policies', 'orders', 'created_at', 'updated_at']

class ItemCollectionModelView(SiteAdminModelView):
    can_delete = False
    column_display_pk = True
    column_filters = ['organization']
    column_list = ('id', 'title')
    form_excluded_columns = ['parent', 'items', 'orders', 'categories', 'created_at', 'updated_at']

class CategoryModelView(SiteAdminModelView):
    can_delete = False
    column_display_pk = True
    column_filters = ['item_collection']
    column_list = ('id', 'title')
    form_excluded_columns = ['parent', 'items', 'created_at', 'updated_at']

class ItemModelView(SiteAdminModelView):
    can_delete = False
    column_display_pk = True
    column_filters = ['item_collection']
    column_searchable_list = ['title']
    column_list = ('id', 'title')
    form_excluded_columns = ['parent', 'line_items', 'created_at', 'updated_at']
    form_overrides = dict(assignee_details=JSONField)

class PriceModelView(SiteAdminModelView):
    can_delete = False
    column_display_pk = True
    column_filters = ['item']
    column_list = ('id', 'item', 'title', 'start_at', 'end_at', 'currency', 'amount')
    form_excluded_columns = ['parent', 'created_at', 'updated_at']

class DiscountPolicyModelView(SiteAdminModelView):
    can_delete = False
    column_display_pk = True
    column_filters = ['organization']
    column_list = ('id', 'title')
    column_searchable_list = ['title']
    form_excluded_columns = ['parent', 'line_items', 'created_at', 'updated_at', 'discount_coupons']

class DiscountCouponModelView(SiteAdminModelView):
    can_delete = False
    column_filters = ['discount_policy']
    column_searchable_list = ['code']
    column_list = ('code', 'discount_policy')
    form_excluded_columns = ['line_items', 'created_at', 'updated_at']
<|endoftext|>


<commit_before>#! /ufs/guido/bin/sgi/tkpython

# A Python program implementing rmt, an application for remotely
# controlling other Tk applications.
# Cf. Ousterhout, Tcl and the Tk Toolkit, Figs. 27.5-8, pp. 273-276.

# Note that because of forward references in the original, we
# sometimes delay bindings until after the corresponding procedure is
# defined.  We also introduce names for some unnamed code blocks in
# the original because of restrictions on lambda forms in Python.

from Tkinter import *

# 1. Create basic application structure: menu bar on top of
# text widget, scrollbar on right.

root = Tk()
tk = root.tk
mBar = Frame(root, {'relief': 'raised', 'bd': 2,
		    Pack: {'side': 'top', 'fill': 'x'}})
f = Frame(root)
f.pack({'expand': 1, 'fill': 'both'})
s = Scrollbar(f, {'relief': 'flat',
		  Pack: {'side': 'right', 'fill': 'y'}})
t = Text(f, {'relief': 'raised', 'bd': 2, 'yscrollcommand': (s, 'set'),
	     'setgrid': 1,
	     Pack: {'side': 'left', 'fill': 'both', 'expand': 1}})

t.tag_config('bold', {'font': '-Adobe-Courier-Bold-R-Normal-*-120-*'})
s['command'] = (t, 'yview')
root.title('Tk Remote Controller')
root.iconname('Tk Remote')

# 2. Create menu button and menus.

file = Menubutton(mBar, {'text': 'File', 'underline': 0,
			 Pack: {'side': 'left'}})
file_m = Menu(file)
file['menu'] = file_m
file_m_apps = Menu(file_m)
file_m.add('cascade', {'label': 'Select Application', 'underline': 0,
		       'menu': file_m_apps})
file_m.add('command', {'label': 'Quit', 'underline': 0, 'command': 'exit'})

# 3. Create bindings for text widget to allow commands to be
# entered and information to be selected.  New characters
# can only be added at the end of the text (can't ever move
# insertion point).

def single1(e):
	x = e.x
	y = e.y
	tk.setvar('tk_priv(selectMode)', 'char')
	t.mark_set('anchor', At(x, y))
	# Should focus W
t.bind('<1>', single1)

def double1(e):
	x = e.x
	y = e.y
	tk.setvar('tk_priv(selectMode)', 'word')
	tk.call('tk_textSelectTo', t, At(x, y))
t.bind('<Double-1>', double1)

def triple1(e):
	x = e.x
	y = e.y
	tk.setvar('tk_priv(selectMode)', 'line')
	tk.call('tk_textSelectTo', t, At(x, y))
t.bind('<Triple-1>', triple1)

def returnkey(e):
	t.insert('insert', '\n')
	invoke()
t.bind('<Return>', returnkey)

def controlv(e):
	t.insert('insert', tk.call('selection', 'get'))
	t.yview_pickplace('insert')
	if t.index('insert')[-2:] == '.0':
		invoke()
t.bind('<Control-v>', controlv)

# 4. Procedure to backspace over one character, as long as
# the character isn't part of the prompt.

def backspace(e):
	if t.index('promptEnd') != t.index('insert - 1 char'):
		t.delete('insert - 1 char', 'insert')
		t.yview_pickplace('insert')
t.bind('<BackSpace>', backspace)
t.bind('<Control-h>', backspace)
t.bind('<Delete>', backspace)

# 5. Procedure that's invoked when return is typed:  if
# there's not yet a complete command (e.g. braces are open)
# then do nothing.  Otherwise, execute command (locally or
# remotely), output the result or error message, and issue
# a new prompt.

def invoke():
	cmd = t.get('promptEnd + 1 char', 'insert')
	if tk.getboolean(tk.call('info', 'complete', cmd)):
		if app == tk.call('winfo', 'name', '.'):
			msg = tk.call('eval', cmd)
		else:
			msg = tk.call('send', app, cmd)
		if msg:
			t.insert('insert', msg + '\n')
		prompt()
	t.yview_pickplace('insert')

def prompt():
	t.insert('insert', app + ': ')
	t.mark_set('promptEnd', 'insert - 1 char')
	t.tag_add('bold', 'insert linestart', 'promptEnd')

# 6. Procedure to select a new application.  Also changes
# the prompt on the current command line to reflect the new
# name.

def newApp(appName):
	global app
	app = appName
	t.delete('promptEnd linestart', 'promptEnd')
	t.insert('promptEnd', appName + ':')
	t.tag_add('bold', 'promptEnd linestart', 'promptEnd')

newApp_tcl = `id(newApp)`
tk.createcommand(newApp_tcl, newApp)

def fillAppsMenu():
	file_m_apps.add('command')
	file_m_apps.delete(0, 'last')
	names = tk.splitlist(tk.call('winfo', 'interps'))
	names = map(None, names) # convert tuple to list
	names.sort()
	for name in names:
		file_m_apps.add('command', {'label': name,
					    'command': (newApp_tcl, name)})

file_m_apps['postcommand'] = fillAppsMenu
mBar.tk_menuBar(file)

# 7. Miscellaneous initialization.

app = tk.call('winfo', 'name', '.')
prompt()
tk.call('focus', t)

root.mainloop()
<commit_msg>Adapt to new Tkinter.py<commit_after>#! /ufs/guido/bin/sgi/tkpython

# A Python program implementing rmt, an application for remotely
# controlling other Tk applications.
# Cf. Ousterhout, Tcl and the Tk Toolkit, Figs. 27.5-8, pp. 273-276.

# Note that because of forward references in the original, we
# sometimes delay bindings until after the corresponding procedure is
# defined.  We also introduce names for some unnamed code blocks in
# the original because of restrictions on lambda forms in Python.

from Tkinter import *

# 1. Create basic application structure: menu bar on top of
# text widget, scrollbar on right.

root = Tk()
tk = root.tk
mBar = Frame(root, {'relief': 'raised', 'bd': 2,
		    Pack: {'side': 'top', 'fill': 'x'}})
f = Frame(root)
f.pack({'expand': 1, 'fill': 'both'})
s = Scrollbar(f, {'relief': 'flat',
		  Pack: {'side': 'right', 'fill': 'y'}})
t = Text(f, {'relief': 'raised', 'bd': 2, 'yscrollcommand': (s, 'set'),
	     'setgrid': 1,
	     Pack: {'side': 'left', 'fill': 'both', 'expand': 1}})

t.tag_config('bold', {'font': '-Adobe-Courier-Bold-R-Normal-*-120-*'})
s['command'] = (t, 'yview')
root.title('Tk Remote Controller')
root.iconname('Tk Remote')

# 2. Create menu button and menus.

file = Menubutton(mBar, {'text': 'File', 'underline': 0,
			 Pack: {'side': 'left'}})
file_m = Menu(file)
file['menu'] = file_m
file_m_apps = Menu(file_m)
file_m.add('cascade', {'label': 'Select Application', 'underline': 0,
		       'menu': file_m_apps})
file_m.add('command', {'label': 'Quit', 'underline': 0, 'command': 'exit'})

# 3. Create bindings for text widget to allow commands to be
# entered and information to be selected.  New characters
# can only be added at the end of the text (can't ever move
# insertion point).

def single1(e):
	x = e.x
	y = e.y
	t.setvar('tk_priv(selectMode)', 'char')
	t.mark_set('anchor', At(x, y))
	# Should focus W
t.bind('<1>', single1)

def double1(e):
	x = e.x
	y = e.y
	t.setvar('tk_priv(selectMode)', 'word')
	t.tk_textSelectTo(At(x, y))
t.bind('<Double-1>', double1)

def triple1(e):
	x = e.x
	y = e.y
	t.setvar('tk_priv(selectMode)', 'line')
	t.tk_textSelectTo(At(x, y))
t.bind('<Triple-1>', triple1)

def returnkey(e):
	t.insert(AtInsert(), '\n')
	invoke()
t.bind('<Return>', returnkey)

def controlv(e):
	t.insert(AtInsert(), t.selection_get())
	t.yview_pickplace(AtInsert())
	if t.index(AtInsert())[-2:] == '.0':
		invoke()
t.bind('<Control-v>', controlv)

# 4. Procedure to backspace over one character, as long as
# the character isn't part of the prompt.

def backspace(e):
	if t.index('promptEnd') != t.index('insert - 1 char'):
		t.delete('insert - 1 char', AtInsert())
		t.yview_pickplace(AtInsert())
t.bind('<BackSpace>', backspace)
t.bind('<Control-h>', backspace)
t.bind('<Delete>', backspace)

# 5. Procedure that's invoked when return is typed:  if
# there's not yet a complete command (e.g. braces are open)
# then do nothing.  Otherwise, execute command (locally or
# remotely), output the result or error message, and issue
# a new prompt.

def invoke():
	cmd = t.get('promptEnd + 1 char', AtInsert())
	if t.getboolean(tk.call('info', 'complete', cmd)): # XXX
		if app == root.winfo_name():
			msg = tk.call('eval', cmd) # XXX
		else:
			msg = t.send(app, cmd)
		if msg:
			t.insert(AtInsert(), msg + '\n')
		prompt()
	t.yview_pickplace(AtInsert())

def prompt():
	t.insert(AtInsert(), app + ': ')
	t.mark_set('promptEnd', 'insert - 1 char')
	t.tag_add('bold', 'insert linestart', 'promptEnd')

# 6. Procedure to select a new application.  Also changes
# the prompt on the current command line to reflect the new
# name.

def newApp(appName):
	global app
	app = appName
	t.delete('promptEnd linestart', 'promptEnd')
	t.insert('promptEnd', appName + ':')
	t.tag_add('bold', 'promptEnd linestart', 'promptEnd')

def fillAppsMenu():
	file_m_apps.add('command')
	file_m_apps.delete(0, 'last')
	names = root.winfo_interps()
	names = map(None, names) # convert tuple to list
	names.sort()
	for name in names:
		try:
			root.send(name, 'winfo name .')
		except TclError:
			# Inoperative window -- ignore it
			pass
		else:
			file_m_apps.add('command', {'label': name,
						    'command':
						    lambda name=name:
						    newApp(name)})

file_m_apps['postcommand'] = fillAppsMenu
mBar.tk_menuBar(file)

# 7. Miscellaneous initialization.

app = root.winfo_name()
prompt()
t.focus()

root.mainloop()
<|endoftext|>