pip and virtualenv

http://mathematism.com/2009/07/30/presentation-pip-and-virtualenv/

Screencasts, diagrams, and links from my presentation for July’s django-district.

I put together a walkthrough of pip and virtualenv for the django-district July meeting. It was a slide-less presentation, focusing mostly on talking points and command-line walkthroughs. This post provides a recap of what I covered.

virtualenv

virtualenv is a tool to create isolated Python environments. It was created by Ian Bicking to provide a solution to a consistent problem.

The Problem

To illustrate the problem let’s pretend you have a Web server with two Web sites on it: mysite.com and anothersite.com. Each of your Web sites are sharing the global site-packages directory in /usr/lib/python2.x/site-packages.

 

The global site-packages directory has Django 1.0.2, Pinax 0.5 and PIL 1.1.6 among other things. The sites are purring along, living in complete harmony.

One day, the client for anothersite.com decides they’d like to take advantage of some of the new features in Django 1.1. Now we have a problem. How do we upgrade anothersite.com’s dependencies without affecting mysite.com?

The Solution

anothersite.com and mysite.com need the ability to have their own set of dependencies. The way to achieve this is to create isolated Python environments using virtualenv.

 

virtualenv creates an environment that has its own installation directories and isolates itself from other virtual environments. The environment contains a site-packages directory, installs setuptools and a Python interpreter that is aware of its environment.

This allows us to install a different set of dependencies for each of our sites. Now anothersite.com can upgrade to Django 1.1 and Pinax trunk without affecting mysite.com at all.

Installation

virtualenv is available on PyPI. Run the following command to install:

easy_install virtualenv

Working with virtualenv

While I could go into detail about the commands available with virtualenv, I honestly never use the virtualenv commands directly. I use suite of conveniences for virtualenv called virtualenvwrapper.

virtualenvwrapper

Doug Hellmann was kind enough to create virtualenvwrapper, which is best described on PyPI:

virtualenvwrapper is a set of extensions to Ian Bicking’s virtualenv tool. The extensions include wrappers for creating and deleting virtual environments and otherwise managing your development workflow, making it easier to work on more than one project at a time without introducing conflicts in their dependencies.

Screencast

I put together a quick screencast to go over the wrappers and hooks that virtualenvwrapper provides as stated below. You can also view the source codeon Bitbucket. Doug’s code is well commented and I found out about several of these wrappers only after taking a look at the source.

Wrappers

The wrappers provided by virtualenvwrapper (that I know of) are:

  • mkvirtualenv (create a new virtualenv)
  • rmvirtualenv (remove an existing virtualenv)
  • workon (change the current virtualenv)
  • add2virtualenv (add external packages in a .pth file to current virtualenv)
  • cdsitepackages (cd into the site-packages directory of current virtualenv)
  • cdvirtualenv (cd into the root of the current virtualenv)
  • deactivate (deactivate virtualenv, which calls several hooks)

Hooks

One of the coolest things about virtualenvwrapper is the ability to provide hooks when an event occurs. Hook files can be placed in ENV/bin/ and are simply plain-text files with shell commands. virtualenvwrapper provides the following hooks:

  • postmkvirtualenv
  • prermvirtualenv
  • postrmvirtualenv
  • postactivate
  • predeactivate
  • postdeactivate

Installation

virtualenvwrapper is available on PyPI. Run the following command to install:

easy_install virtualenvwrapper

Add two lines to your .bashrc to set the location where the virtual environments should live and the location of the script installed with this package:

export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper_bashrc

You should also take a look at Doug’s blog post on virtualenvwrapper, which provides a great overview of why he created virtualenvwrapper and provides detailed setup instructions.

pip

Another tool created by Ian Bicking, pip stands for pip installs Python packages. It is a replacement for easy_install that provides some great improvements including requirements files and support for version control systems.

Requirements files

Requirements files are plain text files that contain a list of packages to be installed. These text files allow you to create repeatable installations. As illustrated in this example file, there are several ways to specify a required package.

Package name with version requirements:

Django>=1.1
Pinax==0.5

Direct URL to a tarball containing a setup.py script:

http://effbot.org/downloads/Imaging-1.1.6.tar.gz

Editable checkouts from VCS repositories:

-e svn+http://svn.myproject.org/svn/MyProject/trunk#egg=MyProject
-e git+http://git.myproject.org/MyProject/#egg=MyProject
-e hg+ssh://[email protected]/MyProject/#egg=MyProject
-e bzr+https://bzr.myproject.org/MyProject/trunk#egg=MyProject

Editable checkouts from VCS repositories with revision information:

-e svn+http://svn.myproject.org/svn/MyProject/trunk@2019#egg=MyProject
-e git://git.myproject.org/MyProject.git@da39a3ee5e6b4b0d3255bfef95601890afd80709#egg=MyProject
-e hg+http://hg.myproject.org/MyProject/@2019#egg=MyProject
-e bzr+https://bzr.myproject.org/MyProject/trunk/@2019#egg=MyProject

View my sample requirements file for more examples of checking out with revision information including branches, tags and dates.

Usage

Once you have a requirements file, Installing a package using pip is as simple as the following command:

pip install -r /path/to/requirements.txt

I should note that you don’t have to create a requirements file. You can simply issue any of the commands listed in the requirements file directly from the command line like so:

pip install Django>=1.1
pip install http://effbot.org/downloads/Imaging-1.1.6.tar.gz
pip install -e svn+http://myrepo/svn/MyApp#egg=MyApp

pip freeze

pip doesn’t just install packages. It also provides a few other commands, including freeze:

pip freeze > /path/to/requirements.txt

This will inspect the current environment and generate a requirements files that contains explicit version number for each of the installed packages. I generally use this as a starting point for creating a stable requirements file.

There are other commands as well. I’d encourage you to take a look at thedocumentation for pip to learn more about the various options.

Installation

pip is available on PyPI. Run the following command to install:

easy_install pip

You can also check out a copy from bitbucket. Run one of the following commands:

wget http://bitbucket.org/ianb/pip/raw/0.4/pip.py

OR

hg clone http://bitbucket.org/ianb/pip/

Conclusion

