Django

Code

Ticket #5465: django-package2.diff

File django-package2.diff, 31.5 kB (added by jezdez, 1 year ago)

changed the order of the subcommands and options in the docs, following a backwards incompatible change from #6075 (http://code.djangoproject.com/wiki/BackwardsIncompatibleChanges#django-admin.pyandmanage.pynowrequiresubcommandstoprecedeoptions)

  • django/core/management/commands/startapp.py

    old new  
     1import os 
     2from optparse import make_option 
    13from django.core.management.base import copy_helper, CommandError, LabelCommand 
    2 import os 
    34 
    45class Command(LabelCommand): 
     6    option_list = LabelCommand.option_list + ( 
     7        make_option('--noskeleton', action='store_false', dest='use_skeleton', default=True, 
     8            help='Tells Django to disable the metadata assistent and skip extended skeleton file creation.'), 
     9    ) 
    510    help = "Creates a Django app directory structure for the given app name in the current directory." 
    611    args = "[appname]" 
    712    label = 'application name' 
     
    1217    can_import_settings = False 
    1318 
    1419    def handle_label(self, app_name, directory=None, **options): 
     20        use_skeleton = options.get('use_skeleton', True) 
    1521        if directory is None: 
    1622            directory = os.getcwd() 
    1723        # Determine the project_name a bit naively -- by looking at the name of 
     
    1925        project_dir = os.path.normpath(os.path.join(directory, '..')) 
    2026        parent_dir = os.path.basename(project_dir) 
    2127        project_name = os.path.basename(directory) 
    22         if app_name == project_name: 
    23             raise CommandError("You cannot create an app with the same name (%r) as your project." % app_name) 
     28        if use_skeleton: 
     29            directory = os.path.join(directory, app_name) 
     30            try: 
     31                os.mkdir(directory) 
     32            except OSError, e: 
     33                raise CommandError(e) 
     34        else: 
     35            if app_name == project_name: 
     36                raise CommandError("You cannot create an app with the same name (%r) as your project." % app_name) 
    2437        copy_helper(self.style, 'app', app_name, directory, parent_dir) 
     38        if use_skeleton: 
     39            from django.utils import package 
     40            package.standalone_app(directory, app_name) 
    2541 
    2642class ProjectCommand(Command): 
    2743    help = "Creates a Django app directory structure for the given app name in this project's directory." 
  • django/core/management/commands/editapp.py

    old new  
     1from django.core.management.base import LabelCommand, CommandError 
     2import os 
     3 
     4class Command(LabelCommand): 
     5    help = "Edits releae metadata of the Django app in the current directory." 
     6    args = "[appname]" 
     7    label = 'application name' 
     8     
     9    requires_model_validation = False 
     10    # Can't import settings during this command, because they haven't 
     11    # necessarily been created. 
     12    can_import_settings = False 
     13     
     14    def handle_label(self, app_name, directory=None, **options): 
     15        if directory is None: 
     16            directory = os.getcwd() 
     17        release_dir = os.path.join(directory, app_name) 
     18        release_file = os.path.join(directory, "release.py") 
     19         
     20        if os.path.isdir(release_dir) and os.path.isfile(release_file): 
     21            from django.utils import package 
     22            release = package.Release(directory) 
     23            if release.loaded: 
     24                package.standalone_app(directory) 
     25            else: 
     26                raise CommandError("The release.py file does not contain any data.") 
     27        elif not os.path.isdir(release_dir) and \ 
     28                os.path.isfile(release_file): 
     29            raise CommandError("There is a release.py file but the given appname doesn't match.") 
     30        else: 
     31            raise CommandError("There is no release.py file in the current directory.") 
  • django/views/debug.py

    old new  
    705705  <p>Of course, you haven't actually done any work yet. Here's what to do next:</p> 
    706706  <ul> 
    707707    <li>If you plan to use a database, edit the <code>DATABASE_*</code> settings in <code>{{ project_name }}/settings.py</code>.</li> 
    708     <li>Start your first app by running <code>python {{ project_name }}/manage.py startapp [appname]</code>.</li> 
     708    <li>Start your first app by running <code>python {{ project_name }}/manage.py startapp --noskeleton [appname]</code>.</li> 
    709709  </ul> 
    710710</div> 
    711711 
  • django/utils/package/validators.py

    old new  
     1"Validators used for package management" 
     2import os, sys, re 
     3from pkg_resources import safe_version, safe_name 
     4from django.core import validators 
     5 
     6INVALID_APP_NAMES = ('django', 'site', 'test', 'tests', 'release', 'doc', 'docs') 
     7find_keywords_re = re.compile(r'[-\w\.]+') 
     8 
     9def isvalidname(value): 
     10    if value.lower() in INVALID_APP_NAMES: 
     11        sys.stderr.write("Error: That app name is invalid. Please use another name.\n") 
     12        return False 
     13    return True 
     14 
     15def isvalidversion(value): 
     16    if not value or value.startswith("-"): 
     17        sys.stderr.write("Error: That version number is invalid. Use only letters and digits.\n") 
     18        return False 
     19    return True 
     20 
     21def isalnum(value): 
     22    if not value.isalnum(): 
     23        sys.stderr.write("Error: That input is invalid. Use only letters, digits and underscores.\n") 
     24        return False 
     25    return True 
     26 
     27def isgiven(value): 
     28    if not value: 
     29        sys.stderr.write("Error: This field is required.\n") 
     30        return False 
     31    return True 
     32 
     33def iskeywordlist(value): 
     34    if not find_keywords_re.search(value): 
     35        sys.stderr.write("Error: This keyword list is invalid.\n") 
     36        return False 
     37    return True 
     38 
     39def isemailadress(value): 
     40    if not validators.email_re.search(value): 
     41        sys.stderr.write("Error: That e-mail address is invalid.\n") 
     42        return False 
     43    return True 
     44 
     45def isyesorno(value): 
     46    if not value.lower() in ('yes', 'no'): 
     47        sys.stderr.write("Error: Please enter yes or no.\n") 
     48        return False 
     49    return True 
  • django/utils/package/ez_setup.py

    old new  
     1#!python 
     2"""Bootstrap setuptools installation 
     3 
     4If you want to use setuptools in your package's setup.py, just include this 
     5file in the same directory with it, and add this to the top of your setup.py:: 
     6 
     7    from ez_setup import use_setuptools 
     8    use_setuptools() 
     9 
     10If you want to require a specific version of setuptools, set a download 
     11mirror, or use an alternate download directory, you can do so by supplying 
     12the appropriate options to ``use_setuptools()``. 
     13 
     14This file can also be run as a script to install or upgrade setuptools. 
     15""" 
     16import sys 
     17DEFAULT_VERSION = "0.6c6" 
     18DEFAULT_URL     = "http://cheeseshop.python.org/packages/%s/s/setuptools/" % sys.version[:3] 
     19 
     20md5_data = { 
     21    'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca', 
     22    'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb', 
     23    'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b', 
     24    'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a', 
     25    'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618', 
     26    'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac', 
     27    'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5', 
     28    'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4', 
     29    'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c', 
     30    'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b', 
     31    'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27', 
     32    'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277', 
     33    'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa', 
     34    'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e', 
     35    'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e', 
     36    'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f', 
     37    'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2', 
     38    'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc', 
     39    'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167', 
     40    'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64', 
     41    'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d', 
     42    'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20', 
     43    'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab', 
     44    'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53', 
     45} 
     46 
     47import sys, os 
     48 
     49def _validate_md5(egg_name, data): 
     50    if egg_name in md5_data: 
     51        from md5 import md5 
     52        digest = md5(data).hexdigest() 
     53        if digest != md5_data[egg_name]: 
     54            print >>sys.stderr, ( 
     55                "md5 validation of %s failed!  (Possible download problem?)" 
     56                % egg_name 
     57            ) 
     58            sys.exit(2) 
     59    return data 
     60 
     61 
     62def use_setuptools( 
     63    version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, 
     64    download_delay=15 
     65): 
     66    """Automatically find/download setuptools and make it available on sys.path 
     67 
     68    `version` should be a valid setuptools version number that is available 
     69    as an egg for download under the `download_base` URL (which should end with 
     70    a '/').  `to_dir` is the directory where setuptools will be downloaded, if 
     71    it is not already available.  If `download_delay` is specified, it should 
     72    be the number of seconds that will be paused before initiating a download, 
     73    should one be required.  If an older version of setuptools is installed, 
     74    this routine will print a message to ``sys.stderr`` and raise SystemExit in 
     75    an attempt to abort the calling script. 
     76    """ 
     77    try: 
     78        import setuptools 
     79        if setuptools.__version__ == '0.0.1': 
     80            print >>sys.stderr, ( 
     81            "You have an obsolete version of setuptools installed.  Please\n" 
     82            "remove it from your system entirely before rerunning this script." 
     83            ) 
     84            sys.exit(2) 
     85    except ImportError: 
     86        egg = download_setuptools(version, download_base, to_dir, download_delay) 
     87        sys.path.insert(0, egg) 
     88        import setuptools; setuptools.bootstrap_install_from = egg 
     89 
     90    import pkg_resources 
     91    try: 
     92        pkg_resources.require("setuptools>="+version) 
     93 
     94    except pkg_resources.VersionConflict, e: 
     95        # XXX could we install in a subprocess here? 
     96        print >>sys.stderr, ( 
     97            "The required version of setuptools (>=%s) is not available, and\n" 
     98            "can't be installed while this script is running. Please install\n" 
     99            " a more recent version first.\n\n(Currently using %r)" 
     100        ) % (version, e.args[0]) 
     101        sys.exit(2) 
     102 
     103def download_setuptools( 
     104    version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, 
     105    delay = 15 
     106): 
     107    """Download setuptools from a specified location and return its filename 
     108 
     109    `version` should be a valid setuptools version number that is available 
     110    as an egg for download under the `download_base` URL (which should end 
     111    with a '/'). `to_dir` is the directory where the egg will be downloaded. 
     112    `delay` is the number of seconds to pause before an actual download attempt. 
     113    """ 
     114    import urllib2, shutil 
     115    egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3]) 
     116    url = download_base + egg_name 
     117    saveto = os.path.join(to_dir, egg_name) 
     118    src = dst = None 
     119    if not os.path.exists(saveto):  # Avoid repeated downloads 
     120        try: 
     121            from distutils import log 
     122            if delay: 
     123                log.warn(""" 
     124--------------------------------------------------------------------------- 
     125This script requires setuptools version %s to run (even to display 
     126help).  I will attempt to download it for you (from 
     127%s), but 
     128you may need to enable firewall access for this script first. 
     129I will start the download in %d seconds. 
     130 
     131(Note: if this machine does not have network access, please obtain the file 
     132 
     133   %s 
     134 
     135and place it in this directory before rerunning this script.) 
     136---------------------------------------------------------------------------""", 
     137                    version, download_base, delay, url 
     138                ); from time import sleep; sleep(delay) 
     139            log.warn("Downloading %s", url) 
     140            src = urllib2.urlopen(url) 
     141            # Read/write all in one block, so we don't create a corrupt file 
     142            # if the download is interrupted. 
     143            data = _validate_md5(egg_name, src.read()) 
     144            dst = open(saveto,"wb"); dst.write(data) 
     145        finally: 
     146            if src: src.close() 
     147            if dst: dst.close() 
     148    return os.path.realpath(saveto) 
     149 
     150def main(argv, version=DEFAULT_VERSION): 
     151    """Install or upgrade setuptools and EasyInstall""" 
     152 
     153    try: 
     154        import setuptools 
     155    except ImportError: 
     156        egg = None 
     157        try: 
     158            egg = download_setuptools(version, delay=0) 
     159            sys.path.insert(0,egg) 
     160            from setuptools.command.easy_install import main 
     161            return main(list(argv)+[egg])   # we're done here 
     162        finally: 
     163            if egg and os.path.exists(egg): 
     164                os.unlink(egg) 
     165    else: 
     166        if setuptools.__version__ == '0.0.1': 
     167            # tell the user to uninstall obsolete version 
     168            use_setuptools(version) 
     169 
     170    req = "setuptools>="+version 
     171    import pkg_resources 
     172    try: 
     173        pkg_resources.require(req) 
     174    except pkg_resources.VersionConflict: 
     175        try: 
     176            from setuptools.command.easy_install import main 
     177        except ImportError: 
     178            from easy_install import main 
     179        main(list(argv)+[download_setuptools(delay=0)]) 
     180        sys.exit(0) # try to force an exit 
     181    else: 
     182        if argv: 
     183            from setuptools.command.easy_install import main 
     184            main(argv) 
     185        else: 
     186            print "Setuptools version",version,"or greater has been installed." 
     187            print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)' 
     188 
     189 
     190 
     191def update_md5(filenames): 
     192    """Update our built-in md5 registry""" 
     193 
     194    import re 
     195    from md5 import md5 
     196 
     197    for name in filenames: 
     198        base = os.path.basename(name) 
     199        f = open(name,'rb') 
     200        md5_data[base] = md5(f.read()).hexdigest() 
     201        f.close() 
     202 
     203    data = ["    %r: %r,\n" % it for it in md5_data.items()] 
     204    data.sort() 
     205    repl = "".join(data) 
     206 
     207    import inspect 
     208    srcfile = inspect.getsourcefile(sys.modules[__name__]) 
     209    f = open(srcfile, 'rb'); src = f.read(); f.close() 
     210 
     211    match = re.search("\nmd5_data = {\n([^}]+)}", src) 
     212    if not match: 
     213        print >>sys.stderr, "Internal error!" 
     214        sys.exit(2) 
     215 
     216    src = src[:match.start(1)] + repl + src[match.end(1):] 
     217    f = open(srcfile,'w') 
     218    f.write(src) 
     219    f.close() 
     220 
     221 
     222if __name__=='__main__': 
     223    if len(sys.argv)>2 and sys.argv[1]=='--md5update': 
     224        update_md5(sys.argv[2:]) 
     225    else: 
     226        main(sys.argv[1:]) 
     227 
     228 
     229 
     230 
  • django/utils/package/__init__.py

    old new  
     1from ez_setup import use_setuptools 
     2use_setuptools() 
     3 
     4import os, sys, urlparse, shutil 
     5from setuptools import setup as original_setup 
     6from pkg_resources import safe_version, safe_name 
     7 
     8from django.core.management.base import CommandError 
     9from django.utils.package.prompts import * 
     10 
     11def setup(**args): 
     12    """ 
     13    Hacky wrapper to make sure that the default PyPI keyword is included when 
     14    the setup.py of an app is used 
     15    """ 
     16    keywords = args.get('keyword', PYPI_KEYWORD) 
     17    if PYPI_KEYWORD not in keywords: 
     18        args['keyword'] = "%s %s" % (PYPI_KEYWORD, args['keyword']) 
     19    original_setup(args) 
     20 
     21def generate_default_files(template_dir): 
     22    """ 
     23    Generates a list of filepaths and appendant content. 
     24    """ 
     25    for d, subdirs, files in os.walk(template_dir): 
     26        for f in files: 
     27            parent = os.path.basename(d) 
     28            if f.startswith('.') or f.endswith('.pyc') or parent.startswith('.'): 
     29                continue 
     30            filepath = os.path.join(d, f) 
     31            filecontent = open(filepath, 'r').read() 
     32            yield (os.path.basename(filepath), filecontent) 
     33 
     34# could also be combined with skeleton files in django.conf (?)s 
     35TEMPLATE_DIR =  os.path.join(os.path.abspath(os.path.dirname(__file__)), "templates") 
     36DEFAULT_FILES = generate_default_files(TEMPLATE_DIR) 
     37DEFAULT_DIRECTORIES = ('docs', 'tests', '%(NAME)s/templates/%(NAME)s') 
     38APP_REPOSITORY_URL = "http://www.djangoproject.com/apps/" 
     39 
     40class Release(dict): 
     41    """ 
     42    Wrapper to handle release metadata from release.py and make it available 
     43    as items and attributes of a dict object. Setting attributes will actually 
     44    set the dict items. 
     45    """ 
     46    def __init__(self, directory, internal=None): 
     47        self.directory = directory 
     48        self.renamed_name = False 
     49        self.loaded = False 
     50        self.manifest = "" 
     51         
     52        if internal is None: 
     53            internal = {} 
     54        self.load() 
     55        dict.__init__(self, internal) 
     56        self.__initialised = True 
     57     
     58    def __getattr__(self, item): 
     59        """ 
     60        Simulates getting attributes 
     61        """ 
     62        try: 
     63            return self.__getitem__(item) 
     64        except KeyError: 
     65            return False 
     66     
     67    def __setattr__(self, item, value): 
     68        """ 
     69        Simulates setting attributes 
     70        """ 
     71        if not self.__dict__.has_key('_Release__initialised'): 
     72            return dict.__setattr__(self, item, value) 
     73        elif self.__dict__.has_key(item): 
     74            dict.__setattr__(self, item, value) 
     75        else: 
     76            self.__setitem__(item, value) 
     77     
     78    def exists(self): 
     79        """ 
     80        Returns true if the release already exists and could be loaded 
     81        """ 
     82        return len(self)>0 
     83     
     84    def load(self): 
     85        """ 
     86        Loads metadata from release.py into itself 
     87        """ 
     88        sys.path.insert(0, self.directory) 
     89        os.chdir(self.directory) 
     90        try: 
     91            rel = __import__("release", {}, {}, ['']) 
     92            for info in dir(rel): 
     93                if info == info.upper(): 
     94                    self[info] = str(getattr(rel, info)) 
     95        except (ImportError, AttributeError): 
     96            return 
     97        self.loaded = True 
     98     
     99    def save(self, path, filename, data): 
     100        """ 
     101        Saves given data to a file 
     102        """ 
     103        filepath = os.path.join(path, filename) 
     104        try: 
     105            if os.path.isfile(filepath): 
     106                filecontent = open(filepath, 'r').read() 
     107                if filecontent == data: 
     108                    return 
     109            f = open(filepath, 'w') 
     110            f.write(data) 
     111            f.close() 
     112        except OSError, e: 
     113            raise CommandError(e) 
     114        print "Written: %s" % filepath 
     115     
     116    def check_path(self): 
     117        """ 
     118        Moves an app directory if the app was renamed (except templates dir). 
     119        """ 
     120        if self.renamed_name: 
     121            old_path = os.path.join(self.directory, self.renamed_name) 
     122            new_path = os.path.join(self.directory, self.NAME) 
     123            try: 
     124                shutil.move(old_path, new_path) 
     125            except (IOError, OSError), e: 
     126                raise CommandError(e) 
     127            else: 
     128                print "Moved: %r to %r" % (old_path, new_path) 
     129                print "If necessary please move the templates manually." 
     130            self.renamed_name = False 
     131     
     132    def update(self, directories=DEFAULT_DIRECTORIES, files=DEFAULT_FILES): 
     133        """ 
     134        Creates default directories and default files and should be called at 
     135        the end of the assistent. 
     136        """ 
     137        # check if the app was renamed and move it if yes 
     138        self.check_path() 
     139        # create default directories 
     140         
     141        for newdir in directories: 
     142            try: 
     143                newpath = os.path.join(self.directory, newdir % self) 
     144                if not os.path.exists(newpath): 
     145                    os.makedirs(newpath) 
     146                    print "Created: %s" % newpath 
     147                elif not os.access(newpath, os.W_OK): 
     148                    raise CommandError("You have no write access to the directory.") 
     149            except OSError, e: 
     150                raise CommandError(e) 
     151            self.manifest += "recursive-include %s *\n" % newdir % self 
     152         
     153        # write default files 
     154        for newfile in files: 
     155            if self.loaded and newfile[0].endswith(".txt"): 
     156                continue 
     157            self.save(self.directory, newfile[0], newfile[1] % self) 
     158            self.manifest += "include %s\n" % newfile[0] % self 
     159         
     160        # save manifest to file 
     161        self.save(self.directory, "MANIFEST.in", self.manifest) 
     162        self.loaded = True 
     163 
     164    def clean_up(self): 
     165        """ 
     166        Helper function for file clean-up after interruption 
     167        """ 
     168        try: 
     169            shutil.rmtree(self.directory, True) 
     170        except: 
     171            pass 
     172 
     173def ask(prompt): 
     174    return prompt.ask() 
     175 
     176def standalone_app(directory, default_name=None): 
     177    """ 
     178    Helper function for creating a setup.py file for modules under the current 
     179    workding dir. All arguments are required and will be prompted for if 
     180    invalid or not given. 
     181    """ 
     182    release = Release(directory) 
     183    if default_name is not None and default_name.lower() in INVALID_APP_NAMES: 
     184        release.clean_up(directory) 
     185        raise CommandError("%r conflicts with the name of some package files and cannot be used as an app name. Please try another name." % default_name) 
     186    if release.loaded: 
     187        print "Django app found: %s (%s)." % (release.NAME, release.VERSION) 
     188    try: 
     189        name = Name(default_name or release.NAME or '').ask() 
     190        # what if the name was changed during editapp? 
     191        if name not in (release.NAME, default_name): 
     192            release.renamed_name = release.NAME or default_name 
     193        release.NAME = name 
     194        release.URL = urlparse.urljoin(APP_REPOSITORY_URL, name) 
     195        release.VERSION = Version(release.VERSION or '').ask() 
     196        release.SUMMARY = Summary(release.SUMMARY or '').ask() 
     197        release.KEYWORDS = Keywords(release.KEYWORDS or '').ask() 
     198        release.AUTHOR = Author(release.AUTHOR or '').ask() 
     199        release.AUTHOR_EMAIL = Email(release.AUTHOR_EMAIL or '').ask() 
     200        release.ZIP_SAFE = ZipSafe(release.ZIP_SAFE or '').ask() 
     201         
     202    except (KeyboardInterrupt, EOFError): 
     203        # Delete directory if canceled 
     204        if not release.loaded: 
     205            clean_up(directory) 
     206        print "\n" 
     207        raise CommandError("Operation cancelled.") 
     208    # Update the release with the new meta data 
     209    release.update() 
  • django/utils/package/prompts.py

    old new  
     1from django.utils.package.validators import * 
     2PYPI_KEYWORD = "django.apps" 
     3 
     4class Prompt(object): 
     5    """Simple base class for prompting""" 
     6    def __init__(self, default=None): 
     7        self.default = default 
     8        self.title = self.__class__.__name__ 
     9        self.preflight() 
     10        self.setup() 
     11     
     12    def setup(self): 
     13        "sets up the user dialog" 
     14        self.question = self.title 
     15        if self.default is not None: 
     16            self.question += ' (%r)' % self.default 
     17        self.question += ': ' 
     18     
     19    def ask(self): 
     20        "main loop for user input" 
     21        while 1: 
     22            response = raw_input(self.question).strip() 
     23            if not response: 
     24                if self.default is not None: 
     25                    response = self.default 
     26            if self.validate(response): 
     27                return self.postflight(response) 
     28     
     29    def preflight(self): 
     30        "can be used to manipulate the default data" 
     31        pass 
     32     
     33    def validate(self, response): 
     34        "validates user response against validators" 
     35        return isgiven(response) 
     36     
     37    def postflight(self, response): 
     38        "can be used to manipulate the response" 
     39        return response 
     40 
     41class Name(Prompt): 
     42    "the application and directory name" 
     43    def validate(self, response): 
     44        response = safe_name(response) 
     45        return isalnum(response) and isvalidname(response) 
     46 
     47class Version(Prompt): 
     48    "the version, validated against pkg_resources" 
     49    def validate(self, response): 
     50        response = safe_version(response) 
     51        return isvalidversion(response) 
     52         
     53class Keywords(Prompt): 
     54    "the keywords, includes the default PyPI keyword" 
     55    def preflight(self): 
     56        keywordlist = find_keywords_re.findall(self.default) 
     57        if PYPI_KEYWORD in keywordlist: 
     58            keywordlist.remove(PYPI_KEYWORD) 
     59            self.default = " ".join(keywordlist).strip() 
     60     
     61    def validate(self, response): 
     62        return isgiven(response) and iskeywordlist(response) 
     63     
     64    def postflight(self, response): 
     65        keywordlist = find_keywords_re.findall(response) 
     66        keywordlist.insert(0,PYPI_KEYWORD) 
     67        return " ".join(keywordlist).strip() 
     68 
     69class Email(Prompt): 
     70    "e-mail adress of the application author" 
     71    def validate(self, response): 
     72        return isgiven(response) and isemailadress(response) 
     73 
     74class ZipSafe(Prompt): 
     75    "defines if the egg distribution can be a zipped file while installation" 
     76    def preflight(self): 
     77        if self.default.lower() in ("true", "false"): 
     78            self.default = {'true':'yes','false':'no'}[self.default.lower()] 
     79     
     80    def validate(self, response): 
     81        return isyesorno(response) 
     82     
     83    def postflight(self, response): 
     84        return {'yes':True,'no':False}[response] 
     85 
     86class Author(Prompt): 
     87    "name of the app author and owner" 
     88    pass 
     89 
     90class Summary(Prompt): 
     91    "short summary about the app" 
     92    pass 
  • django/utils/package/templates/INSTALL.txt

    old new  
     1Thanks for downloading "%(NAME)s". 
     2 
     3To install it, run the following command inside this directory: 
     4 
     5    python setup.py install 
     6 
     7Or if you'd prefer you can use any other setuptools function, or simply 
     8place the included ``%(NAME)s`` directory somewhere on your Python path. 
     9 
     10Note that this application requires Python 2.3 or later, and Django 
     110.97 or later. You can obtain Python from http://www.python.org/ and 
     12Django from http://www.djangoproject.com/. 
  • django/utils/package/templates/release.py

    old new  
     1# Metadata used for packaging, handle with care 
     2NAME = "%(NAME)s" 
     3VERSION = "%(VERSION)s" 
     4URL = "%(URL)s" 
     5AUTHOR = "%(AUTHOR)s" 
     6AUTHOR_EMAIL = "%(AUTHOR_EMAIL)s" 
     7SUMMARY = "%(SUMMARY)s" 
     8KEYWORDS = "%(KEYWORDS)s" 
     9ZIP_SAFE = %(ZIP_SAFE)s 
  • django/utils/package/templates/setup.py

    old new  
     1from setuptools import find_packages 
     2from django.utils.package import setup 
     3 
     4try: 
     5    import release 
     6except ImportError: 
     7    raise "Please add a release.py file to the application directory." 
     8 
     9setup( 
     10    name = release.NAME, 
     11    version = release.VERSION, 
     12    url = release.URL, 
     13    author = release.AUTHOR, 
     14    author_email = release.AUTHOR_EMAIL, 
     15    summary = release.SUMMARY, 
     16    zip_safe = release.ZIP_SAFE, 
     17    keywords = release.KEYWORDS, 
     18    packages = find_packages(), 
     19    include_package_data = True, 
     20) 
  • django/utils/package/templates/README.txt

    old new  
     1%(NAME)s 
     2============================================================================== 
     3 
     4TODO 
  • extras/django_bash_completion

    old new  
    4242    prev="${COMP_WORDS[COMP_CWORD-1]}" 
    4343 
    4444    # Standalone options 
    45     opts="--help --settings --pythonpath --noinput --noreload --format --indent --verbosity --adminmedia --version" 
     45    opts="--help --settings --pythonpath --noinput --noreload --noskeleton --format --indent --verbosity --adminmedia --version" 
    4646    # Actions 
    4747    actions="adminindex createcachetable dbshell diffsettings \ 
    4848             dumpdata flush inspectdb loaddata reset runfcgi runserver \ 
  • docs/tutorial01.txt

    old new  
    220220To create your app, make sure you're in the ``mysite`` directory and type 
    221221this command:: 
    222222 
    223     python manage.py startapp polls 
     223    python manage.py startapp --noskeleton polls 
    224224 
    225225That'll create a directory ``polls``, which is laid out like this:: 
    226226 
  • docs/tutorial03.txt

    old new  
    418418with minimal fuss. 
    419419 
    420420Our poll app is pretty decoupled at this point, thanks to the strict directory 
    421 structure that ``python manage.py startapp`` created, but one part of it is 
    422 coupled to the Django settings: The URLconf. 
     421structure that ``python manage.py startapp --noskeleton`` created, but one 
     422part of it is coupled to the Django settings: The URLconf. 
    423423 
    424424We've been editing the URLs in ``mysite/urls.py``, but the URL design of an 
    425425app is specific to the app, not to the Django installation -- so let's move the 
  • docs/man/django-admin.1

    old new  
    8787Prints the SQL statements for resetting PostgreSQL sequences for the 
    8888given app name(s). 
    8989.TP 
    90 .BI "startapp [" "appname" "]" 
     90.BI "startapp [" "\-\-noskeleton" "] [" "appname" "]" 
    9191Creates a Django app directory structure for the given app name in 
    9292the current directory. 
     93.BI \-\-noskeleton 
     94option disables the assistent for creating reusable Django apps. 
    9395.TP 
    9496.BI "startproject [" "projectname" "]" 
    9597Creates a Django project directory structure for the given project name 
  • docs/django-admin.txt

    old new  
    505505Creates a Django app directory structure for the given app name in the current 
    506506directory. 
    507507 
     508Turning off the metadata assistent 
     509~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     510 
     511Use the ``--noskeleton`` option to disable the assistent which asks for 
     512metadata to create reusable Django apps. This means you won't be asked for 
     513detailed information about the app you are going to create and no additional 
     514files will be created. 
     515 
    508516startproject <projectname> 
    509517-------------------------- 
    510518