From d628f6db6a9316593ad8774dfcb058d5e9dc2085 Mon Sep 17 00:00:00 2001 From: Mohammad Ali Hosseini Date: Mon, 22 Jan 2018 16:47:36 +0330 Subject: [PATCH] Use setuptools instead of distutils --- .gitignore | 9 +- README.md | 66 +++++++++---- amir/__init__.py | 13 --- amir/amirconfig.py | 91 +++++++++--------- {data => amir/data}/amir_migrate/README | 0 {data => amir/data}/amir_migrate/__init__.py | 0 {data => amir/data}/amir_migrate/manage.py | 0 {data => amir/data}/amir_migrate/migrate.cfg | 0 .../amir_migrate/versions/001_Version_1.py | 0 .../amir_migrate/versions/002_Version_2.py | 0 .../data}/amir_migrate/versions/__init__.py | 0 {data => amir/data}/media/background.png | Bin {data => amir/data}/media/icon.png | Bin {data => amir/data}/media/icon/128.png | Bin {data => amir/data}/media/icon/16.png | Bin {data => amir/data}/media/icon/22.png | Bin {data => amir/data}/media/icon/32.png | Bin {data => amir/data}/media/icon/48.png | Bin {data => amir/data}/media/icon/64.png | Bin {data => amir/data}/media/logo.png | Bin {data => amir/data}/ui/PurchasingForm.glade | 0 {data => amir/data}/ui/SellingForm.glade | 0 .../data}/ui/automaticaccounting.glade | 0 {data => amir/data}/ui/bankaccounts.glade | 0 {data => amir/data}/ui/cheque.glade | 0 {data => amir/data}/ui/customers.glade | 0 {data => amir/data}/ui/document.glade | 0 {data => amir/data}/ui/mainwin.glade | 0 {data => amir/data}/ui/mainwin.glade.h | 0 {data => amir/data}/ui/notebook.glade | 0 {data => amir/data}/ui/notebook.glade.h | 0 {data => amir/data}/ui/report.glade | 0 {data => amir/data}/ui/setting.glade | 0 {data => amir/data}/ui/warehousing.glade | 0 data/locale/fa/LC_MESSAGES/amir.mo | Bin 42924 -> 0 bytes data/locale/fr/LC_MESSAGES/amir.mo | Bin 651 -> 0 bytes data/locale/he/LC_MESSAGES/amir.mo | Bin 7665 -> 0 bytes data/locale/tr/LC_MESSAGES/amir.mo | Bin 1241 -> 0 bytes setup.py | 83 +++++----------- 39 files changed, 123 insertions(+), 139 deletions(-) rename {data => amir/data}/amir_migrate/README (100%) rename {data => amir/data}/amir_migrate/__init__.py (100%) rename {data => amir/data}/amir_migrate/manage.py (100%) rename {data => amir/data}/amir_migrate/migrate.cfg (100%) rename {data => amir/data}/amir_migrate/versions/001_Version_1.py (100%) rename {data => amir/data}/amir_migrate/versions/002_Version_2.py (100%) rename {data => amir/data}/amir_migrate/versions/__init__.py (100%) rename {data => amir/data}/media/background.png (100%) rename {data => amir/data}/media/icon.png (100%) rename {data => amir/data}/media/icon/128.png (100%) rename {data => amir/data}/media/icon/16.png (100%) rename {data => amir/data}/media/icon/22.png (100%) rename {data => amir/data}/media/icon/32.png (100%) rename {data => amir/data}/media/icon/48.png (100%) rename {data => amir/data}/media/icon/64.png (100%) rename {data => amir/data}/media/logo.png (100%) rename {data => amir/data}/ui/PurchasingForm.glade (100%) rename {data => amir/data}/ui/SellingForm.glade (100%) rename {data => amir/data}/ui/automaticaccounting.glade (100%) rename {data => amir/data}/ui/bankaccounts.glade (100%) rename {data => amir/data}/ui/cheque.glade (100%) rename {data => amir/data}/ui/customers.glade (100%) rename {data => amir/data}/ui/document.glade (100%) rename {data => amir/data}/ui/mainwin.glade (100%) rename {data => amir/data}/ui/mainwin.glade.h (100%) rename {data => amir/data}/ui/notebook.glade (100%) rename {data => amir/data}/ui/notebook.glade.h (100%) rename {data => amir/data}/ui/report.glade (100%) rename {data => amir/data}/ui/setting.glade (100%) rename {data => amir/data}/ui/warehousing.glade (100%) delete mode 100644 data/locale/fa/LC_MESSAGES/amir.mo delete mode 100644 data/locale/fr/LC_MESSAGES/amir.mo delete mode 100644 data/locale/he/LC_MESSAGES/amir.mo delete mode 100644 data/locale/tr/LC_MESSAGES/amir.mo diff --git a/.gitignore b/.gitignore index cb999f5..50eee29 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,12 @@ *.pyc *.db *.sqlite +*.pot +*.egg-info +*.tar.gz data/amir.conf -build/ MANIFEST -*.pot +build/ dist/ -*.egg-info deb_dist/ -*.tar.gz +locale/ diff --git a/README.md b/README.md index 3838c7e..b74d0fd 100644 --- a/README.md +++ b/README.md @@ -1,43 +1,73 @@ -# Amir accounting software +# Amir Accounting Software -Amir accounting program is free (as in freedom) software, and you can change it or even give it to your friends. +Amir is an accounting software mostly focused on businesses based in Iran. -Version 0.1 of this program is now available for [Windows](https://launchpad.net/amir/0.1/0.1/+download/Amir-0.1-win32-setup.exe) and Linux operating systems. Program is writen with Python and if you are a programmer then you can run it on other platforms. - -Amir is released under the GPL v3 license. - -Our sites: -http://www.freeamir.com +![Screenshot](http://www.freeamir.com/images/thumb/c/cd/Win1.png/727px-Win1.png) -https://github.com/Jooyeshgar/amir +## Requirements -https://launchpad.net/amir/ +* python (2.7) +* pip +* setuptools +* python-glade2 -![Screenshot](http://www.freeamir.com/images/thumb/c/cd/Win1.png/727px-Win1.png) +to install other requirements simply run below commands: +```bash +pip install -r requirements.txt +sudo apt-get install python-glade2 +``` ## Installation +### From source + ```bash -pip install -r requirements.txt -python setup.py install +git clone https://github.com/Jooyeshgar/amir.git +cd amir +sudo python setup.py install ``` -## Installation Using .deb File +### Ubuntu + +Deb package for the latest version is available in [Launchpad](https://launchpad.net/amir/0.1/0.1/+download/amir_0.2_all.deb) + +### Windows -To install the latest version of the package you can [download](https://launchpad.net/amir/0.1/0.1/+download/amir_0.2_all.deb) it from Lanchpad and install it. +Windows installer for version 0.1 is now available for [Windows](https://launchpad.net/amir/0.1/0.1/+download/Amir-0.1-win32-setup.exe) ## Run +Run `amir` command in terminal. + ```bash amir ``` -## Generate Documentation +## Development + +To start development and contributing install with below commands: + +```bash +git clone https://github.com/Jooyeshgar/amir.git +cd amir +sudo python setup.py develop +``` + +## Documentation To generate documentations first install [doxygen](http://www.doxygen.org/) ```bash -cd doc +git clone https://github.com/Jooyeshgar/amir.git +cd amir/doc make all -``` \ No newline at end of file +``` + +## Author + +Amir is developed by [Jooyeshgar](https://www.jooyeshgar.com) + +## License + +Amir is licensed under the GNU Genral Public License Version 3.0 \ No newline at end of file diff --git a/amir/__init__.py b/amir/__init__.py index bb8c681..e69de29 100644 --- a/amir/__init__.py +++ b/amir/__init__.py @@ -1,13 +0,0 @@ -import os, logging -import pygtk -pygtk.require('2.0') -import gtk,gtk.glade -import gettext,locale -import gobject -import glib -from amir.amirconfig import AmirConfig -from amir.share import share - -config = AmirConfig() -share.config = config -gettext.install('amir', config.locale_path, unicode=1) \ No newline at end of file diff --git a/amir/amirconfig.py b/amir/amirconfig.py index d026180..55f7eaa 100644 --- a/amir/amirconfig.py +++ b/amir/amirconfig.py @@ -1,16 +1,16 @@ # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- ### BEGIN LICENSE # Copyright (C) 2010 -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 3, as published +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published # by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranties of -# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranties of +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR # PURPOSE. See the GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along +# +# You should have received a copy of the GNU General Public License along # with this program. If not, see . ### END LICENSE @@ -21,7 +21,7 @@ # where your project will head for your data (for instance, images and ui files) # by default, this is ../data, relative your trunk layout -__amir_data_directory__ = r'../../../../share/amir' +__amir_data_directory__ = r'data' __license__ = 'GPL-3' @@ -35,7 +35,7 @@ import platform import database - + ## \defgroup Utility ## @{ @@ -65,8 +65,8 @@ def format_option(self, option): for line in help_lines[1:]]) elif opts[-1] != "\n": result.append("\n") - return "".join(result) - + return "".join(result) + class AmirConfig: """Retrieve amir data path @@ -79,14 +79,14 @@ class AmirConfig: localelist = ["en_US", "fr", "he", "fa_IR", "tr"] langlist = ["English", "French", "Hebrew", "Persian", "Turkish"] directionlist = ["ltr", "ltr", "rtl", "rtl", "ltr"] - + datetypes = ["jalali", "gregorian"] datedelims = [":", "/", "-"] datefields = {"year":0, "month":1, "day":2} dateorders = [('year', 'month', 'day'), ('month', 'year', 'day'), ('day', 'year', 'month'), ('year', 'day', 'month'), ('day', 'month', 'year'), ('month', 'day', 'year')] - + def __init__(self): parser = optparse.OptionParser(version="%prog %ver",formatter=IndentedHelpFormatterWithNL() ) parser.add_option("-v", "--verbose", action="store_const", const=1, dest="verbose", help="Show debug messages") @@ -107,10 +107,8 @@ def __init__(self): if self.options.pathname == None: if platform.system() == 'Windows': pathname = os.path.join(os.path.dirname(sys.executable),"data") - elif __amir_data_directory__.startswith('..'): - pathname = os.path.join(os.path.dirname(__file__) , __amir_data_directory__) else: - pathname = __amir_data_directory__ + pathname = os.path.join(os.path.dirname(__file__) , __amir_data_directory__) logging.debug('Project data directory. "%s"' % pathname) else: pathname = self.options.pathname @@ -122,6 +120,7 @@ def __init__(self): self.locale_path = os.path.join(abs_data_path,"locale") else: self.locale_path = '/usr/share/locale' + else: logging.error('Project path not found. "%s"' % abs_data_path) @@ -134,22 +133,22 @@ def __init__(self): os.makedirs(confdir, 0755) confpath = os.path.join(confdir, 'amir.conf') - + dbfile = '' os.system.__subclasshook__ logging.debug('Reading configuration "%s"' % confpath) - + #A ConfigParser is defined with default configuration values - self.defaultConfig = {"current_database": "1", "repair_at_start": "no", "language": "C", "dateformat": "jalali", "delimiter": ":", + self.defaultConfig = {"current_database": "1", "repair_at_start": "no", "language": "C", "dateformat": "jalali", "delimiter": ":", "dateorder": "0", "use_latin_numbers": "yes", "name_font": "14", "header_font": "12", "content_font": "9", "footer_font": "8", "paper_ppd_name": "A4", "paper_display_name": "A4", - "paper_width_points": "595", "paper_height_points": "841", "paper_orientation": "0", + "paper_width_points": "595", "paper_height_points": "841", "paper_orientation": "0", "top_margin": "18", "bottom_margin": "18", "right_margin": "18", "left_margin": "18"} self.sconfig = ConfigParser.SafeConfigParser(self.defaultConfig) if not os.path.exists(confpath): open(confpath, 'w').close() - + self.sconfig.readfp(open(confpath,'r+')) if not self.sconfig.has_section('General'): self.sconfig.add_section('General') @@ -157,7 +156,7 @@ def __init__(self): self.sconfig.add_section('Report Fonts') if not self.sconfig.has_section('Paper Setup'): self.sconfig.add_section('Paper Setup') - + self.dblist = [] self.dbnames = [] @@ -177,13 +176,13 @@ def __init__(self): dbfile = self.options.database self.dblist.append(dbfile) self.dbnames.append(os.path.basename(dbfile)) - + if dbfile == '': dbfile = 'sqlite:///'+os.path.join(confdir, 'amir.sqlite') self.dblist.append(dbfile) self.dbnames.append('amir.sqlite') logging.error("No database path found. the default database %s will be opened for use." % dbfile) - + logging.info('database path: ' + dbfile) #try: self.db_repository = os.path.join(abs_data_path, 'amir_migrate') @@ -191,79 +190,79 @@ def __init__(self): share.session = self.db.session #except: # sys.exit("Cannot open database.") - + # str = self.configfile.returnStringValue("repair_at_start") str = self.sconfig.get('General', 'repair_at_start') if str.lower() == 'yes': self.repair_atstart = True else: self.repair_atstart = False - + # str = self.configfile.returnStringValue("dateformat") str = self.sconfig.get('General', 'language') if str in self.localelist: self.locale = str else: self.locale = "en_US" - + str = self.sconfig.get('General', 'dateformat') if str == '': self.datetype = 0 else: self.datetype = self.datetypes.index(str) - + # str = self.configfile.returnStringValue("delimiter") str = self.sconfig.get('General', 'delimiter') if str == '': self.datedelim = 0 else: self.datedelim = self.datedelims.index(str) - + # str = self.configfile.returnStringValue("dateorder") str = self.sconfig.get('General', 'dateorder') if str == '': self.dateorder = 0 else: self.dateorder = int(str) - + for i in range(0,3): field = self.dateorders[self.dateorder][i] self.datefields[field] = i - + # uselatin = self.configfile.returnStringValue("use_latin_numbers") uselatin = self.sconfig.get('General', 'use_latin_numbers') if uselatin.lower() == "no": - self.digittype = 1 # 0 for latin, 1 for persian + self.digittype = 1 # 0 for latin, 1 for persian else: self.digittype = 0 - + self.namefont = self.sconfig.getint('Report Fonts', "name_font") self.headerfont = self.sconfig.getint('Report Fonts', "header_font") self.contentfont = self.sconfig.getint('Report Fonts', "content_font") self.footerfont = self.sconfig.getint('Report Fonts', "footer_font") - + self.paper_ppd = self.sconfig.get('Paper Setup', 'paper_ppd_name') self.paper_name = self.sconfig.get('Paper Setup', 'paper_display_name') self.paper_width = self.sconfig.getfloat('Paper Setup', 'paper_width_points') self.paper_height = self.sconfig.getfloat('Paper Setup', 'paper_height_points') self.paper_orientation = self.sconfig.getint('Paper Setup', 'paper_orientation') - + self.topmargin = self.sconfig.getint('Paper Setup', 'top_margin') self.botmargin = self.sconfig.getint('Paper Setup', 'bottom_margin') self.rightmargin = self.sconfig.getint('Paper Setup', 'right_margin') self.leftmargin = self.sconfig.getint('Paper Setup', 'left_margin') - + def updateConfigFile(self): if self.digittype == 1: uselatin = "no" else: uselatin = "yes" - + if self.repair_atstart == True: repair = "yes" else: repair = "no" - + # keys = ['database', 'dateformat', 'delimiter', 'dateorder', 'use_latin_numbers', 'repair_at_start', # 'top_margin', 'bottom_margin', 'right_margin', 'left_margin', # 'name_font', 'header_font', 'content_font', 'footer_font'] @@ -276,28 +275,28 @@ def updateConfigFile(self): self.sconfig.set('General', 'current_database', str(self.currentdb)) self.sconfig.set('General', 'repair_at_start', repair) self.sconfig.set('General', 'language', self.locale) - + self.sconfig.set('General', 'dateformat', self.datetypes[self.datetype]) self.sconfig.set('General', 'delimiter', self.datedelims[self.datedelim]) self.sconfig.set('General', 'dateorder', str(self.dateorder)) self.sconfig.set('General', 'use_latin_numbers', uselatin) - + self.sconfig.set('Report Fonts', 'name_font', str(self.namefont)) self.sconfig.set('Report Fonts', 'header_font', str(self.headerfont)) self.sconfig.set('Report Fonts', 'content_font', str(self.contentfont)) self.sconfig.set('Report Fonts', 'footer_font', str(self.footerfont)) - + self.sconfig.set('Paper Setup', 'paper_ppd_name', str(self.paper_ppd)) self.sconfig.set('Paper Setup', 'paper_display_name', str(self.paper_name)) self.sconfig.set('Paper Setup', 'paper_width_points', str(self.paper_width)) self.sconfig.set('Paper Setup', 'paper_height_points', str(self.paper_height)) self.sconfig.set('Paper Setup', 'paper_orientation', str(self.paper_orientation)) - + self.sconfig.set('Paper Setup', 'top_margin', str(self.topmargin)) self.sconfig.set('Paper Setup', 'bottom_margin', str(self.botmargin)) self.sconfig.set('Paper Setup', 'right_margin', str(self.rightmargin)) self.sconfig.set('Paper Setup', 'left_margin', str(self.leftmargin)) - + if platform.system() == 'Windows': confdir = os.path.join(os.path.expanduser('~'), 'amir') else: @@ -305,7 +304,7 @@ def updateConfigFile(self): confpath = os.path.join(confdir, 'amir.conf') logging.debug('Writing configuration "%s"' % confpath) self.sconfig.write(open(confpath, 'wb')) -# self.configfile.update(keys, values) +# self.configfile.update(keys, values) def restoreDefaultFonts(self): self.namefont = int(self.defaultConfig["name_font"]) @@ -314,5 +313,3 @@ def restoreDefaultFonts(self): self.footerfont = int(self.defaultConfig["footer_font"]) ## @} - - diff --git a/data/amir_migrate/README b/amir/data/amir_migrate/README similarity index 100% rename from data/amir_migrate/README rename to amir/data/amir_migrate/README diff --git a/data/amir_migrate/__init__.py b/amir/data/amir_migrate/__init__.py similarity index 100% rename from data/amir_migrate/__init__.py rename to amir/data/amir_migrate/__init__.py diff --git a/data/amir_migrate/manage.py b/amir/data/amir_migrate/manage.py similarity index 100% rename from data/amir_migrate/manage.py rename to amir/data/amir_migrate/manage.py diff --git a/data/amir_migrate/migrate.cfg b/amir/data/amir_migrate/migrate.cfg similarity index 100% rename from data/amir_migrate/migrate.cfg rename to amir/data/amir_migrate/migrate.cfg diff --git a/data/amir_migrate/versions/001_Version_1.py b/amir/data/amir_migrate/versions/001_Version_1.py similarity index 100% rename from data/amir_migrate/versions/001_Version_1.py rename to amir/data/amir_migrate/versions/001_Version_1.py diff --git a/data/amir_migrate/versions/002_Version_2.py b/amir/data/amir_migrate/versions/002_Version_2.py similarity index 100% rename from data/amir_migrate/versions/002_Version_2.py rename to amir/data/amir_migrate/versions/002_Version_2.py diff --git a/data/amir_migrate/versions/__init__.py b/amir/data/amir_migrate/versions/__init__.py similarity index 100% rename from data/amir_migrate/versions/__init__.py rename to amir/data/amir_migrate/versions/__init__.py diff --git a/data/media/background.png b/amir/data/media/background.png similarity index 100% rename from data/media/background.png rename to amir/data/media/background.png diff --git a/data/media/icon.png b/amir/data/media/icon.png similarity index 100% rename from data/media/icon.png rename to amir/data/media/icon.png diff --git a/data/media/icon/128.png b/amir/data/media/icon/128.png similarity index 100% rename from data/media/icon/128.png rename to amir/data/media/icon/128.png diff --git a/data/media/icon/16.png b/amir/data/media/icon/16.png similarity index 100% rename from data/media/icon/16.png rename to amir/data/media/icon/16.png diff --git a/data/media/icon/22.png b/amir/data/media/icon/22.png similarity index 100% rename from data/media/icon/22.png rename to amir/data/media/icon/22.png diff --git a/data/media/icon/32.png b/amir/data/media/icon/32.png similarity index 100% rename from data/media/icon/32.png rename to amir/data/media/icon/32.png diff --git a/data/media/icon/48.png b/amir/data/media/icon/48.png similarity index 100% rename from data/media/icon/48.png rename to amir/data/media/icon/48.png diff --git a/data/media/icon/64.png b/amir/data/media/icon/64.png similarity index 100% rename from data/media/icon/64.png rename to amir/data/media/icon/64.png diff --git a/data/media/logo.png b/amir/data/media/logo.png similarity index 100% rename from data/media/logo.png rename to amir/data/media/logo.png diff --git a/data/ui/PurchasingForm.glade b/amir/data/ui/PurchasingForm.glade similarity index 100% rename from data/ui/PurchasingForm.glade rename to amir/data/ui/PurchasingForm.glade diff --git a/data/ui/SellingForm.glade b/amir/data/ui/SellingForm.glade similarity index 100% rename from data/ui/SellingForm.glade rename to amir/data/ui/SellingForm.glade diff --git a/data/ui/automaticaccounting.glade b/amir/data/ui/automaticaccounting.glade similarity index 100% rename from data/ui/automaticaccounting.glade rename to amir/data/ui/automaticaccounting.glade diff --git a/data/ui/bankaccounts.glade b/amir/data/ui/bankaccounts.glade similarity index 100% rename from data/ui/bankaccounts.glade rename to amir/data/ui/bankaccounts.glade diff --git a/data/ui/cheque.glade b/amir/data/ui/cheque.glade similarity index 100% rename from data/ui/cheque.glade rename to amir/data/ui/cheque.glade diff --git a/data/ui/customers.glade b/amir/data/ui/customers.glade similarity index 100% rename from data/ui/customers.glade rename to amir/data/ui/customers.glade diff --git a/data/ui/document.glade b/amir/data/ui/document.glade similarity index 100% rename from data/ui/document.glade rename to amir/data/ui/document.glade diff --git a/data/ui/mainwin.glade b/amir/data/ui/mainwin.glade similarity index 100% rename from data/ui/mainwin.glade rename to amir/data/ui/mainwin.glade diff --git a/data/ui/mainwin.glade.h b/amir/data/ui/mainwin.glade.h similarity index 100% rename from data/ui/mainwin.glade.h rename to amir/data/ui/mainwin.glade.h diff --git a/data/ui/notebook.glade b/amir/data/ui/notebook.glade similarity index 100% rename from data/ui/notebook.glade rename to amir/data/ui/notebook.glade diff --git a/data/ui/notebook.glade.h b/amir/data/ui/notebook.glade.h similarity index 100% rename from data/ui/notebook.glade.h rename to amir/data/ui/notebook.glade.h diff --git a/data/ui/report.glade b/amir/data/ui/report.glade similarity index 100% rename from data/ui/report.glade rename to amir/data/ui/report.glade diff --git a/data/ui/setting.glade b/amir/data/ui/setting.glade similarity index 100% rename from data/ui/setting.glade rename to amir/data/ui/setting.glade diff --git a/data/ui/warehousing.glade b/amir/data/ui/warehousing.glade similarity index 100% rename from data/ui/warehousing.glade rename to amir/data/ui/warehousing.glade diff --git a/data/locale/fa/LC_MESSAGES/amir.mo b/data/locale/fa/LC_MESSAGES/amir.mo deleted file mode 100644 index d000d2df514d407450e7b82809cbbe6ace3891e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42924 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 diff --git a/data/locale/fr/LC_MESSAGES/amir.mo b/data/locale/fr/LC_MESSAGES/amir.mo deleted file mode 100644 index ba144b65ddd1d016224cfd9e22832724ed3f6dbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 651 zcmYk3&2G~`5XTLa51A7j5r;j3stvm#w5cgkOzombHbjYwdfmhmcgtqiTCe-@2Jisf zxNzv9yaw;VvoPzRmXUs%UC)1ZKK$qD*7pGIKJpw%kcWsuynRI;Bj1n*h!<}mKafYr zPvq)O5d1>_44K~DKT;KIGCm5}-^S)K^nfO~gT9Ma*f&Udx~ zOH;ixrPNhKh70M!W15K;%hjT!=|#80n{9B)x+&RS)W>c3DUay~&|o(c-ei&&i&mk_!s{RON^}l diff --git a/data/locale/he/LC_MESSAGES/amir.mo b/data/locale/he/LC_MESSAGES/amir.mo deleted file mode 100644 index 8fa4b9229dd8586d3469ca3ba0e566a054b6e4cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7665 zcmcJSZHygN8OKLJperg?d`CI0ltSBk+3gFIwQt+)7K+`r>5BqJo7sD(yO-X*b2~G) z%NnD8@PjX3w(Tx;*=;E+*zSJN4-mi@iXSvF0TL1nSB)`|L=#Lj8jT@_5P$zOXXf7B zZV^nJ_T2x>nddy`dHFxjnf?9Jt0p|Iy^I?f<5zgzQSiF=^27D))t+}1_!Dq5coFF7bv}lK>m9J?zswn zkmphGqu_TyRC(t>?K=y~j%VHb7r+%fzXpB+yq3*B2`&fw!OfuLzXyH{JPS(i)1dr& z$-Vyrc!=kJf@{EgF>)0+0)7ab0olTP3RL_qf*Zi!f}aDg#~HIWKva2Ua4i^u zTfrGnad-{99()~?U;lRRm!L!(*aa>FC&4ShpMp1l&x5ytzXE07Ti`9=Z74C|KF|k` zf!n}Wz%lR!f~x(V02R-t9X=0A|1TZB=k2rlJlzl84Aw#II{}KP zKL)kmFF@&k8I=6*KI0Q;QcF*5%_+3zbOn~Cgtb6`B$bawG{GihN zD=58Jve`!P7SMo)!L{Hw!TsQqZvJXWr#P(yKLhRnrLW}XN5P{!KMWSZD?XmaqYKo! z2SBLdjeyGgx4>QCkHCAuH$d6dOK=qT`#@6Q`Cu;?gR1jqK*ixEoRfd6_>sST-~-_O z;4t_U*a2#lGK&a}y z07~y~K=JO64qtcp7ZBRnOZG};H3PG(z3aeD4Ed~hiIckSWURM$tsn6QGrZl5yBLal zb}3ey8OBZQ0XH&KOS))>*1sP6lyXn}-N9JHxQRjNZO^+JB;DQ>i~=LO6vsY>@}^7u zaGAYJf9?kEanHDId8ZQ8wU?|_D*X9kdeNJ4|wUn_$Hw7-Q$Ha|+2ZK^#Mk>jW zNro!1srkc!@vBkbmq$(TP$f=cQ>pPTFr`Km1+~OfgX2N9==GFJVWXB*YJ+A+SZWOO z%IhhYO)VHPQ8;4nEe=bp+ju?odUe$6i2^ekHrSe*BsArq8YJAY!N^cp4NTc7+d5Bl ztJmw-Of5`IX~?e)2D$0UXgz4X3u`s`gI*~t`-wl`$3f8?+8)e#8E# z)jNRSCO%fJU`@8rgppys6h={_o)q8ZK34q^RFuNn@gPe6r>$cDcq=AeuhX=*9z=dp z32UY|9Ih*Zr$G%Won0Csg9aGVG?W) z!=r7F1L}c#s%1qmIM(p1b_wC&e<~D4Ov!j4 zE=85PJZisZmx@1F3*$=6-H{^!1S|!z(vigMX$%hpsA<%zl@fO4ybzJSKDjCq_6^q) zo94i}kv?YZPer2$yDS?OFZa&tv(sTcsI^DYw6Yq@0TC_}lzb`+RxJ(I zCG)9xzh5IsW`8h9)u-(8_JnzH$2i@nl{J->XgZU2k5o7QbSyA4vigFE>dM!(^&4x_ z*2`&C6-SVVfKa&U9z_Xfxua!e8zA8Hs$$E~gc4|pw(L(V31V+=9>Dg1t7^A;`>Fwr z!}ScAo~6O2US_$XZtEw-g{x|0CKxtHqHx&uqbh-2qtyBI$;<;$sX}jYJC67~6utey zuwN19bVsHwiw^{B>QYR$8`x(nthO>Sb!ZZl(?)uv62*xLYeCV=mdvL>+d7JKkZzxl zpoGq9?VPt>O%pW&HOTbD@D8|>qt^yHe=NBsjn=fWm)B7KCBH!|Da9c_HgU)aQyQw! z7@V>gGo8A(TTjqAGJJ+rk&$U00kU9b`s{J$+K>(pwIa0w?KrGq!XpaZ@k-c;P2C?1 zJRKD+%4OA>o)zUVh-)j;bFugiB$LaC=4470UPcUqEmI97cUH@|{2a6A3-3xC0d$)I z+KDZIuuAnC$gSQK%fp`GN>nsEEiJOch;+DPQeDYOr%qk6gFScO*)BFJI+V4q{iJYN zHf_00&+xJgSXr_MQW&jVW41e{v@&h}%e8`PaMX^)-^4hkL9{XlR2bn=m+Jv(;n?>lf{OUJ&w2Me5Y_8chKGt;c??CLCZZYXr! zX}a#{UcYg5=lXS>2p0CkKxJ#8+&a^>zI(%l)ty`&yZtyRSZ}I6o^_l1{fIAsP4Q51 zRCn73=^51`bl8GyZLk5I3kL(Alm4DyAR^0~hJtO?N->NEw{-OH>hEiL*j4Q8;Nv3U zE3R;m>~)(YcqqBOUZo3tPTyQn93-0$9o$*i*pgFVIg<;0HTo^Rs@rTFs3aZt6?XfL zT4|{6mkWIlDZ(wcx(c0Lg|4-x^RDi-xG%TvE8HE_^f@D!@|EV+frffS*V?W-@3^fa z{bFsNYfdz0n`5SVqB+x?Hr$^v&4-)gra8sb1=Bp=oa7&qJT=ei#kgHG)jZAoT+w6l zF~%c?iCLs3cs<7NoQLED?;dZ?N$&*fS$(>Biih#VUU~>mA$NxF5!Rk=PN#BX+J2fn zPV@4-K|2b^Tl;FwbaP^>Owoo@%`@Cj%d2y;vH7T$&swutX_r5S; z7>p@0a`RNWVvfbqe5R=QOd#~c;_p-O6X+q5W2|7eT=Ex+6>FPkJQmmjwrfQ;-nuF0Zffl$Ock zF0R-;jGaP&B+3Ztv#pY5tn*Vc)Rn!owS`Ktu~yiXc?+`B(tOeyN3%F#S4r3gKCjhz zBJ>yJPfKL+Z00mypu26M!a37Cb$J1&d0x$0Cd##}2k^HCQCZkFWnJ1utrK>mH42#P zYlp3;&X&~5)Dpj1Ud9=u1Klb&Us(qYQwvXkdY1@WsmL%yoaSclkIy2pFuJfpGpBGt`&M^cg z*g)}X%Z>XSXj@K{CSkel7Bbx_JBc%P&OR%EXERN5iL*dPwC|(tG|3G8X|g%HAoh8C zuvynqH=`c5@ZeO&+rK89s0vut;Fb(`Y!t%xlr5js6)c+{7Oaydb$=XYC$;4;y*?UV)X0O9P@z5T#aY-ZSv;?S*)m&zcg z_~L{WrCi~uTe;5}_l3w#?`C;>IkHs5%i1JiZre$HJ>84>bT5c)mt<9I`|3GchL+my ze6cdQO>N&jszF!cCn3{g+Ja2mv~p{CH-@h;jW0a$kHg-IDBQA*H?oR$A)-#xmZioT z?mloYyLleBORR85du~Tw74rn58F~#$<59C?tuJ3zj3gq7kncQ>3To}E3- z&SKvwQj~%&P(jL+P^1Y((x$MB6shbLYV$paALoWsuG- z1TF`E6MPT;RJ>16qIU1i+eQzZwUQE%1z&!g!-XgPm%%oh!z21)#1>L zSk);$%1d69PA#xSmv0q{EjiWKo-KK2rfRGvz3fW3@iJNXa_%ze_Z%s!DWk9vd@HuE zw%Ki`?rF6JYU^36?0%ClA$I()5 zy|TzW8lpt6w*8kwBelK4dmGXf%74AqUKX?aaa6%wvFvN%o#b7)=2kia`5LgZ)14u?labwPH#+BzNmMe>P%0p zl(n>B6Bpb44fC^Eu$`Zg-YCq;x*YeBo88E5xwr5tY}Todux*rMoptHp$uL3^{nGu) I>rLg^|GTvi5&!@I diff --git a/setup.py b/setup.py index 6bc971c..4e8fb71 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- import os -from distutils.core import setup, Extension +import setuptools def removeall(path): if not os.path.isdir(path): @@ -27,70 +27,39 @@ def rmgeneric(path, __func__): pass # Create mo files: -if not os.path.exists("mo/"): - os.mkdir("mo/") +if not os.path.exists("locale/"): + os.mkdir("locale/") for lang in ('fa', 'fr', 'he', 'tr'): pofile = "po/" + lang + ".po" - mofile = "mo/" + lang + "/amir.mo" - if not os.path.exists("mo/" + lang + "/"): - os.mkdir("mo/" + lang + "/") - print "generating", mofile - os.system("msgfmt %s -o %s" % (pofile, mofile)) + locale = "locale/" + lang + "/amir.mo" + if not os.path.exists("locale/" + lang + "/"): + os.mkdir("locale/" + lang + "/") + print "generating", locale + os.system("msgfmt %s -o %s" % (pofile, locale)) - -setup( - name='amir', - version='18.01', - description='Amir accounting software', - author='Jooyeshgar', - author_email='info@jooyeshgar.com', - maintainer= 'Jooyeshgar', - url='https://launchpad.net/amir', - install_requires=['migrate', 'tempita', 'sqlalchemy'], - py_modules = ['amir'], - classifiers=[ +setuptools.setup( + name = 'amir', + version = '0.2.0', + description = 'Amir accounting software', + author = 'Jooyeshgar', + author_email = 'info@jooyeshgar.com', + maintainer = 'Jooyeshgar', + url = 'https://github.com/jooyeshgar/amir', + install_requires=['sqlalchemy-migrate>=0.9.0', 'sqlalchemy>=1.0.0'], + classifiers = [ 'Intended Audience :: End Users/Desktop', 'License :: GNU General Public License v3.0 (GPL-3)', 'Programming Language :: Python', ], - packages = ['amir', 'amir/database'], - keywords='amir accounting', + packages = setuptools.find_packages(), + package_data = {'amir': ['data/ui/*.glade', 'data/ui/*.glade.h', 'data/media/*.png', 'data/media/icon/*.png', 'data/amir_migrate/*', 'data/amir_migrate/versions/*']}, + keywords = 'amir accounting', scripts = ['scripts/amir'], - data_files=[ - ('share/locale/fa/LC_MESSAGES', ['data/locale/fa/LC_MESSAGES/amir.mo']), - ('share/locale/fr/LC_MESSAGES', ['data/locale/fr/LC_MESSAGES/amir.mo']), - ('share/locale/he/LC_MESSAGES', ['data/locale/he/LC_MESSAGES/amir.mo']), - ('share/locale/tr/LC_MESSAGES', ['data/locale/tr/LC_MESSAGES/amir.mo']), - ('share/amir/media/icon', ['data/media/icon/16.png']), - ('share/amir/media/icon', ['data/media/icon/22.png']), - ('share/amir/media/icon', ['data/media/icon/32.png']), - ('share/amir/media/icon', ['data/media/icon/48.png']), - ('share/amir/media/icon', ['data/media/icon/64.png']), - ('share/amir/media/icon', ['data/media/icon/128.png']), - ('share/amir/ui', ['data/ui/SellingForm.glade']), - ('share/amir/ui', ['data/ui/PurchasingForm.glade']), - ('share/amir/ui', ['data/ui/cheque.glade']), - ('share/amir/ui', ['data/ui/mainwin.glade']), - ('share/amir/ui', ['data/ui/setting.glade']), - ('share/amir/ui', ['data/ui/document.glade']), - ('share/amir/ui', ['data/ui/customers.glade']), - ('share/amir/ui', ['data/ui/bankaccounts.glade']), - ('share/amir/ui', ['data/ui/notebook.glade.h']), - ('share/amir/ui', ['data/ui/automaticaccounting.glade']), - ('share/amir/ui', ['data/ui/mainwin.glade.h']), - ('share/amir/ui', ['data/ui/warehousing.glade']), - ('share/amir/ui', ['data/ui/notebook.glade']), - ('share/amir/ui', ['data/ui/report.glade']), - ('share/amir/amir_migrate/versions', ['data/amir_migrate/versions/001_Version_1.py']), - ('share/amir/amir_migrate/versions', ['data/amir_migrate/versions/002_Version_2.py']), - ('share/amir/amir_migrate/versions', ['data/amir_migrate/versions/__init__.py']), - ('share/amir/media', ['data/media/logo.png']), - ('share/amir/media', ['data/media/background.png']), - ('share/amir/media', ['data/media/icon.png']), - ('share/amir/amir_migrate', ['data/amir_migrate/__init__.py']), - ('share/amir/amir_migrate', ['data/amir_migrate/migrate.cfg']), - ('share/amir/amir_migrate', ['data/amir_migrate/README']), - ('share/amir/amir_migrate', ['data/amir_migrate/manage.py'])] + data_files = [ + ('/usr/share/locale/fa/LC_MESSAGES', ['locale/fa/amir.mo']), + ('/usr/share/locale/fr/LC_MESSAGES', ['locale/fr/amir.mo']), + ('/usr/share/locale/he/LC_MESSAGES', ['locale/he/amir.mo']), + ('/usr/share/locale/tr/LC_MESSAGES', ['locale/tr/amir.mo'])] )