Using virtualenv, virtualenvwrapper and pip together can help you create isolated, repeatable environments with ease. We use these tools on a daily basis at Discovery Creative and it has saved us countless hours in addition to providing documentation for requirements for our applications and sites.

Showing 26 comments

  • skyl

    yes, keep spreading the virtualenv love, nice article.

  • great stuff! thanks for putting the work in and sharing this informative piece.

  • Absolutely! I love putting these together – let me know if you have any other walkthroughs/screencasts you’d like to see.

  • shacker

    Question: What happens to my $PYTHONPATH within virtualenv?

    echo $PYTHONPATH

    returns nothing. Is it now assumed that all directories within the current virtualenv are automatically on the path? Looks like it – I had to comment out the $PYTHONPATH lines in my .bash_profile to get things basically working.

    But that doesn’t seem to be the whole enchilada. I was able to pip install 3rd party apps with pip or through the requirements file, but I also have a lot of custom reusable apps with no setup.py. I can’t install them with pip, and if I put them manually in /src, /lib, or /include, my Django project fails to see that they’re present. They worked previously, when I was basing everything off the $PYTHONPATH, but now there is no pythonpath.

    In general, what directories within the virtualenv are recommended for what?

    Side question: How would you switch to using a different version of an installed package (such as Django?)

    Thanks.

  • Hi shacker – I’m not sure what’s happening to your PYTHONPATH. The author’s code preserves the existing PYTHONPATH (see line 306 athttp://bitbucket.org/ianb/virt…. I personally only use virtual python environments and virtualenv’s –no-site-packages option so I don’t explicity set PYTHONPATH in my profile and haven’t run into this.

    To answer your second question, if you need a package that doesn’t have a setup.py, you can take two approaches. Put the package directly in lib/python2.x/site-packages/ or use the add2virtualenv command, which creates a .pth file in lib/python2.x/site-packages/.

    A virtual environment creates an isolated folder with bin, lib, include, etc. It’s similar to your system folders – executable scripts are in bin, lib contains python2.x, etc.

    If you wanted to change the version of an installed package, you can run pip install -U Django==X, where X is the version of Django (or any other package) you want to modify.

    Hope that helps!

  • shacker

    Thanks for the response Rich. I think I confused things a bit. Yes, if I keep a $PYTHONPATH set in bash, it’s preserved in the virtualenv. I have commented out the path in .bash_profile. What I *thought* would happen was that when I entered the virtualenv I’d get a new, automatically created $PYTHONPATH that reflected the new environment. Apparently not.

    Interestingly, even though echo pythonpath shows nothing, Django debug pages still show a full pythonpath reflecting the virtualenv. So it’s there, but the shell doesn’t know about it.

    The import errors turned out to be my own mistake (tangled package paths only revealed when I started isolating things with virtualenv).

    Thanks again.

     

  • Jay Liew, hustler + hacker startup guy

    Good intro, Rich. Btw, is there a way to change the virtualenv prompt?

    Just in case anyone else ran into the same problem, I couldn’t find virtualenvwrapper_bashrc in /usr/local/bin/ on my OS X 10.5 machine, and turns out it was here, so I symlinked it from here and it worked:

    ln -s /Library/Frameworks/Python.framework/Versions/2.6/bin/virtualenvwrapper_bashrc /usr/local/bin

    If yours isn’t there, (from bash shell) just do a:

    find / -name virtualenvwrapper_bashrc

    (for the record I installed virtualenv and virtualenvwrapper with pip)

  • You can change the virtual environment’s prompt using the –prompt option to virtualenv:

    –prompt==PROMPT Provides an alternative prompt prefix for this environment

  • Vn44ca

    So, where do you keep your real apps?
    Can you put a bit of code on how you develop your app in this framework?
    Let’s say you are making a site called mySite that has app1 app2 & app3.

  • I primarily use Django and all of my projects live outside the virtualenv completely. It’s the packages that my projects use that live in the virtualenv.

    For example, let’s say I have a site called mycoolsite.com. I’ll create a virtualenv called mycoolsite. The actual project files and web server configurations are in a repo and are checked out somewhere (e.g. /var/www/mysite/code/. The web server configs pull everything together. In the instance of a Django project, I’d have a .wsgi file that sets up my paths and points to my project files.

    A lot of updates have happened to virtualenvwrapper since I wrote this post. It’s definitely time for me to update and show off the new functionality.

  • Vn44ca

    Hi Rich,
    So, if I used the add2virtualenv, then I decide that I want to remove it, how do I go about it?

    I am using buildout right now, it is powerful, but it has its own problems. I am trying to move over to virenv. Any suggestions for the new converts?

  • Hi there – honestly I don’t use add2virtualenv at all. I just highlighted it because it’s available. But what it does is just put a .pth file inside site-packages. So you could just remove that file.

    My preferred way of working is to use the “–no-site-packages” flag to mkvirtualenv. This creates a clean site-packages folder and doesn’t pull in system-wide site-packages. Then you have a nice, clean env to start with, installing all the pieces you need.

  • Also – it’s interesting to me that lots of people are coming from buildout to ve. I’m doing the exact opposite at my new job, although I could see that changing at some point.

  • Vn44ca

    I still like buildout for a “finished” product. I wish it had the freeze option so I didn’t have to use the version tag and manually lock up all working versions. But lets say that I want to quickly test a new django CMS that someone wrote. With buidout, I have to go about and creating a buildout env to get it tested. With virtualenv, in few short minutes, I have the new CMS/example app up and running. I’d think that if buildout and virtualevn marry someday, they would produce a beautiful offspring. :)

  • Ryan

    I’m confused. If virtualenvwrapper maintains your virtual environments, then it can’t reside inside any of those virtual environments where *does* it live?

  • Hi Ryan – you run “sudo easy_install virtualenv virtualenvwrapper”. It lives in your system Python’s site-packages.

  • You can also add a hook to your workon home directory, just like you do with each individual virtualenv in the bin directory.

    Just create the hook file in your workon home (such as “postactivate”) and it will be applied when ANY virtualenv is called.

    For example, you could create a hook in your workon home called “postactivate” and then add in:

    cdvirtualenv

    …to the file and any time a virtualenv is activated, it will automatically cd to the directory of your virtualenv. This makes it so you only need to declare your hooks once, not one time for each virtualenv.

    Good write up!

    Cheers,
    Dana W.

  • Orangutan Cloud, Mobile and web application development

    This is a great write up, thanks.

    I always keep my projects outside of the virtual environments and they live in a separate directory.

    To keep things simple, I create a symlink to the virtual environments python inside my project.

    ln -s /srv/environments/djnonrel/bin/python /srv/projects/myproject/python

    Then you can just do something like this in myproject:
    ./python manage.py runserver

    etc

    And just forget about where you put the environment while you work on your project

  • Mark Essel, pro sim-gineer, alg geek, dude

    Thanks for writing this up and the screencast. Coming from an acolyte’s level of experience with ruby, I eagerly anticipated something like rvm for python. It looks like virtualenvwrapper will serve that role well. What’s really fantastic about this environment tools is how easy it makes setting up new apps or systems.

  • Ethan Herdrick, Co-founder of Biographicon.com.

    Thanks.  BTW your link to “Doug’s blog post” is missing.

  • Hope you found it helpful! Fixed that link – thanks for pointing it out.

  • Olivier Larchevêque

    I use closed environments for each projects with freeze versions, and I wonder how you supervise your packages deployed, to check outdated packages for example.
    Is there any supervision tool, app to do this?

  • Hi Oliver – a colleague of mine, Corey Oordt, wrote some Fabric tools to check for outdated/out of sync dependencies: https://gist.github.com/106622…. That may be what you’re looking for.

  • Olivier Larchevêque

    Thanks, I have still have a look on, It’s pretty my needs, but I am not responsible of deployment,  so I don’t have any ssh access… anyway, should be easy to port for webby approach!

  • Morgan Craft, Django/Python and JS Guru

    Nice writeup, I’ve been linking to this in all my github project installation instructions.

  • Guest

    The filename virtualenvwrapper_bashrc has been updated since prior posts, for version 3.0 of virtualenvwrapper the filename is virtualenvwrapper.sh

0

0
 

Herramientas de Software de Artesanía

Cualquier artesano es sólo tan buena como las herramientas a su disposición y la nave del desarrollo de software no es diferente. Para producir sus mejores esfuerzos, que deben tener las mejores herramientas que se pueden permitir. Afortunadamente, en la industria del software, algunas de estas mejores herramientas son gratuitas. Si usted está en la búsqueda de una herramienta, saben que ninguna herramienta o marco es tan amplio como para abarcar una exhaustiva los casos de uso. Así que cualquier decisión que tomes, es probable que usted se encontrará con alguien de la lucha contra el campamento. Escuche sus argumentos, sólo asegúrese de sus necesidades. De lo contrario, perderá su tiempo en la búsqueda de la mejor herramienta! Mientras estamos en ello, he aquí una cuestión relacionada con: dado que ninguna herramienta puede satisfacer todas sus necesidades, usted puede tener que aprender otra herramienta. Con eso dicho, aquí hay una lista de las herramientas que he adquirido y usar: Entorno informático : Usted puede comprar las mejores herramientas, pero si usted tiene que ejecutar en un equipo pésimo, su productividad se ve dificultada aún. He estado usando un MacBook durante los últimos tres años y no me arrepiento de la inversión. ¿Por qué? Debido a que simplemente funciona. Hágase un favor y obtener el mejor equipo que puedes comprar. Lenguaje de programación : Otra opción importante para los desarrolladores de software es el lenguaje de programación, ya que tienes que vivir, literalmente, de la misma. De todos los idiomas que he utilizado, prefiero Python . Es simple, por lo tanto, fácil de aprender, sino que tiene gran comunidad alrededor, tengo muchos marcos, tanto para escritorio y web, y una ventaja de un lenguaje de programación simple es que cuando regrese después de una pausa, usted puede recoger y avanzar con rapidez. Entorno Virtual : Sin un entorno virtual, los cambios realizados afectar a la instalación principal, a veces alterar el comportamiento del sistema. Los entornos virtuales le dan la flexibilidad de experimentación y aislar los cambios experimentales. Puedo utilizar VirtualBox , que es un completo emulador de hecho y derecho virtual y virtualenv que es un entorno virtual de python. Sketchers de carcasa : Es mejor para visualizar el diseño antes de escribir una sola línea de código. Esto limitará el coste de los cambios más adelante. Juego con muchas herramientas basadas en escritorio y basadas en la web de alambre, pero sigo volviendo a lápiz (el papel real y lápiz y el simple lápiz extensión para Firefox ) IDE / Editor de texto : entornos de desarrollo integrados se incluyen con un montón de herramientas para ayudar al desarrollo de software. Pero, me parecen hinchado por un desarrollo basado en la web de Python. Un editor de texto cumple con casi todas las exigencias de un desarrollo basado en la web de Python. Recientemente, me cambié a TextMate y estoy contento con él. Viene con un montón de paquetes que facilitan su forma de trabajar. Marcos : Marcos de proporcionar un medio para todas las actividades comunes de desarrollo de software como el diseño de la interfaz de usuario, los controladores de eventos, acceso a base de datos y gestión de sesiones (en el caso de aplicaciones web). Dicho esto, los marcos también puede ser restrictivo, por lo que asegurar que los marcos de apoyo a los casos de uso que tiene en mente. Yo uso regularmente wxWidgets para la programación de escritorio y web2py para el desarrollo web. Ellos no son perfectos y siempre hay un marco mejor, pero se ajustan a mis necesidades. Control de código fuente : Es suicida para iniciar el desarrollo de software sin una herramienta de control de código fuente, incluso para un desarrollo en solitario-desarrollador (como yo). Hay un beneficio asociado a la utilización de un sistema de control de código fuente: el uso de los comentarios de confirmación, puede realizar un seguimiento de su progreso en la implementación de características y corrigiendo errores. Mercurial es mi elección para el control de código fuente. En Mac, yo uso turbia como el cliente de mercurio. Bug / Edición / Base de datos Características : Errores y características se deben recoger en un solo cubo en lugar de estar lleno de papeles o en archivos de texto. La mayoría de los sistemas de control de versiones proporcionan un sistema de seguimiento de fallos también. Yo uso la base de datos bug / problema que viene junto con Bitbucket . (Automatizado) Herramientas de prueba : después de un cierto umbral, que es imposible que todas las características de la prueba de forma manual. usted debe automatizar tanto como sea posible y recurrir a las pruebas manuales únicamente para los aspectos que necesitan ser probados de forma manual, como look & feel de la aplicación. Hay un montón de herramientas de prueba disponibles en función de los aspectos de las pruebas, por ejemplo, ensayos funcionalidad y pruebas de carga. Yo no tengo una opción o una preferencia cuando se trata de herramientas de test. He usado Python pruebas unitarias, selenio y ahora está aprendiendo Marco Robot . Pero todavía estoy en la búsqueda de una mejor (léase que hace que las pruebas funcionales y de carga más fácil) herramienta de prueba. Alojamiento : Las aplicaciones Web necesitan un entorno de hospedaje. Para mi simple necesidad Google AppEngine y WebFaction son suficientes. Estoy ansioso por saber cuáles son las herramientas que utiliza? Deja en los comentarios .

0

0
 

Creando interfaces atractivos con Active Admin

Create Beautiful Administration Interfaces with Active Admin

SOURCE: Ian Murray on Sep 12th 2011 with 73 comments
Tutorial Details
  • Difficulty: Medium
  • Framework: RoR
  • Estimated Completion Time: 1 hour

Every web developer knows that creating an administration interface for their projects is an incredibly tedious task. Luckily, there are tools that make this task considerably simpler. In this tutorial, I’ll show you how to use Active Admin, a recently launched administration framework for Ruby on Rails applications.

 

You can use Active Admin to add an administration interface to your current project, or you can even use it to create a complete web application from scratch – quickly and easily.

Today, we’ll be doing the latter, by creating a fairly simple project management system. It might sound like quite a bit of work, but Active Admin will do the bulk of the work for us!


Step 1 – Set up the Development Environment

I’m going to assume you have some previous Ruby on Rails knowledge, especially involving model validations, since the rest of the application interface is going to be taken care of by Active Admin. Apart from that, you should have a development environment for Ruby on Rails 3.1 already set up, including Ruby 1.9.2.

Refer to this article if you require assistance installing Ruby and Rails.

Create the application we’ll be working on, by running the following command in your Terminal:

1
rails new active_admin

Next, open your Gemfile and add the following lines:

1
2
gem 'activeadmin'
gem 'meta_search', '>= 1.1.0.pre'

The last gem is required for Active Admin to work with Rails 3.1, so don’t forget it. After that’s done, run the bundle install command to install the gems. Now, we need to finish installing Active Admin, by running the following command:

1
rails generate active_admin:install

This will generate all needed initializers and migrations for Active Admin to work. It will also create an AdminUser model for authentication, so run rake db:migrate to create all the needed database tables. Apart from that, you need to add one line to your config/environments/development.rb file, so sending emails works:

1
config.action_mailer.default_url_options = { :host => 'localhost:3000' }

Once that’s done, run rails server and point your browser to localhost:3000/admin. You’ll be greeted with a nice login form. Just type “[email protected]” as the email and “password” as the password, and hit “Login”. You should now see a nice administration interface.


Step 2 – Configuring our User Model

As you can see from the webpage you just generated, there’s not much you can do, yet. We’re going to need a way to edit our users, and we can do that using Active Admin. The framework uses what it calls “Resources”. Resources map models to administration panels. You need to generate them using a command in your terminal, so Active Admin can know their existence, so go ahead and run:

1
rails generate active_admin:resource AdminUser

The syntax for that command is simple: just write the database model’s name at the end. This will generate a file inside the app/admin folder, called admin_users.rb. Now, if you refresh your browser you’ll see a new link at the top bar, called “Admin Users”. Clicking that will take you to the Admin User administration panel. Now, it’ll probably look a little too cluttered, since by default, Active Admin shows all of the model’s columns, and considering that the framework uses Devise for authentication, you’ll see a bunch of columns that are not really necessary. This takes us to the first part of our customization: the index page.

Admin User

Customizing Active Admin resources is fairly easy (and fun if you ask me). Open app/admin/admin_users.rb on your favorite text editor and make it look like this:

1
2
3
4
5
6
7
8
9
ActiveAdmin.register AdminUser do
  index do
    column :email
    column :current_sign_in_at
    column :last_sign_in_at
    column :sign_in_count
    default_actions
  end
end

Let’s review the code:

  • The first line is created by Active Admin, and, like it says, it registers a new resource. This created the menu link at the top bar and all of the default actions, like the table you just saw.
  • The index method allows us to customize the index view, which is the table that shows all rows.
  • Inside of the block you pass to the index method, you specify which columns you do want to appear on the table, ie. writing column :email will have Active Admin show that column on the view.
  • default_actions is a convenience method that creates one last column with links to the detail, edition and deletion of the row.

One final step for this view is to customize the form. If you click the “New Admin User” link on the top right, you’ll see that the form also contains all of the columns on the model, which is obviously not very useful. Since Active Admin uses Devise, we only need to enter an email address to create a user, and the rest should be taken care of by the authentication gem. To customize the forms that Active Admin displays, there’s a method, called (you guessed it) form:

1
2
3
4
5
6
7
8
9
10
11
12
ActiveAdmin.register AdminUser do
  index do
    # ...
  end
  form do |f|
    f.inputs "Admin Details" do
      f.input :email
    end
    f.buttons
  end
end

If the code looks familiar to you, you’ve probably used the Formtastic gem before. Let’s take a look at the code:

  • You specify the form’s view by calling the form method and passing it a block with an argument (f in this case).
  • f.inputs creates a fieldset. Word of advice: you have to add at least one fieldset. Fields outside of one will simply not appear on the view.
  • To create a field, you simply call f.input and pass a symbol with the name of the model’s column, in this case, “email”.
  • f.buttons creates the “Submit” and “Cancel” buttons.

You can further customize the forms using the DSL (Domain Specific Language) provided by Formtastic, so take a look at tutorials about this gem.

One last step for this form to work: since we’re not providing a password, Devise is not going to let us create the record, so we need to add some code to the AdminUser model:

1
2
3
4
5
after_create { |admin| admin.send_reset_password_instructions }
def password_required?
  new_record? ? false : super
end

The after_create callback makes sure Devise sends the user a link to create a new password, and the password_required? method will allow us to create a user without providing a password.

Go try it out. Create a user, and then check your email for a link, which should let you create a new password, and log you into the sytem.


Step 3 – Projects

We are going to create a simple Project Management system. Not anything too complicated though, just something that will let us manage projects and tasks for the project, and assign tasks to certain users. First thing, is to create a project model:

1
rails generate model Project title:string

Active Admin relies on Rails’ models for validation, and we don’t want projects with no title, so let’s add some validations to the generated model:

1
2
# rails
validates :title, :presence => true

Now, we need to generate an Active Admin resource, by running:

1
rails generate active_admin:resource Project

For now, that’s all we need for projects. After migrating your database, take a look at the interface that you just created. Creating a project with no title fails, which is what we expected. See how much you accomplished with just a few lines of code?


Step 4 – Tasks

Projects aren’t very useful without tasks right? Let’s add that:

1
rails generate model Task project_id:integer admin_user_id:integer title:string is_done:boolean due_date:date

This creates a task model that we can associate with projects and users. The idea is that a task is assigned to someone and belongs to a project. We need to set those relations and validations in the model:

1
2
3
4
5
6
7
class Task < ActiveRecord::Base
  belongs_to :project
  belongs_to :admin_user
  validates :title, :project_id, :admin_user_id, :presence => true
  validates :is_done, :inclusion => { :in => [true, false] }
end

Remember to add the relations to the Project and AdminUser models as well:

1
2
3
4
5
class AdminUser < ActiveRecord::Base
  has_many :tasks
  # ...
end
1
2
3
4
5
class Project < ActiveRecord::Base
  has_many :tasks
  # ...
end

Migrate the database, and register the task model with Active Admin:

1
rails generate active_admin:resource Task

Now go and take a look at the tasks panel in your browser. You just created a project management system! Good job.


Step 5 – Making It Even Better

The system we just created isn’t too sophisticated. Luckily, Active Admin is not just about creating a nice scaffolding system, it gives you far more power than that. Let’s start with the Projects section. We don’t really need the id, created and updated columns there, and we certainly don’t need to be able to search using those columns. Let’s make that happen:

1
2
3
4
5
6
7
8
9
10
index do
  column :title do |project|
    link_to project.title, admin_project_path(project)
  end
  default_actions
end
# Filter only by title
filter :title

A few notes here:

  • When you specify columns, you can customize what is printed on every row. Simply pass a block with an argument to it, and return whatever you want in there. In this case, we are printing a link to the project’s detail page, which is easier than clicking the “View” link on the right.
  • The filters on the right are also customizable. Just add a call to filter for every column you want to be able to filter with.

The project’s detail page is a little boring don’t you think? We don’t need the date columns and the id here, and we could show a list of the tasks more directly. Customizing the detail page is accomplished by using the show method in the app/admin/projects.rb file:

1
2
3
4
5
6
7
8
9
10
show :title => :title do
  panel "Tasks" do
    table_for project.tasks do |t|
      t.column("Status") { |task| status_tag (task.is_done ? "Done" : "Pending"), (task.is_done ? :o k : :error) }
      t.column("Title") { |task| link_to task.title, admin_task_path(task) }
      t.column("Assigned To") { |task| task.admin_user.email }
      t.column("Due Date") { |task| task.due_date? ? l(task.due_date, :format => :long) : '-' }
    end
  end
end

Let’s walk through the code:

  • show :title => :title specifies the title the page will have. The second :title specifies the model’s column that will be used.
  • By calling panel "Tasks" we create a panel with the given title. Within it, we create a custom table for the project’s tasks, using table_for.
  • We then specify each column and the content’s it should have for each row.
    • The “Status” column will contain “Done” or “Pending” whether the task is done or not. status_tag is a method that renders the word passed with a very nice style, and you can define the color by passing a second argument with either : ok, :warning and :error for the colors green, orange and red respectively.
    • The “Title” column will contain a link to the task so we can edit it.
    • The “Assigned To” column just contains the email of the person responsible.
    • The “Due Date” will contain the date the task is due, or just a “-” if there’s no date set.

Step 6 – Some Tweaks for the Tasks

How about an easy way to filter tasks that are due this week? Or tasks that are late? That’s easy! Just use a scope. In the tasks.rb file, add this:

1
2
3
4
5
6
7
8
9
10
scope :all, :default => true
scope :due_this_week do |tasks|
  tasks.where('due_date > ? and due_date < ?', Time.now, 1.week.from_now)
end
scope :late do |tasks|
  tasks.where('due_date < ?', Time.now)
end
scope :mine do |tasks|
  tasks.where(:admin_user_id => current_admin_user.id)
end

Let’s review that code:

  • scope :all defines the default scope, showing all rows.
  • scope accepts a symbol for the name, and you can pass a block with an argument. Inside the block you can refine a search according to what you need. You can also define the scope inside the model and simply name it the same as in this file.
  • As you can see, you can access the current logged in user’s object using current_admin_user.
Tasks2

Check it out! Just above the table, you’ll see some links, which quickly show you how many tasks there are per scope, and lets you quickly filter the list. You should further customize the table and search filters, but I’ll leave that task to you.

We’re now going to tweak the task’s detail view a bit, since it looks rather cluttered:

1
2
3
4
5
6
7
8
9
10
11
12
13
show do
  panel "Task Details" do
    attributes_table_for task do
      row("Status") { status_tag (task.is_done ? "Done" : "Pending"), (task.is_done ? :o k : :error) }
      row("Title") { task.title }
      row("Project") { link_to task.project.title, admin_project_path(task.project) }
      row("Assigned To") { link_to task.admin_user.email, admin_admin_user_path(task.admin_user) }
      row("Due Date") { task.due_date? ? l(task.due_date, :format => :long) : '-' }
    end
  end
  active_admin_comments
end

This will show a table for the attributes of the model (hence the method’s name, attributes_table_for). You specify the model, in this case task, and in the block passed, you define the rows you want to show. It’s roughly the same we defined for the project’s detail page, only for the task. You may be asking yourself: What’s that “active_admin_comments” method call for? Well, Active Admin provides a simple commenting system for each model. I enabled it here because commenting on a task could be very useful to discuss functionality, or something similar. If you don’t call that method, comments will be hidden.

Tasks

There’s another thing I’d like to show when viewing a task’s detail, and that’s the rest of the assignee’s tasks for that project. That’s easily done using sidebars!

1
2
3
4
5
6
sidebar "Other Tasks For This User", :o nly => :show do
  table_for current_admin_user.tasks.where(:project_id => task.project) do |t|
    t.column("Status") { |task| status_tag (task.is_done ? "Done" : "Pending"), (task.is_done ? :o k : :error) }
    t.column("Title") { |task| link_to task.title, admin_task_path(task) }
  end
end

This creates a sidebar panel, titled “Other Tasks For This User”, which is shown only on the “show” page. It will show a table for the currentadminuser, and all tasks where the project is the same as the project being shown (you see, task here will refer to the task being shown, since it’s a detail page for one task). The rest is more or less the same as before: some columns with task details.


Step 7 – The Dashboard

You may have noticed, when you first launched your browser and logged into your app, that there was a “Dashboard” section. This is a fully customizable page where you can show nearly anything: tables, statistics, whatever. We’re just going to add the user’s task list as an example. Open up the dashboards.rb file and revise it, like so:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ActiveAdmin::Dashboards.build do
  section "Your tasks for this week" do
    table_for current_admin_user.tasks.where('due_date > ? and due_date < ?', Time.now, 1.week.from_now) do |t|
      t.column("Status") { |task| status_tag (task.is_done ? "Done" : "Pending"), (task.is_done ? :o k : :error) }
      t.column("Title") { |task| link_to task.title, admin_task_path(task) }
      t.column("Assigned To") { |task| task.admin_user.email }
      t.column("Due Date") { |task| task.due_date? ? l(task.due_date, :format => :long) : '-' }
    end
  end
  section "Tasks that are late" do
    table_for current_admin_user.tasks.where('due_date < ?', Time.now) do |t|
      t.column("Status") { |task| status_tag (task.is_done ? "Done" : "Pending"), (task.is_done ? :o k : :error) }
      t.column("Title") { |task| link_to task.title, admin_task_path(task) }
      t.column("Assigned To") { |task| task.admin_user.email }
      t.column("Due Date") { |task| task.due_date? ? l(task.due_date, :format => :long) : '-' }
    end
  end
end

The code should be fairly familiar to you. It essentially creates two sections (using the section method and a title), with one table each, which displays current and late tasks, respectively.

Dashboard

Conclusion

We’ve created an extensive application in very few steps. You may be surprised to know that there are plenty more features that Active Admin has to offer, but it’s not possible to cover them all in just one tutorial, certainly. If you’re interested in learning more about this gem, visit activeadmin.info.

You also might like to check out my project, called active_invoices on GitHub, which is a complete invoicing application made entirely with Active Admin. If you have any questions, feel free to ask them in the comments, or send me a tweet.

0

0
 

http://stackoverflow.com/questions/4324341/streaming-audio-from-android-to-desktop-application

http://stackoverflow.com/questions/4324341/streaming-audio-from-android-to-desktop-application

 

What the title says really. I need to stream the audio from the microphone on the telephone and play it in a desktop application (also Java code) on a computer.

Using UDP or TCP does not matter for me, whatever works best. Phone and computer will be on same NAT anyway so transmission will work fine.

I have a fair idea of how to send the stream data from the device using this code:

MediaRecorder recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

String host = "10.0.2.2";
int port = 5740;

Socket socket = null;
try {
    socket = new Socket(InetAddress.getByName(host), port);

    ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket);
    recorder.setOutputFile(pfd.getFileDescriptor());
    recorder.prepare();
    recorder.start();

    Log.d(TAG, "Sending audio for 20 seconds..");
    Thread.sleep(20000);

    } catch (Exception e) {    
    // TODO Auto-generated catch block
        e.printStackTrace();
            }

