~ubuntu-branches/ubuntu/natty/quickly/natty

« back to all changes in this revision

Viewing changes to data/templates/ubuntu-application/license.py

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2010-03-29 19:00:48 UTC
  • mfrom: (8.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100329190048-olhobq492x3xnztz
Tags: 0.3.90-0ubuntu1
* New release:
  Quickly core:
  - check now that --template has one argument
  - -- enables to give options to templates (unknown options and arguments
    are still given to templates but -- specify explicity what to give to
    templates commands like -h, --version...)
  - check and enable recreation of the credential if user deletes it on
    Launchpad
  - Use realpath so that we can symlink to the binary in trunk.
    (Jonathan Lange)
  - project_path_not_found is raised when data_path_not_found should be
    (originated from Philip Peitsch's patch). (LP: #497688)
  - importing command in one template from another template is now possible
    support as well "all" keyword to import all commands from a template
    into another one (take care of overridden commands too)
    (LP: #452306, #487301)
  - add an apport hook to get installed templates (LP: #411127)
  - enable option completion for templates
  - handle now version upgrade, launching script for templates and handling
    versionning on them
  - change getstarted wording (LP: #486180) - Grant
  - Quickly ship now "version" tag instead of "format" tag
  - add some templatetools to check X display
  - if a commands exit with 4, do not show "ERROR:" (case of wrong command
    usage, for instance)
  - Rewrote importing module in both bin/quickly and ubuntu-project binary
  - Add get_camel_case_name() and get_sentence_name() to templatetools
  - Refactor some code in pre_create hook()
  - Now dashes and spaces support in project name! Dealing with python and
    packaging issues for you. (LP: #493130)
  - Provide Quickly API (LP: #426480)
  - Fix some issues in the man page
  ubuntu-application Template:
  - Enabling upload to team or user ppa, as well as any ppa.
    Use --ppa ppaname or --ppa team/ppaname
    .quickly file can be used as well with ppa = ppaname or
    ppa = team/ppaname (LP: #470192)
    ppa completion is also available
  - Change BSD header by full license
  - Add MIT license
  - Fixes an error when launchpad display name contains unicode character
    (Petar Vasić)
  - Fix typo in quickly help save (Petar Vasić)
  - Adds logo.png as logo property in about dialog (LP: #478389)
    (Petar Vasić)
  - Remove lp-project-change command and add configure command.
    configure lp-project [project_name] to set/reset lp project binded to
    your Quickly project
    ppa <ppa name> to set a default ppa with your project
  - Fix ~/.selected-editor being ignored (LP: #484730)
  - Fix wrong shell completion when in a template (it wrongly proposed
    all commands followed by templates)
  - Check if we have a X display available before running "run" or launching
    GUI in "create" command.
  - add -- support in quickly run to pass options like --help, --version so
    that Quickly core don't take them.
  - enable preferences save call being called multiple times (Philip Peitsch)
  - Use realpath so that we can symlink to the binary in trunk.
  - Fixed some errors in the tutorial (Brian) (LP: #499356)
  - Fix missing import sys in setup.py (Philip Peitsch) (LP: #499712)
  - rename ubuntu-project to ubuntu-application
  - enhance quickly license (no more Copyright file, only one AUTHORS file)
    personal license needs COPYING file now (and the header will be copied in
    every files). No more # needed in those files too. Some other little
    refactoring too (LP: #469330)
  - autolicence by default on first share/release (with LP info and on GPL-3)
  - change versionning support in ubuntu application: (LP: #476814)
   + quickly share just adds -publicX to current version where X is bumped
     at each "quicky share" execution
   + quickly release remove -publicX (if any) and release with current YY.MM.
     If there is already a release with that version, it will be YY.MM.1, 
     then YY.MM.2
  - add accelerators to menu items (jens persson)
  - set correctly title dialog (Philip Peitsch) (LP: #501999)
  - about dialog box is now fully automated: (LP: #478414)
   + update copyright, authors, license (when licensing)
   + version (when sharing and releasing)
   + homepage (when changing launchpad project: release and configure)
  - add an 'add' command. $ quickly dialog … is now $ quickly add dialog …
    (LP: #438320)
  - enable automatic release and milestone built in LP, releasing and pushing
    upstream tarball (LP: #470344)
  - automatic collect and publish changelog message from commits and save
    messages used during devlopment. (LP: #476572)
  - add i18n to boiler plate (LP: #423529)
  - enable adding manual depdencies to quickly project (LP: #474639)
  - enable configure its own bzr branch and resetting parent branch even once
    already configured (quickly configure bzr <branch-path>)
  - now recommends seahorse-plugins to have a graphical prompt for signing
    package
  - rename quickly glade to quickly design (LP: #528664)
  - create command is now more flexible and enable people to inherit from
    other template more easily
  - add translation domain to gtkbuilder and fix some items that shouldn't
    been translatable (Łukasz Jernaś)
  - add apport and launchpadintegration to new and existing project once
    bounded to LP (Philip Peitsch)
  - fix spelling mistake "connexion" (Łukasz Jernaś) (LP: #532667)
  - the ubuntu-application tutorial is now internationalized and use docbook
    format. Translators, it's yours! (Shane Fagan) (LP: #525168)
  - package/share/release are now more quiet and only print something on error
    warning as a summary as with unfound packages, and so on (LP: #482915)
  - new algorithm to select good email automatically. Try to get the preferred
    email and update the AUTHOR file with it.
  - test GPG key and create one automatically if none is available. The
    corresponding public key availabity in launchpad is also checked.
    (LP: #427730, #408993)
  - add devscripts as a dependency (bug #465833), will fix all the depends
    mess later
  - bump python-distutils-extra (>= 2.18bzr1)
  ubuntu-cli Template:
  - first release using import command feature (no command written into the
    template itself). This is a basic ubuntu CLI application
  ubuntu-pygame Template:
  - first release using import command feature. python-pygame added as a
    depends
* debian/control:
  - renamed and separate in multiple packages to get a -common used with
    Quickly widgets (LP: #519633)
  - suggests python-quickly-widgets

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
# -*- coding: utf-8 -*-
 
3
# Copyright 2009 Didier Roche
 
4
#
 
5
# This file is part of Quickly ubuntu-application template
 
6
#
 
7
#This program is free software: you can redistribute it and/or modify it 
 
8
#under the terms of the GNU General Public License version 3, as published 
 
9
#by the Free Software Foundation.
 
10
#
 
11
#This program is distributed in the hope that it will be useful, but 
 
12
#WITHOUT ANY WARRANTY; without even the implied warranties of 
 
13
#MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR 
 
14
#PURPOSE.  See the GNU General Public License for more details.
 
15
#
 
16
#You should have received a copy of the GNU General Public License along 
 
17
#with this program.  If not, see <http://www.gnu.org/licenses/>.
 
18
 
 
19
import datetime
 
20
import filecmp
 
21
import os
 
22
import re
 
23
import shutil
 
24
import sys
 
25
 
 
26
from quickly import configurationhandler, templatetools
 
27
from internal import quicklyutils
 
28
 
 
29
import gettext
 
30
from gettext import gettext as _
 
31
# set domain text
 
32
gettext.textdomain('quickly')
 
33
 
 
34
class LicenceError(Exception):
 
35
    def __init__(self, msg):
 
36
        self.msg = msg
 
37
    def __str__(self):
 
38
        return repr(self.msg)
 
39
 
 
40
BEGIN_LICENCE_TAG = '### BEGIN LICENSE'
 
41
END_LICENCE_TAG = '### END LICENSE'
 
42
 
 
43
 
 
44
def help():
 
45
    print _("""Usage:
 
46
$quickly license <Your_Licence>
 
47
 
 
48
Adds license to project files. Before using this command, you should:
 
49
 
 
50
1. Edit the file AUTHORS to include your authorship (this step is automatically done
 
51
   if you directly launch "$ quickly release" or "$ quickly share" before changing license)
 
52
   In this case, license is GPL-3 by default.
 
53
2. If you want to put your own quickly unsupported Licence, add a COPYING file containing
 
54
   your own licence.
 
55
3. Executes either $ quickly license or $ quickly license <License>
 
56
   where <License> can be either:
 
57
   - GPL-3 (default)
 
58
   - GPL-2
 
59
 
 
60
This will modify the Copyright file with the chosen licence (with GPL-3 by default).
 
61
Updating previous chosen Licence if needed.
 
62
If you previously removed the tags to add your own licence, it will leave it pristine.
 
63
If no name is attributed to the Copyright, it will try to retrieve it from Launchpad
 
64
(in quickly release or quickly share command only)
 
65
 
 
66
Finally, this will copy the Copyright at the head of every files.
 
67
 
 
68
Note that if you don't run quickly licence before calling quickly release or quickly
 
69
share, this one will execute it for you and guess the copyright holder from your
 
70
launchpad account if you didn't update it.
 
71
""")
 
72
 
 
73
def get_supported_licenses():
 
74
    """Get supported licenses"""
 
75
 
 
76
    available_licenses = []
 
77
    
 
78
    for license_file in os.listdir(os.path.dirname(__file__) + "/available_licenses"):
 
79
        result = re.split("header_(.*)", license_file)
 
80
        if len(result) == 3:
 
81
            available_licenses.append(result[1])
 
82
 
 
83
    return available_licenses
 
84
    
 
85
 
 
86
def copy_license_to_files(license_content):
 
87
    """Copy license header to every .py files"""
 
88
 
 
89
    # get the project name
 
90
    if not configurationhandler.project_config:
 
91
        configurationhandler.loadConfig()
 
92
    project_name = configurationhandler.project_config['project']
 
93
 
 
94
    # open each python file and main bin file
 
95
    for root, dirs, files in os.walk('./'):
 
96
        for name in files:
 
97
            if name.endswith('.py') or os.path.join(root, name) == "./bin/" + project_name:
 
98
                skip_until_end_found = False
 
99
                try:
 
100
                    target_file_name = os.path.join(root, name)
 
101
                    ftarget_file_name = file(target_file_name, 'r')
 
102
                    ftarget_file_name_out = file(ftarget_file_name.name + '.new', 'w')
 
103
                    for line in ftarget_file_name:
 
104
                        # seek if we have to add or Replace a License
 
105
                        if BEGIN_LICENCE_TAG in line:
 
106
                            ftarget_file_name_out.write(line) # write this line, otherwise will be skipped
 
107
                            skip_until_end_found = True
 
108
                            ftarget_file_name_out.write(license_content)
 
109
 
 
110
                        if END_LICENCE_TAG in line:
 
111
                            skip_until_end_found = False
 
112
 
 
113
                        if not skip_until_end_found:
 
114
                            ftarget_file_name_out.write(line)
 
115
 
 
116
                    ftarget_file_name.close()
 
117
                    ftarget_file_name_out.close()
 
118
 
 
119
                    if skip_until_end_found: # that means we didn't find the END_LICENCE_TAG, don't copy the file
 
120
                        print _("WARNING: %s was not found in the file %s. No licence replacement") % (END_LICENCE_TAG, ftarget_file_name.name)
 
121
                        os.remove(ftarget_file_name_out.name)
 
122
                    else:
 
123
                        templatetools.apply_file_rights(ftarget_file_name.name, ftarget_file_name_out.name)
 
124
                        os.rename(ftarget_file_name_out.name, ftarget_file_name.name)
 
125
 
 
126
                except (OSError, IOError), e:
 
127
                    msg = _("%s file was not found") % fcopyright_name
 
128
                    raise LicenceError(msg)
 
129
 
 
130
 
 
131
def licensing(license=None):
 
132
    """Add license or update it to the project files
 
133
 
 
134
    Default is GPL-3"""
 
135
 
 
136
 
 
137
    fauthors_name = "AUTHORS"
 
138
    flicense_name = "COPYING"
 
139
 
 
140
    if not configurationhandler.project_config:
 
141
        configurationhandler.loadConfig()
 
142
    project_name = configurationhandler.project_config['project']
 
143
    python_name = templatetools.python_name(project_name)
 
144
 
 
145
    # check if we have a license tag in setup.py otherwise, default to GPL-3
 
146
    if license is None:
 
147
        try:
 
148
            license = quicklyutils.get_setup_value('license')
 
149
        except quicklyutils.cant_deal_with_setup_value:
 
150
            pass
 
151
    if license is None or license == '':
 
152
        license = 'GPL-3'
 
153
 
 
154
    # get Copyright holders in AUTHORS file
 
155
    license_content = ""
 
156
    try:
 
157
        for line in file(fauthors_name, 'r'):
 
158
            if "<Your Name> <Your E-mail>" in line:
 
159
                # if we have an author in setup.py, grab it
 
160
                try:
 
161
                    author = quicklyutils.get_setup_value('author')
 
162
                    author_email = quicklyutils.get_setup_value('author_email')
 
163
                    line = "Copyright (C) %s %s <%s>\n" % (datetime.datetime.now().year, author, author_email)
 
164
                    # update AUTHORS file
 
165
                    fout = file('%s.new' % fauthors_name, 'w')
 
166
                    fout.write(line)
 
167
                    fout.flush()
 
168
                    fout.close()
 
169
                    os.rename(fout.name, fauthors_name)
 
170
                except quicklyutils.cant_deal_with_setup_value:
 
171
                    msg = _('Copyright is not attributed. ' \
 
172
                            'Edit the AUTHORS file to include your name for the copyright replacing ' \
 
173
                            '<Your Name> <Your E-mail>. Update it in setup.py or use quickly share/quickly release ' \
 
174
                            'to fill it automatically')
 
175
                    raise LicenceError(msg)
 
176
            license_content += "# %s" % line
 
177
    except (OSError, IOError), e:
 
178
        msg = _("%s file was not found") % fauthors_name
 
179
        raise LicenceError(msg)
 
180
 
 
181
    # add header to license_content
 
182
    # check that COPYING file is provided if using a personal license
 
183
    supported_licenses_list = get_supported_licenses()
 
184
    if license in supported_licenses_list:
 
185
        header_file_path = os.path.dirname(__file__) + "/available_licenses/header_" + license
 
186
    else:
 
187
        header_file_path = flicense_name
 
188
    try:
 
189
        for line in file(header_file_path, 'r'):
 
190
            license_content += "# %s" % line
 
191
    except (OSError, IOError), e:
 
192
        if header_file_path == flicense_name:
 
193
            msg = _("%s file was not found. It is compulsory for user defined license") % flicense_name
 
194
        else:
 
195
            msg = _("Header of %s license not found. Quickly installation corrupted?") % header_file_path
 
196
        raise LicenceError(msg)
 
197
 
 
198
 
 
199
    # update license in config.py, setup.py and refresh COPYING if needed
 
200
    try:
 
201
        config_file = '%s/%sconfig.py' % (python_name, python_name)
 
202
        for line in file(config_file, 'r'):
 
203
            fields = line.split(' = ') # Separate variable from value
 
204
            if fields[0] == '__license__' and fields[1].strip() != "'%s'" % license:
 
205
                fin = file(config_file, 'r')
 
206
                fout = file(fin.name + '.new', 'w')
 
207
                for line_input in fin:            
 
208
                    fields = line_input.split(' = ') # Separate variable from value
 
209
                    if fields[0] == '__license__':
 
210
                        line_input = "%s = '%s'\n" % (fields[0], license)
 
211
                    fout.write(line_input)
 
212
                fout.flush()
 
213
                fout.close()
 
214
                fin.close()
 
215
                os.rename(fout.name, fin.name)
 
216
                if license in supported_licenses_list:
 
217
                    src_license_file = "/usr/share/common-licenses/" + license
 
218
                    if os.path.isfile(src_license_file):
 
219
                        shutil.copy("/usr/share/common-licenses/" + license, flicense_name)
 
220
                break
 
221
        try:
 
222
            quicklyutils.set_setup_value('license', license)
 
223
        except quicklyutils.cant_deal_with_setup_value:
 
224
            msg = _("Can't update license in setup.py file\n")
 
225
            raise LicenceError(msg)
 
226
    except (OSError, IOError), e:
 
227
        msg = _("%s/%sconfig.py file not found.") % (python_name, python_name)
 
228
        raise LicenceError(msg)
 
229
 
 
230
    # update About dialog, if present:
 
231
    about_dialog_file_name = quicklyutils.get_about_file_name()
 
232
    if about_dialog_file_name:
 
233
        copyright_holders = ""
 
234
        authors_holders = ""
 
235
        # get copyright holders and authors
 
236
        for line in file(fauthors_name, 'r'):
 
237
            if "copyright" in line.lower() or "(c)" in line.lower(): 
 
238
                copyright_holders += line
 
239
                authors_holders += line
 
240
            else:
 
241
                authors_holders += line
 
242
 
 
243
        # update without last \n
 
244
        quicklyutils.change_xml_elem(about_dialog_file_name, "object/property",
 
245
                                     "name", "copyright", copyright_holders[:-1],
 
246
                                     {'translatable': 'yes'})
 
247
        quicklyutils.change_xml_elem(about_dialog_file_name, "object/property",
 
248
                                     "name", "authors", authors_holders[:-1],
 
249
                                     {})
 
250
        quicklyutils.change_xml_elem(about_dialog_file_name, "object/property",
 
251
                                     "name", "license", license_content,
 
252
                                     {'translatable': 'yes'})
 
253
    copy_license_to_files(license_content)
 
254
 
 
255
 
 
256
def shell_completion(argv):
 
257
    """Propose available license as the third parameter"""
 
258
    
 
259
    # if then license argument given, returns available licenses
 
260
    if len(argv) == 1:
 
261
        print " ".join(get_supported_licenses())
 
262
 
 
263
 
 
264
if __name__ == "__main__":
 
265
 
 
266
    templatetools.handle_additional_parameters(sys.argv, help, shell_completion)
 
267
    license = None
 
268
    if len(sys.argv) > 2:
 
269
        print _("This command only take one optional argument: License\nUsage is: quickly license <license>")
 
270
        sys.exit(4)
 
271
    if len(sys.argv) == 2:
 
272
        license = sys.argv[1]
 
273
    try:
 
274
        licensing(license)
 
275
    except LicenceError, error_message:
 
276
        print(error_message)
 
277
        sys.exit(1)
 
278