From 27abe190b8b6e2796237434f21bb953655f1c1ae Mon Sep 17 00:00:00 2001 From: Mike GRIFFIN Date: Thu, 14 Jan 2021 20:58:46 +1030 Subject: [PATCH 01/12] Update links from google to readthedocs --- bots/admin.py | 4 ++-- bots/models.py | 6 +++--- bots/templates/bots/menu.html | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bots/admin.py b/bots/admin.py index 3c0569b..b7e7543 100644 --- a/bots/admin.py +++ b/bots/admin.py @@ -34,7 +34,7 @@ class CcodeAdmin(BotsAdmin): search_fields = ('ccodeid__ccodeid','leftcode','rightcode','attr1','attr2','attr3','attr4','attr5','attr6','attr7','attr8') fieldsets = ( (None, {'fields': ('ccodeid','leftcode','rightcode','attr1','attr2','attr3','attr4','attr5','attr6','attr7','attr8'), - 'description': 'For description of user code lists and usage in mapping: see wiki.', + 'description': 'For description of user code lists and usage in mapping: see documentation.', 'classes': ('wide extrapretty',) }), ) @@ -74,7 +74,7 @@ class ChannelAdmin(BotsAdmin): 'classes': ('collapse wide extrapretty',) }), ('Safe writing & file locking',{'fields': ('mdnchannel','syslock', 'lockname'), - 'description': 'For more info see wiki
', + 'description': 'For more info see documentation
', 'classes': ('collapse wide extrapretty',) }), ('Other',{'fields': ('testpath','keyfile','certfile','rsrv2','rsrv1','parameters'), diff --git a/bots/models.py b/bots/models.py index 8ababf6..eb8ef81 100644 --- a/bots/models.py +++ b/bots/models.py @@ -256,7 +256,7 @@ class channel(models.Model): apop = models.BooleanField(default=False,verbose_name='No check to-address',help_text='Do not check if incoming "to" email addresses is known.') #20110104: used as 'no check on "to:" email address' remove = models.BooleanField(default=False,help_text='Delete incoming edi files after reading.
Use in production else files are read again and again.') path = StripCharField(max_length=256,blank=True) #different from host - in ftp both host and path are used - filename = StripCharField(max_length=70,blank=True,help_text='Incoming: use wild-cards eg: "*.edi".
Outgoing: many options, see wiki.
Advised: use "*" in filename (is replaced by unique counter per channel).
eg "D_*.edi" gives D_1.edi, D_2.edi, etc.') + filename = StripCharField(max_length=70,blank=True,help_text='Incoming: use wild-cards eg: "*.edi".
Outgoing: many options, see documentation.
Advised: use "*" in filename (is replaced by unique counter per channel).
eg "D_*.edi" gives D_1.edi, D_2.edi, etc.') lockname = StripCharField(max_length=35,blank=True,verbose_name='Lock-file',help_text='Directory locking: if lock-file exists in directory, directory is locked for reading/writing.') syslock = models.BooleanField(default=False,verbose_name='System locks',help_text='Use system file locks for reading or writing edi files (windows, *nix).') parameters = StripCharField(max_length=70,blank=True,help_text='For use in user communication scripting.') @@ -266,14 +266,14 @@ class channel(models.Model): askmdn = StripCharField(max_length=17,blank=True,choices=ENCODE_MIME,verbose_name='mime encoding') #20100703: used to indicate mime-encoding sendmdn = StripCharField(max_length=17,blank=True,choices=EDI_AS_ATTACHMENT,verbose_name='as body or attachment') #20120922: for email/mime: edi file as attachment or in body mdnchannel = StripCharField(max_length=35,blank=True,verbose_name='Tmp-part file name',help_text='Write file than rename. Bots renames to filename without this tmp-part.
Eg first write "myfile.edi.tmp", tmp-part is ".tmp", rename to "myfile.edi".') #20140113:use as tmp part of file name - archivepath = StripCharField(max_length=256,blank=True,verbose_name='Archive path',help_text='Write edi files to an archive.
See wiki. Eg: "C:/edi/archive/mychannel".') #added 20091028 + archivepath = StripCharField(max_length=256,blank=True,verbose_name='Archive path',help_text='Write edi files to an archive.
See documentation. Eg: "C:/edi/archive/mychannel".') #added 20091028 desc = models.TextField(max_length=256,null=True,blank=True,verbose_name='Description') rsrv1 = TextAsInteger(max_length=35,blank=True,null=True,verbose_name='Max failures',help_text='Max number of connection failures of incommunication before this is reported as a processerror (default: direct report).') #added 20100501 #20140315: used as max_com rsrv2 = models.IntegerField(null=True,blank=True,verbose_name='Max seconds',help_text='Max seconds for in-communication channel to run. Purpose: limit incoming edi files; for large volumes it is better read more often than all files in one time.') #added 20100501. 20110906: max communication time. rsrv3 = models.IntegerField(null=True,blank=True,verbose_name='Max days archive',help_text='Max number of days files are kept in archive.
Overrules global setting in bots.ini.') #added 20121030. #20131231: use as maxdaysarchive keyfile = StripCharField(max_length=256,blank=True,null=True,verbose_name='Private key file',help_text='Path to file that contains PEM formatted private key.') #added 20121201 certfile = StripCharField(max_length=256,blank=True,null=True,verbose_name='Certificate chain file',help_text='Path to file that contains PEM formatted certificate chain.') #added 20121201 - testpath = StripCharField(max_length=256,blank=True,verbose_name='Acceptance test path',help_text='Path used during acceptance tests, see wiki.') #added 20120111 + testpath = StripCharField(max_length=256,blank=True,verbose_name='Acceptance test path',help_text='Path used during acceptance tests, see documentation.') #added 20120111 def communicationscript(self): return script_link2(os.path.join(botsglobal.ini.get('directories','usersysabs'),'communicationscripts', self.idchannel + '.py')) diff --git a/bots/templates/bots/menu.html b/bots/templates/bots/menu.html index a2b4648..1e878e9 100644 --- a/bots/templates/bots/menu.html +++ b/bots/templates/bots/menu.html @@ -4,7 +4,7 @@ From 9602f7c043719d2ea05e5f98e4f09b8e1b0938d1 Mon Sep 17 00:00:00 2001 From: Mike GRIFFIN Date: Thu, 14 Jan 2021 22:32:54 +1030 Subject: [PATCH 02/12] Various bugfixes --- bots/cleanup.py | 6 +++--- bots/communication.py | 20 ++++++++++++++------ bots/models.py | 1 + bots/pluglib.py | 2 +- bots/transform.py | 3 ++- 5 files changed, 21 insertions(+), 11 deletions(-) diff --git a/bots/cleanup.py b/bots/cleanup.py index 976bb9c..a1e5499 100644 --- a/bots/cleanup.py +++ b/bots/cleanup.py @@ -16,10 +16,10 @@ def cleanup(do_cleanup_parameter,userscript,scriptname): most cleanup functions are by default done only once a day. ''' whencleanup = botsglobal.ini.get('settings','whencleanup','daily') - if botsglobal.ini.getboolean('acceptance','runacceptancetest',False): #no cleanup during acceptance testing - do_full_cleanup = False - elif do_cleanup_parameter: #if explicit indicated via commandline parameter + if do_cleanup_parameter: #if explicit indicated via commandline parameter do_full_cleanup = True + elif botsglobal.ini.getboolean('acceptance','runacceptancetest',False): # no automatic cleanup during acceptance testing + return elif whencleanup in ['always','daily']: #perform full cleanup only first run of the day. cur_day = int(time.strftime('%Y%m%d')) #get current date, convert to int diff --git a/bots/communication.py b/bots/communication.py index 01cf7d0..a5cd063 100644 --- a/bots/communication.py +++ b/bots/communication.py @@ -111,7 +111,14 @@ def run(self): if self.command == 'new': #only in-communicate for new run #~ print('in communication run 1') #handle maxsecondsperchannel: use global value from bots.ini unless specified in channel. (In database this is field 'rsrv2'.) - self.maxsecondsperchannel = self.channeldict['rsrv2'] if self.channeldict['rsrv2'] is not None and self.channeldict['rsrv2'] > 0 else botsglobal.ini.getint('settings','maxsecondsperchannel',sys.maxsize) + # MJG Python 3 deprecation warning fix + self.maxsecondsperchannel = botsglobal.ini.getint('settings','maxsecondsperchannel',sys.maxint) + try: + secs = int(self.channeldict['rsrv2']) + if secs > 0: + self.maxsecondsperchannel = secs + except: + pass #bots tries to connect several times. this is probably a better stategy than having long time-outs. max_nr_connect_tries = botsglobal.ini.getint('settings','maxconnectiontries',3) #how often does bots try to connect. TODO later version: setting per channel nr_connect_tries = 0 @@ -131,11 +138,12 @@ def run(self): #max_nr_retry : from channel. should be integer, but only textfields where left. so might be ''/None->use 0 max_nr_retry = int(self.channeldict['rsrv1']) if self.channeldict['rsrv1'] else 0 if max_nr_retry: - domain = 'bots_communication_failure_' + self.channeldict['idchannel'] + domain = (self.channeldict['idchannel'] + u'_failure')[:35] nr_retry = botslib.unique(domain) #update nr_retry in database if nr_retry >= max_nr_retry: botslib.unique(domain,updatewith=0) #reset nr_retry to zero else: + botsglobal.logger.info(u'Communication failure %s on channel %s',nr_retry,self.channeldict['idchannel']) return #max_nr_retry is not reached. return without error raise finally: @@ -145,7 +153,7 @@ def run(self): # ~ #max_nr_retry : get this from channel. should be integer, but only textfields where left. so might be ''/None->use 0 # ~ max_nr_retry = int(self.channeldict['rsrv1']) if self.channeldict['rsrv1'] else 0 # ~ if max_nr_retry: - # ~ domain = 'bots_communication_failure_' + self.channeldict['idchannel'] + # ~ domain = (self.channeldict['idchannel'] + u'_failure')[:35] # ~ botslib.unique(domain,updatewith=0) #set nr_retry to zero self.incommunicate() self.disconnect() @@ -267,8 +275,8 @@ def file2mime(self): confirmtype = '' confirmasked = False charset = row['charset'] - - if row['editype'] == 'email-confirmation': #outgoing MDN: message is already assembled + # MJG 15/01/2019 BUGFIX for automaticretrycommunication + if row['editype'] == 'email-confirmation' or self.command == 'automaticretrycommunication': # message is already assembled outfilename = row['filename'] else: #assemble message: headers and payload. Bots uses simple MIME-envelope; by default payload is an attachment message = email.message.Message() @@ -413,7 +421,7 @@ def savemime(msg): outfile.close() nrmimesaved += 1 ta_file.update(statust=OK, - contenttype=contenttype, + contenttype=contenttype[:35], # MJG 24/08/2016 truncate to fit in db filename=outfilename, filesize=filesize, divtext=attachment_filename) diff --git a/bots/models.py b/bots/models.py index 8ababf6..24e92b2 100644 --- a/bots/models.py +++ b/bots/models.py @@ -166,6 +166,7 @@ def script_link1(script,linktext): ''' if script exists return a plain text name as link; else return "no" icon, plain text name used in translate (all scripts should exist, missing script is an error). ''' + script = script.replace('.',os.sep,script.count('.')-1) # allow mapping script subdirs if os.path.exists(script): return '%s'%(urllib_quote(script.encode("utf-8")),linktext) else: diff --git a/bots/pluglib.py b/bots/pluglib.py index 0bb428c..3d8bdc3 100644 --- a/bots/pluglib.py +++ b/bots/pluglib.py @@ -378,7 +378,7 @@ def plugout_files(cleaned_data): if cleaned_data['fileconfiguration']: #gather from usersys files2return.extend(plugout_files_bydir(usersys,'usersys')) if not cleaned_data['charset']: #if edifact charsets are not needed: remove them (are included in default bots installation). - charsetdirs = plugout_files_bydir(os.path.join(usersys,'charsets'),'usersys/charsets') + charsetdirs = plugout_files_bydir(os.path.join(usersys,'charsets'),os.path.join('usersys','charsets')) for charset in charsetdirs: try: index = files2return.index(charset) diff --git a/bots/transform.py b/bots/transform.py index f7c2dec..06b13af 100644 --- a/bots/transform.py +++ b/bots/transform.py @@ -190,7 +190,8 @@ def _translate_one_file(row,routedict,endstatus,userscript,scriptname): if inn_splitup.ta_info.get('KillWholeFile',False): raise botslib.KillWholeFileException(msg) txt = botslib.txtexc() - ta_splitup.update(statust=ERROR,errortext=txt,**inn_splitup.ta_info) #update db. inn_splitup.ta_info could be changed by mappingscript. Is this useful? + inn_splitup.ta_info['errortext'] = txt + ta_splitup.update(statust=ERROR,**inn_splitup.ta_info) #update db. inn_splitup.ta_info could be changed by mappingscript. Is this useful? ta_splitup.deletechildren() else: ta_splitup.update(statust=DONE, **inn_splitup.ta_info) #update db. inn_splitup.ta_info could be changed by mappingscript. Is this useful? From c5697313972ad54d58d7aa051d7f146776c476bf Mon Sep 17 00:00:00 2001 From: Mike GRIFFIN Date: Fri, 15 Jan 2021 00:07:21 +1030 Subject: [PATCH 03/12] Django update to 1.11 --- bots/admin.py | 74 ++++++++++++++++++------------- bots/install/settings.py | 43 +++++++++--------- bots/models.py | 14 +++--- bots/pluglib.py | 3 +- bots/templates/admin/base.html | 50 ++++++++++++--------- bots/templates/bots/confirm.html | 2 +- bots/templates/bots/document.html | 2 +- bots/templates/bots/incoming.html | 2 +- bots/templates/bots/outgoing.html | 2 +- bots/templates/bots/process.html | 2 +- bots/templates/bots/reports.html | 8 ++-- 11 files changed, 113 insertions(+), 89 deletions(-) diff --git a/bots/admin.py b/bots/admin.py index 3c0569b..42b0143 100644 --- a/bots/admin.py +++ b/bots/admin.py @@ -1,9 +1,9 @@ ''' Bots configuration for django's admin site.''' from django import forms -try: - from django.forms import util as django_forms_util +try: # new first to avoid django 1.8 deprecation warning + from django.forms import utils as django_forms_util except: - from django.forms import utils as django_forms_util #django1.7 + from django.forms import util as django_forms_util from django.contrib import admin from django.contrib.auth.admin import UserAdmin from django.contrib.auth.models import User @@ -34,14 +34,21 @@ class CcodeAdmin(BotsAdmin): search_fields = ('ccodeid__ccodeid','leftcode','rightcode','attr1','attr2','attr3','attr4','attr5','attr6','attr7','attr8') fieldsets = ( (None, {'fields': ('ccodeid','leftcode','rightcode','attr1','attr2','attr3','attr4','attr5','attr6','attr7','attr8'), - 'description': 'For description of user code lists and usage in mapping: see wiki.', - 'classes': ('wide extrapretty',) + 'description': 'For description of user code lists and usage in mapping: see documentation.', + 'classes': ('',) }), ) def lookup_allowed(self, lookup, *args, **kwargs): if lookup.startswith('ccodeid'): return True return super(CcodeAdmin, self).lookup_allowed(lookup, *args, **kwargs) + def get_form(self, request, obj=None, **kwargs): + # over-ride form text field widths to better fit their actual size + form = super(CcodeAdmin, self).get_form(request, obj, **kwargs) + for field in form.base_fields: + if form.base_fields[field].widget.attrs.get('class') == 'vTextField': + form.base_fields[field].widget.attrs['style'] = 'width: %dch;' %min(70,int(form.base_fields[field].widget.attrs['maxlength'])) + return form admin.site.register(models.ccode,CcodeAdmin) class CcodetriggerAdmin(BotsAdmin): @@ -52,7 +59,7 @@ class CcodetriggerAdmin(BotsAdmin): admin.site.register(models.ccodetrigger,CcodetriggerAdmin) class ChannelAdmin(BotsAdmin): - list_display = ('idchannel', 'inorout', 'type', 'communicationscript', 'remove', 'host', 'port', 'username', 'secret', 'path', 'filename','mdnchannel','testpath','archivepath','rsrv3','rsrv2','rsrv1','syslock','parameters','starttls','apop','askmdn','sendmdn','ftpactive', 'ftpbinary') + list_display = ('idchannel', 'inorout', 'type', 'communicationscript', 'remove', 'host', 'port', 'username', 'path', 'filename','mdnchannel','testpath','archivepath','rsrv3','rsrv2','rsrv1','syslock','parameters','starttls','apop','askmdn','sendmdn','ftpactive', 'ftpbinary') list_filter = ('inorout','type') ordering = ('idchannel',) readonly_fields = ('communicationscript',) @@ -65,22 +72,29 @@ class ChannelAdmin(BotsAdmin): ('path','filename'), ('archivepath','rsrv3'), 'desc'), - 'classes': ('wide extrapretty',) + 'classes': ('',) }), ('Email specific',{'fields': ('starttls', 'apop', 'askmdn', 'sendmdn' ), - 'classes': ('collapse wide extrapretty',) + 'classes': ('collapse',) }), ('FTP specific',{'fields': ('ftpactive', 'ftpbinary', 'ftpaccount' ), - 'classes': ('collapse wide extrapretty',) + 'classes': ('collapse',) }), ('Safe writing & file locking',{'fields': ('mdnchannel','syslock', 'lockname'), - 'description': 'For more info see wiki
', - 'classes': ('collapse wide extrapretty',) + 'description': 'For more info see documentation
', + 'classes': ('collapse',) }), ('Other',{'fields': ('testpath','keyfile','certfile','rsrv2','rsrv1','parameters'), - 'classes': ('collapse wide extrapretty',) + 'classes': ('collapse',) }), ) + def get_form(self, request, obj=None, **kwargs): + # over-ride form text field widths to better fit their actual size + form = super(ChannelAdmin, self).get_form(request, obj, **kwargs) + for field in form.base_fields: + if form.base_fields[field].widget.attrs.get('class') == 'vTextField': + form.base_fields[field].widget.attrs['style'] = 'width: %dch;' %min(70,int(form.base_fields[field].widget.attrs['maxlength'])) + return form admin.site.register(models.channel,ChannelAdmin) class MyConfirmruleAdminForm(forms.ModelForm): @@ -118,7 +132,7 @@ class ConfirmruleAdmin(BotsAdmin): ordering = ('confirmtype','ruletype') fieldsets = ( (None, {'fields': ('active','negativerule','confirmtype','ruletype','frompartner', 'topartner','idroute','idchannel','messagetype'), - 'classes': ('wide extrapretty',) + 'classes': ('',) }), ) def formfield_for_dbfield(self,db_field,**kwargs): @@ -141,22 +155,22 @@ class PartnerAdmin(BotsAdmin): list_display_links = ('idpartner',) list_filter = ('active',) ordering = ('idpartner',) - search_fields = ('idpartner','name','mail','cc','address1','city','countrysubdivision','countrycode','postalcode','attr1','attr2','attr3','attr4','attr5','name1','name2','name3') + search_fields = ('idpartner','name','address1','city','countrysubdivision','countrycode','postalcode','mail','cc','attr1','attr2','attr3','attr4','attr5','name1','name2','name3','desc') fieldsets = ( (None, {'fields': ('active', ('idpartner', 'name'), ('mail','cc'),'desc',('startdate', 'enddate')), - 'classes': ('wide extrapretty',) + 'classes': ('',) }), ('Address',{'fields': ('name1','name2','name3','address1','address2','address3',('postalcode','city'),('countrycode','countrysubdivision'),('phone1','phone2')), - 'classes': ('collapse wide extrapretty',) + 'classes': ('collapse',) }), ('Is in groups',{'fields': ('group',), - 'classes': ('collapse wide extrapretty',) + 'classes': ('collapse',) }), ('User defined',{'fields': ('attr1','attr2','attr3','attr4','attr5'), - 'classes': ('wide extrapretty',) + 'classes': ('collapse',) }), ) - def queryset(self, request): + def get_queryset(self, request): return self.model.objects.filter(isgroup=False) admin.site.register(models.partner,PartnerAdmin) @@ -177,10 +191,10 @@ class PartnerGroepAdmin(BotsAdmin): search_fields = ('idpartner','name','desc') fieldsets = ( (None, {'fields': ('active', 'idpartner', 'name','desc',('startdate', 'enddate')), - 'classes': ('wide extrapretty',) + 'classes': ('',) }), ) - def queryset(self, request): + def get_queryset(self, request): return self.model.objects.filter(isgroup=True) admin.site.register(models.partnergroep,PartnerGroepAdmin) @@ -198,21 +212,21 @@ def clean(self): class RoutesAdmin(BotsAdmin): actions = ('activate',) form = MyRouteAdminForm - list_display = ('active','idroute','seq','routescript','fromchannel','fromeditype','frommessagetype','alt','frompartner','topartner','translt','tochannel','defer','toeditype','tomessagetype','frompartner_tochannel','topartner_tochannel','indefaultrun','testindicator','zip_incoming','zip_outgoing',) + list_display = ('active','indefaultrun','idroute','seq','routescript','fromchannel','fromeditype','frommessagetype','translt','alt','frompartner','topartner','tochannel','defer','toeditype','tomessagetype','frompartner_tochannel','topartner_tochannel','testindicator','zip_incoming','zip_outgoing',) list_display_links = ('idroute',) list_filter = ('active','notindefaultrun','idroute','fromeditype') ordering = ('idroute','seq') readonly_fields = ('routescript',) search_fields = ('idroute', 'fromchannel__idchannel','fromeditype', 'frommessagetype', 'alt', 'tochannel__idchannel','toeditype', 'tomessagetype', 'desc') fieldsets = ( - (None, {'fields': (('active','notindefaultrun'),'routescript',('idroute', 'seq',),'fromchannel', ('fromeditype', 'frommessagetype'),'translateind','tochannel','desc'), - 'classes': ('wide extrapretty',) + (None, {'fields': (('active','notindefaultrun',),'routescript',('idroute', 'seq',),'fromchannel', ('fromeditype', 'frommessagetype'),'translateind', ('tochannel', 'defer',), 'desc'), + 'classes': ('',) }), ('Filtering for outchannel',{'fields':('toeditype', 'tomessagetype','frompartner_tochannel', 'topartner_tochannel', 'testindicator'), - 'classes': ('collapse wide extrapretty',) + 'classes': ('collapse',) }), - ('Advanced',{'fields': ('alt','frompartner','topartner','defer','zip_incoming','zip_outgoing'), - 'classes': ('collapse wide extrapretty',) + ('Advanced',{'fields': ('alt','frompartner','topartner','zip_incoming','zip_outgoing'), + 'classes': ('collapse',) }), ) admin.site.register(models.routes,RoutesAdmin) @@ -243,10 +257,10 @@ class TranslateAdmin(BotsAdmin): search_fields = ('fromeditype', 'frommessagetype', 'alt', 'frompartner__idpartner', 'topartner__idpartner', 'tscript', 'toeditype', 'tomessagetype', 'desc') fieldsets = ( (None, {'fields': ('active', ('fromeditype', 'frommessagetype'),'tscript', ('toeditype', 'tomessagetype'),'desc'), - 'classes': ('wide extrapretty',) + 'classes': ('',) }), ('Multiple translations per editype/messagetype',{'fields': ('alt', 'frompartner', 'topartner'), - 'classes': ('wide extrapretty',) + 'classes': ('',) }), ) admin.site.register(models.translate,TranslateAdmin) @@ -263,7 +277,7 @@ def has_delete_permission(self, request, obj=None): #no deleting of counters search_fields = ('domein',) fieldsets = ( (None, {'fields': ('domein', 'nummer'), - 'classes': ('wide extrapretty',) + 'classes': ('',) }), ) admin.site.register(models.uniek,UniekAdmin) diff --git a/bots/install/settings.py b/bots/install/settings.py index c5a0ffb..1adbee3 100644 --- a/bots/install/settings.py +++ b/bots/install/settings.py @@ -87,28 +87,36 @@ SESSION_EXPIRE_AT_BROWSER_CLOSE = True #True: always log in when browser is closed SESSION_COOKIE_AGE = 3600 #seconds a user needs to login when no activity SESSION_SAVE_EVERY_REQUEST = True #if True: SESSION_COOKIE_AGE is interpreted as: since last activity +SESSION_COOKIE_NAME = 'Bots-0001' #make this unique for each environment if you need to log in to multiple at the same time #set in bots.ini #~ DEBUG = True -#~ TEMPLATE_DEBUG = DEBUG SITE_ID = 1 # Make this unique, and don't share it with anybody. SECRET_KEY = 'm@-u37qiujmeqfbu$daaaaz)sp^7an4u@h=wfx9dd$$$zl2i*x9#awojdc' #*******template handling and finding************************************************************************* -# List of callables that know how to import templates from various sources. -#disable because these used values are the default values -#~ TEMPLATE_LOADERS = ( - #~ 'django.template.loaders.filesystem.Loader', - #~ 'django.template.loaders.app_directories.Loader', - #~ ) - -TEMPLATE_DIRS = ( +# new TEMPLATES structure for Django 1.8+ +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [ os.path.join(PROJECT_PATH, 'templates'), - # Put strings here, like '/home/html/django_templates' or 'C:/www/django/templates'. - # Always use forward slashes, even on Windows. - # Don't forget to use absolute paths, not relative paths. - ) + ], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.contrib.auth.context_processors.auth', + 'django.template.context_processors.debug', + 'django.template.context_processors.i18n', + 'django.template.context_processors.request', + 'django.contrib.messages.context_processors.messages', + 'django.template.context_processors.static', + 'bots.bots_context.set_context', + ], + }, + }, +] #*******includes for django************************************************************************* LOCALE_PATHS = ( os.path.join(PROJECT_PATH, 'locale'), @@ -132,12 +140,3 @@ 'django.contrib.messages', 'bots', ) -TEMPLATE_CONTEXT_PROCESSORS = ( - 'django.contrib.auth.context_processors.auth', - 'django.core.context_processors.debug', - 'django.core.context_processors.i18n', - 'django.core.context_processors.request', - 'django.contrib.messages.context_processors.messages', - 'django.core.context_processors.static', - 'bots.bots_context.set_context', - ) diff --git a/bots/models.py b/bots/models.py index 8ababf6..25f3151 100644 --- a/bots/models.py +++ b/bots/models.py @@ -169,16 +169,16 @@ def script_link1(script,linktext): if os.path.exists(script): return '%s'%(urllib_quote(script.encode("utf-8")),linktext) else: - return ' %s'%linktext + return ' %s'%linktext def script_link2(script): ''' if script exists return "yes" icon + view link; else return "no" icon used in routes, channels (scripts are optional) ''' if os.path.exists(script): - return ' view'%urllib_quote(script.encode("utf-8")) + return ' view'%urllib.quote(script.encode("utf-8")) else: - return '' + return '' class MultipleEmailField(models.CharField): @@ -442,13 +442,13 @@ def __str__(self): return unicode(self.idroute) + ' ' + unicode(self.seq) def translt(self): if self.translateind == 0: - return '%s'%(self.get_translateind_display()) + return '%s'%(self.get_translateind_display()) elif self.translateind == 1: - return '%s'%(self.get_translateind_display()) + return '%s'%(self.get_translateind_display()) elif self.translateind == 2: - return '%s'%(self.get_translateind_display()) + return '%s'%(self.get_translateind_display()) elif self.translateind == 3: - return '%s'%(self.get_translateind_display()) + return '%s'%(self.get_translateind_display()) translt.allow_tags = True translt.admin_order_field = 'translateind' diff --git a/bots/pluglib.py b/bots/pluglib.py index 0bb428c..05b1519 100644 --- a/bots/pluglib.py +++ b/bots/pluglib.py @@ -332,7 +332,8 @@ def database2plug(db_table): plugs = serializers.serialize('python', db_table.objects.all()) if plugs: app,tablename = plugs[0]['model'].split('.',1) - table = django.db.models.get_model(app,tablename) + #table = django.db.models.get_model(app,tablename) + table = django.apps.apps.get_model(app,tablename) # Django 1.9 fix pk = table._meta.pk.name #adapt plugs for plug in plugs: diff --git a/bots/templates/admin/base.html b/bots/templates/admin/base.html index c72992a..dc53896 100644 --- a/bots/templates/admin/base.html +++ b/bots/templates/admin/base.html @@ -1,36 +1,42 @@ -{% load admin_static %} - +{% load i18n admin_static %} +{% get_current_language as LANGUAGE_CODE %}{% get_current_language_bidi as LANGUAGE_BIDI %} + - {{ bots_http_path }} - - {% block extrastyle %}{% endblock %} - - {% block extrahead %}{% endblock %} - {% if LANGUAGE_BIDI %}{% endif %} - - - +{{ bots_environment_text }} {{ bots_http_path }} + +{% block extrastyle %}{% endblock %} + +{% if LANGUAGE_BIDI %}{% endif %} + + +{% block extrahead %}{% endblock %} +{% block blockbots %}{% endblock %} + + {% load i18n %} - -{% if not is_popup %} + {% if not is_popup %} {% include botslogo %}
{{ bots_environment_text }}
{% include "bots/menu.html" %} -{% endif %} + {% endif %} +
+ + {% block messages %} {% if messages %} -
    - {% for message in messages %} - {{ message }} - {% endfor %} -
+
    {% for message in messages %} + {{ message|capfirst }} + {% endfor %}
{% endif %} + {% endblock messages %} + +
{% block pretitle %}{% endblock %} {% block content_title %}{% if title %}

{{ title }}

{% endif %}{% endblock %} @@ -38,9 +44,13 @@ {% block object-tools %}{% endblock %} {{ content }} {% endblock %} - {% block sidebar %}{% endblock %}
+ + + {% block footer %}{% endblock %}
+ + diff --git a/bots/templates/bots/confirm.html b/bots/templates/bots/confirm.html index ed0fced..2874dd3 100644 --- a/bots/templates/bots/confirm.html +++ b/bots/templates/bots/confirm.html @@ -36,7 +36,7 @@ {% for row in queryset.object_list %} -