The problem is, how do I play this stream in my java application on the PC? Or is there a better way to stream the sound?

I have mined the internet for information on this but without any good results but surely somebody must have accomplished this before?
 

0

0
 

Android send audio data to bluetooth in api 7 without using hidden classes

I have found this solution for API 8 Routing audio to Bluetooth Headset (non-A2DP) on Android

I would like to know how to do in API 7.

I was thinking in using http://developer.android.com/guide/topics/wireless/bluetooth.html#ManagingAConnection but I don’t know how could I send audio to the bluetooth device.


The first question is:

How to send audio data to bluetooth in api 7 without using hidden classes?


Also I readed How write a program to connect to a a2dp bluetooth device using pre 3.0 Android? but it is doing it with hidden API’s. So the question maybe is:

If I use hidden class BluetoothHeadset in API 7, (that for sure now is released since it is not hidden for API 15), the app will work ok in future versions? How can I be sure they didn’t change?

0

0
 

Routing audio to Bluetooth Headset (non-A2DP) on Android

sourcE: http://stackoverflow.com/questions/2144694/routing-audio-to-bluetooth-headset-non-a2dp-on-android

I have a non-A2DP single ear BT headset (Plantronics 510) and would like to use it with my Android HTC Magic to listen to low quality audio like podcasts/audio books.

After much googling I found that only phone call audio can be routed to the non-A2DP BT headsets. (I would like to know if you have found a ready solution to route all kinds of audio to non-A2DP BT headsets)

So I figured, somehow programmatically I can channel the audio to the stream that carries phone call audio. This way I will fool the phone to carry my mp3 audio to my BT headset. I wrote following simple code.

import android.content.*;
import android.app.Activity;
import android.os.Bundle;
import android.media.*;
import java.io.*;
import android.util.Log;

public class BTAudioActivity extends Activity
{
    private static final String TAG = "BTAudioActivity";

    private MediaPlayer mPlayer = null;
    private AudioManager amanager = null;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        amanager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        amanager.setBluetoothScoOn(true);
        amanager.setMode(AudioManager.MODE_IN_CALL);

        mPlayer = new MediaPlayer();

        try {
            mPlayer.setDataSource(new FileInputStream(
                "/sdcard/sample.mp3").getFD());

            mPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);

            mPlayer.prepare();

            mPlayer.start();
        } catch(Exception e) {
            Log.e(TAG, e.toString());
        }
    }

    @Override
    public void onDestroy()
    {
        mPlayer.stop();
        amanager.setMode(AudioManager.MODE_NORMAL);
        amanager.setBluetoothScoOn(false);
        super.onDestroy();
    }
}

As you can see I tried combinations of various methods that I thought will fool the phone to believe my audio is a phone call:

  • Using MediaPlayer’s setAudioStreamType(STREAM_VOICE_CALL)
  • using AudioManager’s setBluetoothScoOn(true)
  • using AudioManager’s setMode(MODE_IN_CALL)

But none of the above worked. If I remove the AudioManager calls in the above code, the audio plays from speaker and if I replace them as shown above then the audio stops coming from speakers, but it doesn’t come through the BT headset. So this might be a partial success.

I have checked that the BT headset works alright with phone calls.

There must be a reason for Android not supporting this. But I can’t let go of the feeling that it is not possible to programmatically reroute the audio. Any ideas?

P.S. above code needs following permission

<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>

 

This thread may be long dead but for those who might be trying the same thing, some notes from the AudioManager docs may be useful. It looks like the missing element is the startBluetoothSco() command but there are restrictions on the use of this channel. From the Android Dev site here:

public void startBluetoothSco () Since: API Level 8 Start bluetooth SCO audio connection.

Requires Permission: MODIFY_AUDIO_SETTINGS.

This method can be used by applications wanting to send and received audio to/from a bluetooth SCO headset while the phone is not in call.

As the SCO connection establishment can take several seconds, applications should not rely on the connection to be available when the method returns but instead register to receive the intent ACTION_SCO_AUDIO_STATE_CHANGED and wait for the state to be SCO_AUDIO_STATE_CONNECTED.

As the connection is not guaranteed to succeed, applications must wait for this intent with a timeout.

When finished with the SCO connection or if the establishment times out, the application must call stopBluetoothSco() to clear the request and turn down the bluetooth connection.

Even if a SCO connection is established, the following restrictions apply on audio output streams so that they can be routed to SCO headset: – the stream type must be STREAM_VOICE_CALL – the format must be mono – the sampling must be 16kHz or 8kHz

The following restrictions apply on input streams: – the format must be mono – the sampling must be 8kHz

Note that the phone application always has the priority on the usage of the SCO connection for telephony. If this method is called while the phone is in call it will be ignored. Similarly, if a call is received or sent while an application is using the SCO connection, the connection will be lost for the application and NOT returned automatically when the call ends.

See Also stopBluetoothSco() ACTION_SCO_AUDIO_STATE_CHANGED

Note that I have not tested this, I’m just passing along a lead I found in researching a similar project. I think Jayesh was close to the solution and the restrictions above may have been what was keeping it from working.

0

0
 

Software para Productividad: “No rompas la cadena” – Secreto de la productividad de Jerry Seinfeld

http://dontbreakthechain.com/what

Secreto de la productividad de Jerry Seinfeld

Editor: Cuando el desarrollador de softwareBrad Isaac nos dijo que tenía asesoramiento de la productividad de Jerry Seinfeld, que no podía rechazar la oportunidad de escuchar más. Siga leyendo para conocer toda la historia de Brad.

Hace años cuando Seinfeld era un nuevo programa de televisión, Jerry Seinfeld todavía era un cómic de gira. En ese momento, yo estaba rondando los clubes que hacen noches de micrófono abierto y tratando de aprender las cuerdas. Una noche yo estaba en el club donde Seinfeld trabajaba, y antes de que él subió al escenario, vi mi oportunidad. Tuve que pedir a Seinfeld si tenía algún consejo para un joven cómico. Lo que me dijo fue algo que me beneficiaría toda la vida …

Dijo que la manera de ser un cómic mejor era crear mejores chistes y la forma de crear mejores chistes era escribir todos los días. Sin embargo, su consejo fue mejor que eso. Tenía una gema de una técnica que utilizó el apalancamiento en sí mismo y se puede utilizar para motivar a ti mismo, incluso cuando usted no se siente como él.

Él reveló un sistema de calendario único que utiliza para presionar a sí mismo a escribir. Así es como funciona.

Él me dijo que consiguiera un calendario de pared grande que tiene un año entero en una sola página y colgarla en una pared prominente. El siguiente paso era conseguir un marcador de gran magia roja.

Dijo que por cada día que yo hago mi tarea de escribir, tengo que poner una X roja grande en ese día. “Después de unos días tendrás una cadena. Hemos de tener en ella y la cadena crecerá más cada día. Te gustará ver esa cadena, especialmente cuando se pone un par de semanas bajo su cinturón. Su único trabajo siguiente es No romper la cadena. “

“No romper la cadena”, dijo de nuevo para dar énfasis.

Con los años que he usado esta técnica en muchas áreas diferentes. Lo he utilizado para hacer ejercicio, aprender a programar, para aprender administración de la red, para crear sitios web exitosos y construir negocios exitosos.

Funciona porque no es el one-shot que hacer que nos empuja hacia dónde queremos ir, es la acción diaria consistente que construye resultados extraordinarios. Usted puede haber oído “pulgada por pulgada de nada es un juego de niños.” Pulgada a pulgada funciona si puede moverse ni un milímetro cada día.

La acción diaria se basa hábitos. Le da la práctica y le hará un experto en un corto período de tiempo. Si usted no romper la cadena, usted comenzará a identificar las oportunidades que de otro modo no lo haría. Pequeñas mejoras se acumulan en grandes mejoras rápidamente porque la acción diaria provee “interés compuesto”.

Omitiendo un día hace más fácil para saltar el siguiente.

A menudo he dicho que prefiero tener a alguien que se tomen medidas, incluso si es pequeño, todos los días a diferencia de alguien que se balancea dura una o dos veces a la semana. Seinfeld entiende que la acción diaria produce mayores beneficios que sentarse y tratar de noquear a 1000 chistes en un día.

Piense por un momento acerca de lo que la acción haría que el impacto más profundo en su vida si usted se trabajaba todos los días. Esa es la acción que yo recomiendo que pongas en tu calendario Seinfeld. Comience hoy y ganar su gran X roja y de aquí en adelante …

No rompas la cadena!

Brad Isaac es un programador de software principal y blogger. Usted puede leer sus estrategias de motivación todos los días en su blog el establecimiento de metas, lograr-IT!

0

0
 

Getting web2py up and running on ActiveState’s Stackato

POSTED 1 MONTH AGO

ActiveState has recently started their own PAAS based on CloudFoundry this blog post is to help you get up and running quickly with a Django CMS installation, and hopefully give you enough information to get your own applications on there as well. (Read more…)

Installing a Django application on Red Hat’s OpenShift PAAS

POSTED 1 MONTH AGO

Follow along as I install a django application onto Red Hat’s new PAAS OpenShift. (Read more…)

Standardizing Python WSGI deployment

POSTED 1 MONTH, 2 WEEKS AGO

Python needs a deployment standard similar to java’s WAR format in order to improve the way python applications are deployed on servers. What does it look like, and how do we get it done? (Read more…)

Developers guide to Running Django Applications on Heroku

POSTED 2 MONTHS, 2 WEEKS AGO

Follow me as I walk my way through installing a Django application on Heroku. (Read more…)

Django Hosting Roundup: (Ep.io vs Gondor.io vs DotCloud vs Heroku vs AppHosted vs DjangoZoom) Who wins?

POSTED 8 MONTHS, 2 WEEKS AGO

Django Hosting Roundup: (Ep.io vs Gondor.io vs DotCloud vs Heroku vs AppHosted vs DjangoZoom) Who wins? (Read more…)

DjangoZoom.com Review

POSTED 8 MONTHS, 2 WEEKS AGO

This is part five in my series on django hosting services, this time I take a look at DjangoZoom.com (Read more…)

AppHosted.com Django Hosting Service Review

POSTED 9 MONTHS AGO

Part four in my series about django hosting services. I got an early sneak peak at AppHosted.com, and here are my notes. (Read more…)

Deploying my Django application to DotCloud

POSTED 9 MONTHS, 3 WEEKS AGO

DotCloud has been generating a lot of buzz lately, and I wanted to check it out for myself, to see what everyone is talking about. Follow along as I deploy my first django application onto DotCloud. (Read more…)

My Day in Gondor.io

POSTED 10 MONTHS AGO

Eldarion just sent out a new batch of beta invites for their Django hosting service called Gondor, I was lucky enough to get an invite, so I decided to test it out. (Read more…)

My Experiences with ep.io

POSTED 10 MONTHS AGO

I was lucky enough to get an invite to the closed beta of a new django hosting service called ep.io. I have been using it for a new project I was creating, and decided to write about my experiences. (Read more…)

0

0
 

10 Cool Dashboard Designs

by Sunalini Rana
AD

Dashboard Designs or commonly knows as an Admin area is basically used as a Front end area to manage the data. Your clients can check your sales figures and even the individual employee’s contribution in increasing the profit ratio. Although the usability of Dashboards is very high, but there are very few Free Templates available online.

 

Today we are showcasing only the “Free Templates” for Dashboard design that will make administrative work easier and fun filing for your clients and also reduce your headache to make a Dashboard Design from scratch.

If you like this article, you might be interested in some of our older articles onProfessional Comparison TablesBest Email TemplatesEffective Newsletter Designs, and How To Create Effective Signup/Registration Forms.

InAdmin Panel

InAdmin Panel

More Information on InAdmin Panel

Spring Time

Spring Time

More Information on Spring Time

Yellow Admin Template

Yellow Admin Template

More Information on Yellow Admin Template

Free Admin Template

Free Admin Template

More Information on Free Admin Template

Free Admin Template

Free Admin Template

More Information on Free Admin Template

Free admin skin Available

Free admin skin Available

More Information on Free admin skin Available

Free Admin Template Transdmin (Direct Link)

Free Admin Template Transdmin

More Information on Free Admin Template Transdmin

Set of XHTML & CSS administrator templates

Set of XHTML & CSS administrator templates

More Information on Set of XHTML & CSS administrator templates

Admin Template

Admin Template

More Information on Admin Template


0

0
 

10 Cool Dashboard Designs

by Sunalini Rana
AD

Dashboard Designs or commonly knows as an Admin area is basically used as a Front end area to manage the data. Your clients can check your sales figures and even the individual employee’s contribution in increasing the profit ratio. Although the usability of Dashboards is very high, but there are very few Free Templates available online.

 

Today we are showcasing only the “Free Templates” for Dashboard design that will make administrative work easier and fun filing for your clients and also reduce your headache to make a Dashboard Design from scratch.

If you like this article, you might be interested in some of our older articles onProfessional Comparison TablesBest Email TemplatesEffective Newsletter Designs, and How To Create Effective Signup/Registration Forms.

InAdmin Panel

InAdmin Panel

More Information on InAdmin Panel

Spring Time

Spring Time

More Information on Spring Time

Yellow Admin Template

Yellow Admin Template

More Information on Yellow Admin Template

Free Admin Template

Free Admin Template

More Information on Free Admin Template

Free Admin Template

Free Admin Template

More Information on Free Admin Template

Free admin skin Available

Free admin skin Available

More Information on Free admin skin Available

Free Admin Template Transdmin (Direct Link)

Free Admin Template Transdmin

More Information on Free Admin Template Transdmin

Set of XHTML & CSS administrator templates

Set of XHTML & CSS administrator templates

More Information on Set of XHTML & CSS administrator templates

Admin Template

Admin Template

More Information on Admin Template


0

0