refactored postinstall.sh

This commit is contained in:
André Bauer 2016-12-02 12:24:00 +01:00
parent abe5a9cc8b
commit 7a8559e678
40 changed files with 764 additions and 440 deletions

View file

@ -14,14 +14,12 @@ engines:
languages: languages:
- ruby - ruby
- javascript - javascript
- python
- php
eslint: eslint:
enabled: true enabled: true
fixme: fixme:
enabled: true enabled: true
phpmd: phpmd:
enabled: true enabled: false
rubocop: rubocop:
enabled: true enabled: true
ratings: ratings:
@ -38,8 +36,6 @@ ratings:
- "**.js" - "**.js"
- "**.jsx" - "**.jsx"
- "**.module" - "**.module"
- "**.php"
- "**.py"
exclude_paths: exclude_paths:
- config/ - config/
- db/ - db/

2
.csslintrc Normal file
View file

@ -0,0 +1,2 @@
--exclude-exts=.min.css
--ignore=adjoining-classes,box-model,ids,order-alphabetical,unqualified-attributes

1
.eslintignore Normal file
View file

@ -0,0 +1 @@
**/*{.,-}min.js

213
.eslintrc Normal file
View file

@ -0,0 +1,213 @@
ecmaFeatures:
modules: true
jsx: true
env:
amd: true
browser: true
es6: true
jquery: true
node: true
# http://eslint.org/docs/rules/
rules:
# Possible Errors
comma-dangle: [2, never]
no-cond-assign: 2
no-console: 0
no-constant-condition: 2
no-control-regex: 2
no-debugger: 2
no-dupe-args: 2
no-dupe-keys: 2
no-duplicate-case: 2
no-empty: 2
no-empty-character-class: 2
no-ex-assign: 2
no-extra-boolean-cast: 2
no-extra-parens: 0
no-extra-semi: 2
no-func-assign: 2
no-inner-declarations: [2, functions]
no-invalid-regexp: 2
no-irregular-whitespace: 2
no-negated-in-lhs: 2
no-obj-calls: 2
no-regex-spaces: 2
no-sparse-arrays: 2
no-unexpected-multiline: 2
no-unreachable: 2
use-isnan: 2
valid-jsdoc: 0
valid-typeof: 2
# Best Practices
accessor-pairs: 2
block-scoped-var: 0
complexity: [2, 6]
consistent-return: 0
curly: 0
default-case: 0
dot-location: 0
dot-notation: 0
eqeqeq: 2
guard-for-in: 2
no-alert: 2
no-caller: 2
no-case-declarations: 2
no-div-regex: 2
no-else-return: 0
no-empty-label: 2
no-empty-pattern: 2
no-eq-null: 2
no-eval: 2
no-extend-native: 2
no-extra-bind: 2
no-fallthrough: 2
no-floating-decimal: 0
no-implicit-coercion: 0
no-implied-eval: 2
no-invalid-this: 0
no-iterator: 2
no-labels: 0
no-lone-blocks: 2
no-loop-func: 2
no-magic-number: 0
no-multi-spaces: 0
no-multi-str: 0
no-native-reassign: 2
no-new-func: 2
no-new-wrappers: 2
no-new: 2
no-octal-escape: 2
no-octal: 2
no-proto: 2
no-redeclare: 2
no-return-assign: 2
no-script-url: 2
no-self-compare: 2
no-sequences: 0
no-throw-literal: 0
no-unused-expressions: 2
no-useless-call: 2
no-useless-concat: 2
no-void: 2
no-warning-comments: 0
no-with: 2
radix: 2
vars-on-top: 0
wrap-iife: 2
yoda: 0
# Strict
strict: 0
# Variables
init-declarations: 0
no-catch-shadow: 2
no-delete-var: 2
no-label-var: 2
no-shadow-restricted-names: 2
no-shadow: 0
no-undef-init: 2
no-undef: 0
no-undefined: 0
no-unused-vars: 0
no-use-before-define: 0
# Node.js and CommonJS
callback-return: 2
global-require: 2
handle-callback-err: 2
no-mixed-requires: 0
no-new-require: 0
no-path-concat: 2
no-process-exit: 2
no-restricted-modules: 0
no-sync: 0
# Stylistic Issues
array-bracket-spacing: 0
block-spacing: 0
brace-style: 0
camelcase: 0
comma-spacing: 0
comma-style: 0
computed-property-spacing: 0
consistent-this: 0
eol-last: 0
func-names: 0
func-style: 0
id-length: 0
id-match: 0
indent: 0
jsx-quotes: 0
key-spacing: 0
linebreak-style: 0
lines-around-comment: 0
max-depth: 0
max-len: 0
max-nested-callbacks: 0
max-params: 0
max-statements: [2, 30]
new-cap: 0
new-parens: 0
newline-after-var: 0
no-array-constructor: 0
no-bitwise: 0
no-continue: 0
no-inline-comments: 0
no-lonely-if: 0
no-mixed-spaces-and-tabs: 0
no-multiple-empty-lines: 0
no-negated-condition: 0
no-nested-ternary: 0
no-new-object: 0
no-plusplus: 0
no-restricted-syntax: 0
no-spaced-func: 0
no-ternary: 0
no-trailing-spaces: 0
no-underscore-dangle: 0
no-unneeded-ternary: 0
object-curly-spacing: 0
one-var: 0
operator-assignment: 0
operator-linebreak: 0
padded-blocks: 0
quote-props: 0
quotes: 0
require-jsdoc: 0
semi-spacing: 0
semi: 0
sort-vars: 0
space-after-keywords: 0
space-before-blocks: 0
space-before-function-paren: 0
space-before-keywords: 0
space-in-parens: 0
space-infix-ops: 0
space-return-throw-case: 0
space-unary-ops: 0
spaced-comment: 0
wrap-regex: 0
# ECMAScript 6
arrow-body-style: 0
arrow-parens: 0
arrow-spacing: 0
constructor-super: 0
generator-star-spacing: 0
no-arrow-condition: 0
no-class-assign: 0
no-const-assign: 0
no-dupe-class-members: 0
no-this-before-super: 0
no-var: 0
object-shorthand: 0
prefer-arrow-callback: 0
prefer-const: 0
prefer-reflect: 0
prefer-spread: 0
prefer-template: 0
require-yield: 0

View file

@ -5,6 +5,6 @@ since-tag=1.0.0
bug-labels=bug,minor bug,security bug-labels=bug,minor bug,security
enhancement-labels=enhancement,feature enhancement-labels=enhancement,feature
issues-wo-labels=false issues-wo-labels=false
include-labels=security,trigger,UX/UI,admin area,API,blocker,browser,bug,channel,chat,duplicate,enhancement,feature,import,minor bug,notification,email filter,ticket templates include-labels=security,trigger,UX/UI,admin area,API,browser,bug,channel,chat,email filter,enhancement,feature,import,minor bug,notification,email filter,ticket templates,
issue-line-labels=enhancement,feature,bug,minor bug,security issue-line-labels=enhancement,feature,bug,minor bug,notification,reporting,security,ticket templates,translation,trigger,UX/UI
exclude-tags=9.0.1,0.9.1,v0.1.8,v0.1.7,unittests_passed exclude-tags=9.0.1,0.9.1,v0.1.8,v0.1.7,unittests_passed

View file

@ -1,14 +1,20 @@
dist: trusty dist: trusty
sudo: required sudo: required
notifications: notifications:
email: false email:
- me+tv@zammad.com
env:
- DB=mysql
- DB=postgresql
addons: addons:
postgresql: "9.4"
apt: apt:
packages: packages:
- mysql-server-5.6 - mysql-server-5.6
- mysql-client-core-5.6 - mysql-client-core-5.6
- mysql-client-5.6 - mysql-client-5.6
services: services:
- postgresql
- mysql - mysql
language: ruby language: ruby
rvm: rvm:
@ -18,12 +24,17 @@ before_install:
- sudo apt-get install -y curl git-core patch build-essential bison zlib1g-dev libssl-dev libxml2-dev libxml2-dev sqlite3 libsqlite3-dev autotools-dev libxslt1-dev libyaml-0-2 autoconf automake libreadline6-dev libyaml-dev libtool libgmp-dev libgdbm-dev libncurses5-dev pkg-config libffi-dev libmysqlclient-dev postfix - sudo apt-get install -y curl git-core patch build-essential bison zlib1g-dev libssl-dev libxml2-dev libxml2-dev sqlite3 libsqlite3-dev autotools-dev libxslt1-dev libyaml-0-2 autoconf automake libreadline6-dev libyaml-dev libtool libgmp-dev libgdbm-dev libncurses5-dev pkg-config libffi-dev libmysqlclient-dev postfix
- mysql -u root -e "CREATE USER 'some_user'@'localhost' IDENTIFIED BY 'some_pass';" - mysql -u root -e "CREATE USER 'some_user'@'localhost' IDENTIFIED BY 'some_pass';"
- mysql -u root -e "GRANT ALL PRIVILEGES ON *.* TO 'some_user'@'localhost';" - mysql -u root -e "GRANT ALL PRIVILEGES ON *.* TO 'some_user'@'localhost';"
- if [ "${DB}" = "mysql" ]; then mysql -u root -e "CREATE USER 'some_user'@'localhost' IDENTIFIED BY 'some_pass';"; fi
- if [ "${DB}" = "mysql" ]; then mysql -u root -e "GRANT ALL PRIVILEGES ON *.* TO 'some_user'@'localhost';"; fi
- if [ "${DB}" = "mysql" ]; then cp config/database.yml.test-mysql config/database.yml; fi
- if [ "${DB}" = "postgresql" ]; then psql -c 'create database zammad_test;' -U postgres; fi
- if [ "${DB}" = "postgresql" ]; then cp config/database.yml.test-postgresql config/database.yml; fi
- export RAILS_ENV=test - export RAILS_ENV=test
- export EMAILHELPER_MAILBOX_1='unittestemailhelper01@znuny.com:somepass'
- cp config/database.yml.test config/database.yml
install: install:
- bundle install --without postgres - if [ "${DB}" = "mysql" ]; then bundle install --without postgres; fi
- if [ "${DB}" = "postgresql" ]; then bundle install; fi
script: script:
- bundle exec rubocop
- rake db:create - rake db:create
- rake db:migrate - rake db:migrate
- rake db:seed - rake db:seed
@ -31,3 +42,17 @@ script:
- rake test:controllers - rake test:controllers
- rake assets:precompile - rake assets:precompile
- rake db:drop - rake db:drop
- rake db:create
- rake db:migrate
- rake db:seed
- ruby -I test/ test/integration/auto_wizard_test.rb
- rake db:drop
- rake db:create
- rake db:migrate
- rake db:seed
- ruby -I test/ test/integration/geo_location_test.rb
- ruby -I test/ test/integration/geo_calendar_test.rb
- ruby -I test/ test/integration/user_agent_test.rb
- ruby -I test/ test/integration/user_device_controller_test.rb
- ruby -I test/ test/integration/sipgate_controller_test.rb
- rake db:drop

View file

@ -9,17 +9,20 @@ with a team of agents?
You're going to love Zammad! You're going to love Zammad!
## Statusbadges ## Statusbadges
- Build: [![Build Status](https://travis-ci.org/zammad/zammad.svg?branch=develop)](https://travis-ci.org/zammad/zammad) - Build: [![Build Status](https://travis-ci.org/zammad/zammad.svg?branch=develop)](https://travis-ci.org/zammad/zammad)
- Code: [![Code Climate](https://codeclimate.com/github/zammad/zammad/badges/gpa.svg)](https://codeclimate.com/github/zammad/zammad) - Code: [![Code Climate](https://codeclimate.com/github/zammad/zammad/badges/gpa.svg)](https://codeclimate.com/github/zammad/zammad)
- Docs: [![Documentation Status](https://readthedocs.org/projects/zammad/badge/?version=latest)](https://docs.zammad.org) - Docs: [![Documentation Status](https://readthedocs.org/projects/zammad/badge/?version=latest)](https://docs.zammad.org)
- Docker Image: [![](https://images.microbadger.com/badges/image/zammad/zammad.svg)](https://microbadger.com/images/zammad/zammad) [![](https://images.microbadger.com/badges/version/zammad/zammad.svg)](https://microbadger.com/images/zammad/zammad) - Docker Image: [![](https://images.microbadger.com/badges/image/zammad/zammad.svg)](https://microbadger.com/images/zammad/zammad) [![](https://images.microbadger.com/badges/version/zammad/zammad.svg)](https://hub.docker.com/r/zammad/zammad/)
## Installing & Getting Started ## Installing & Getting Started
https://docs.zammad.org https://docs.zammad.org
## Screenshots ## Screenshots
https://zammad.org/screenshots https://zammad.org/screenshots
@ -38,3 +41,4 @@ https://zammad.org/participate
Thanks! ❤️ ❤️ ❤️ Thanks! ❤️ ❤️ ❤️
Your Zammad Team Your Zammad Team

View file

@ -25,6 +25,10 @@ class App.Navigation extends App.ControllerWidgetPermanent
@throttledSearch = _.throttle @search, 200 @throttledSearch = _.throttle @search, 200
@globalSearch = new App.GlobalSearch(
render: @renderResult
)
# rerender view, e. g. on langauge change # rerender view, e. g. on langauge change
@bind 'ui:rerender', => @bind 'ui:rerender', =>
@renderMenu() @renderMenu()
@ -127,15 +131,15 @@ class App.Navigation extends App.ControllerWidgetPermanent
items = @getItems(navbar: @Config.get('NavBarRight')) items = @getItems(navbar: @Config.get('NavBarRight'))
# get open tabs to repopen on rerender # get open tabs to repopen on rerender
open_tab = {} openTab = {}
@$('.open').children('a').each( (i,d) -> @$('.open').children('a').each( (i,d) ->
href = $(d).attr('href') href = $(d).attr('href')
open_tab[href] = true openTab[href] = true
) )
@$('.navbar-items-personal').html App.view('navigation/personal')( @$('.navbar-items-personal').html App.view('navigation/personal')(
items: items items: items
open_tab: open_tab openTab: openTab
) )
# only start avatar widget on existing session # only start avatar widget on existing session
@ -151,6 +155,7 @@ class App.Navigation extends App.ControllerWidgetPermanent
# remove result if not result exists # remove result if not result exists
if _.isEmpty(result) if _.isEmpty(result)
@searchContainer.removeClass('open') @searchContainer.removeClass('open')
@globalSearch.close()
@searchResult.html('') @searchResult.html('')
return return
@ -275,6 +280,7 @@ class App.Navigation extends App.ControllerWidgetPermanent
emptyAndClose: => emptyAndClose: =>
@searchInput.val('') @searchInput.val('')
@searchContainer.removeClass('filled').removeClass('open').removeClass('focused') @searchContainer.removeClass('filled').removeClass('open').removeClass('focused')
@globalSearch.close()
# remove not needed popovers # remove not needed popovers
@delay(@anyPopoversDestroy, 100, 'removePopovers') @delay(@anyPopoversDestroy, 100, 'removePopovers')
@ -282,6 +288,7 @@ class App.Navigation extends App.ControllerWidgetPermanent
andClose: => andClose: =>
@searchInput.blur() @searchInput.blur()
@searchContainer.removeClass('open') @searchContainer.removeClass('open')
@globalSearch.close()
@delay(@anyPopoversDestroy, 100, 'removePopovers') @delay(@anyPopoversDestroy, 100, 'removePopovers')
search: => search: =>
@ -290,11 +297,7 @@ class App.Navigation extends App.ControllerWidgetPermanent
return if query is @query return if query is @query
@query = query @query = query
@searchContainer.toggleClass('filled', !!@query) @searchContainer.toggleClass('filled', !!@query)
@globalSearch.search(query: @query)
App.GlobalSearch.execute(
query: @query
render: @renderResult
)
getItems: (data) -> getItems: (data) ->
navbar = _.values(data.navbar) navbar = _.values(data.navbar)

View file

@ -1,5 +1,4 @@
class App.Search extends App.Controller class App.Search extends App.Controller
searchResultCache: {}
elements: elements:
'.js-search': 'searchInput' '.js-search': 'searchInput'
@ -25,6 +24,11 @@ class App.Search extends App.Controller
@throttledSearch = _.throttle @search, 200 @throttledSearch = _.throttle @search, 200
@globalSearch = new App.GlobalSearch(
render: @renderResult
limit: 50
)
@render() @render()
# rerender view, e. g. on langauge change # rerender view, e. g. on langauge change
@ -52,10 +56,11 @@ class App.Search extends App.Controller
@navupdate(url: '#search', type: 'menu') @navupdate(url: '#search', type: 'menu')
return if _.isEmpty(params.query) return if _.isEmpty(params.query)
@$('.js-search').val(params.query).trigger('change') @$('.js-search').val(params.query).trigger('change')
return if @shown
@throttledSearch(true) @throttledSearch(true)
hide: -> hide: ->
# nothing @shown = false
changed: -> changed: ->
# nothing # nothing
@ -117,11 +122,7 @@ class App.Search extends App.Controller
@query = query @query = query
@updateTask() @updateTask()
App.GlobalSearch.execute( @globalSearch.search(query: @query)
query: @query
render: @renderResult
limit: 50
)
renderResult: (result = []) => renderResult: (result = []) =>
@result = result @result = result

View file

@ -1,37 +1,27 @@
class App.GlobalSearch class App.GlobalSearch extends App.Controller
_instance = undefined
@execute: (args) ->
if _instance == undefined
_instance ?= new _globalSearchSingleton
_instance.execute(args)
class _globalSearchSingleton extends Spine.Module
constructor: -> constructor: ->
@searchResultCache = undefined super
@searchResultCacheByKey = {} @searchResultCache = {}
@lastQuery = undefined
@apiPath = App.Config.get('api_path') @apiPath = App.Config.get('api_path')
@ajaxId = "search-#{Math.floor( Math.random() * 999999 )}"
execute: (params) -> search: (params) =>
query = params.query query = params.query
render = params.render
limit = params.limit || 10
cacheKey = "#{query}_#{limit}"
# use cache for search result # use cache for search result
currentTime = new Date currentTime = new Date
if @searchResultCacheByKey[cacheKey] && @searchResultCacheByKey[cacheKey].time > currentTime.setSeconds(currentTime.getSeconds() - 20) if @searchResultCache[query] && @searchResultCache[query].time > currentTime.setSeconds(currentTime.getSeconds() - 20)
@renderTry(render, @searchResultCacheByKey[cacheKey].result, cacheKey) @renderTry(@searchResultCache[query].result, query)
return return
App.Ajax.request( App.Ajax.request(
id: 'search' id: @ajaxId
type: 'GET' type: 'GET'
url: "#{@apiPath}/search" url: "#{@apiPath}/search"
data: data:
query: query query: query
limit: limit limit: @limit || 10
processData: true processData: true
success: (data, status, xhr) => success: (data, status, xhr) =>
App.Collection.loadAssets(data.assets) App.Collection.loadAssets(data.assets)
@ -49,21 +39,24 @@ class _globalSearchSingleton extends Spine.Module
else else
App.Log.error('_globalSearchSingleton', "No such model App.#{item.type}") App.Log.error('_globalSearchSingleton', "No such model App.#{item.type}")
@renderTry(render, result, cacheKey) @renderTry(result, query)
) )
renderTry: (render, result, cacheKey) => renderTry: (result, query) =>
# if result hasn't changed, do not rerender # if result hasn't changed, do not rerender
diff = false diff = false
if @searchResultCache if @lastQuery is query && @searchResultCache[query]
diff = difference(@searchResultCache, result) diff = difference(@searchResultCache[query].result, result)
return if diff isnt false && _.isEmpty(diff) return if diff isnt false && _.isEmpty(diff)
@lastQuery = query
# cache search result # cache search result
@searchResultCache = result @searchResultCache[query] =
@searchResultCacheByKey[cacheKey] =
result: result result: result
time: new Date time: new Date
render(result) @render(result)
close: =>
@lastQuery = undefined

View file

@ -1,5 +1,5 @@
class App.Macro extends App.Model class App.Macro extends App.Model
@configure 'Macro', 'name', 'perform', 'active' @configure 'Macro', 'name', 'perform', 'note', 'active'
@extend Spine.Model.Ajax @extend Spine.Model.Ajax
@url: @apiPath + '/macros' @url: @apiPath + '/macros'
@configure_attributes = [ @configure_attributes = [

View file

@ -1,6 +1,6 @@
<% for item in @items: %> <% for item in @items: %>
<% if item.child: %> <% if item.child: %>
<li class="<% if item.class: %><%- item.class %><% end %> dropup <% if @open_tab[item.target] : %>open<% end %>"> <li class="<% if item.class: %><%- item.class %><% end %> dropup <% if @openTab[item.target] : %>open<% end %>">
<a class="list-button dropdown-toggle js-action" data-toggle="dropdown" href="<%= item.target %>" title="<% if item.translate: %><%- @Ti( item.name ) %><% else: %><%= item.name %><% end %>"> <a class="list-button dropdown-toggle js-action" data-toggle="dropdown" href="<%= item.target %>" title="<% if item.translate: %><%- @Ti( item.name ) %><% else: %><%= item.name %><% end %>">
<span class="dropdown-nose"></span> <span class="dropdown-nose"></span>
<% if item.class is 'user': %> <% if item.class is 'user': %>

View file

@ -21,8 +21,7 @@ add an avatar based on auto detection (email address)
# return if we run import mode # return if we run import mode
return if Setting.get('import_mode') return if Setting.get('import_mode')
return if !data[:url] return if data[:url].blank?
return if data[:url].empty?
Avatar.add( Avatar.add(
object: data[:object], object: data[:object],
@ -96,7 +95,7 @@ add avatar by url
# check if avatar with url already exists # check if avatar with url already exists
avatar_already_exists = nil avatar_already_exists = nil
if data[:source] && !data[:source].empty? if data[:source].present?
avatar_already_exists = Avatar.find_by( avatar_already_exists = Avatar.find_by(
object_lookup_id: object_id, object_lookup_id: object_id,
o_id: data[:o_id], o_id: data[:o_id],
@ -105,7 +104,7 @@ add avatar by url
end end
# fetch image based on http url # fetch image based on http url
if data[:url] && data[:url] =~ /^http/ if data[:url] =~ /^http/
# check if source ist already updated within last 2 minutes # check if source ist already updated within last 2 minutes
if avatar_already_exists && avatar_already_exists.source_url == data[:url] if avatar_already_exists && avatar_already_exists.source_url == data[:url]

View file

@ -75,92 +75,19 @@ returnes preset of ical feeds
returns returns
{ {
'US' => 'http://www.google.com/calendar/ical/en.usa%23holiday%40group.v.calendar.google.com/public/basic.ics', 'http://www.google.com/calendar/ical/en.usa%23holiday%40group.v.calendar.google.com/public/basic.ics' => 'US',
... ...
} }
=end =end
def self.ical_feeds def self.ical_feeds
gfeeds = { data = YAML.load_file(Rails.root.join('config/holiday_calendars.yml'))
'Australia' => 'en.australian', url = data['url']
'Austria' => 'de.austrian',
'Argentina' => 'en.ar', data['countries'].map do |country, domain|
'Bahamas' => 'en.bs', [(url % { domain: domain }), country]
'Belarus' => 'en.by', end.to_h
'Brazil' => 'en.brazilian',
'Bulgaria' => 'en.bulgarian',
'Canada' => 'en.canadian',
'China' => 'en.china',
'Chile' => 'en.cl',
'Costa Rica' => 'en.cr',
'Colombia' => 'en.co',
'Croatia' => 'en.croatian',
'Cuba' => 'en.cu',
'Cyprus' => 'de.cy',
'Switzerland' => 'de.ch',
'Denmark' => 'da.danish',
'Netherlands' => 'nl.dutch',
'Egypt' => 'en.eg',
'Ethiopia' => 'en.et',
'Ecuador' => 'en.ec',
'Estonia' => 'en.ee',
'Finland' => 'en.finnish',
'France' => 'en.french',
'Germany' => 'de.german',
'Greece' => 'en.greek',
'Ghana' => 'en.gh',
'Hong Kong' => 'en.hong_kong',
'Haiti' => 'en.ht',
'Hungary' => 'en.hungarian',
'India' => 'en.indian',
'Indonesia' => 'en.indonesian',
'Iran' => 'en.ir',
'Ireland' => 'en.irish',
'Italy' => 'it.italian',
'Israel' => 'en.jewish',
'Japan' => 'en.japanese',
'Kuwait' => 'en.kw',
'Latvia' => 'en.latvian',
'Liechtenstein' => 'en.li',
'Lithuania' => 'en.lithuanian',
'Luxembourg' => 'en.lu',
'Malaysia' => 'en.malaysia',
'Mexico' => 'en.mexican',
'Morocco' => 'en.ma',
'Mauritius' => 'en.mu',
'Moldova' => 'en.md',
'New Zealand' => 'en.new_zealand',
'Norway' => 'en.norwegian',
'Philippines' => 'en.philippines',
'Poland' => 'en.polish',
'Portugal' => 'en.portuguese',
'Pakistan' => 'en.pk',
'Russia' => 'en.russian',
'Senegal' => 'en.sn',
'Singapore' => 'en.singapore',
'South Africa' => 'en.sa',
'South Korean' => 'en.south_korea',
'Spain' => 'en.spain',
'Slovakia' => 'en.slovak',
'Serbia' => 'en.rs',
'Slovenia' => 'en.slovenian',
'Sweden' => 'en.swedish',
'Taiwan' => 'en.taiwan',
'Thai' => 'en.th',
'Turkey' => 'en.turkish',
'UK' => 'en.uk',
'US' => 'en.usa',
'Ukraine' => 'en.ukrainian',
'Uruguay' => 'en.uy',
'Vietnam' => 'en.vietnamese',
'Venezuela' => 'en.ve',
}
all_feeds = {}
gfeeds.each { |key, name|
all_feeds["http://www.google.com/calendar/ical/#{name}%23holiday%40group.v.calendar.google.com/public/basic.ics"] = key
}
all_feeds
end end
=begin =begin
@ -201,7 +128,7 @@ returns
=end =end
def self.sync def self.sync
Calendar.all.each(&:sync) Calendar.find_each(&:sync)
true true
end end
@ -313,7 +240,7 @@ returns
# if changed calendar is default, set all others default to false # if changed calendar is default, set all others default to false
def sync_default def sync_default
return if !default return if !default
Calendar.all.each { |calendar| Calendar.find_each { |calendar|
next if calendar.id == id next if calendar.id == id
next if !calendar.default next if !calendar.default
calendar.default = false calendar.default = false
@ -331,7 +258,7 @@ returns
# check if sla's are refer to an existing calendar # check if sla's are refer to an existing calendar
default_calendar = Calendar.find_by(default: true) default_calendar = Calendar.find_by(default: true)
Sla.all.each { |sla| Sla.find_each { |sla|
if !sla.calendar_id if !sla.calendar_id
sla.calendar_id = default_calendar.id sla.calendar_id = default_calendar.id
sla.save! sla.save!

View file

@ -82,8 +82,7 @@ class Channel::Driver::Facebook
@sync['pages'].each { |page_to_sync_id, page_to_sync_params| @sync['pages'].each { |page_to_sync_id, page_to_sync_params|
page = get_page(page_to_sync_id) page = get_page(page_to_sync_id)
next if !page next if !page
next if !page_to_sync_params['group_id'] next if page_to_sync_params['group_id'].blank?
next if page_to_sync_params['group_id'].empty?
page_client = Facebook.new(page['access_token']) page_client = Facebook.new(page['access_token'])
posts = page_client.client.get_connection('me', 'feed', fields: 'id,from,to,message,created_time,permalink_url,comments{id,from,to,message,created_time}') posts = page_client.client.get_connection('me', 'feed', fields: 'id,from,to,message,created_time,permalink_url,comments{id,from,to,message,created_time}')

View file

@ -68,6 +68,11 @@ example
end end
if options.key?(:port) && !options[:port].empty? if options.key?(:port) && !options[:port].empty?
port = options[:port] port = options[:port]
# disable ssl for non ssl ports
if port == 143 && !options.key?(:ssl)
ssl = false
end
end end
Rails.logger.info "fetching imap (#{options[:host]}/#{options[:user]} port=#{port},ssl=#{ssl})" Rails.logger.info "fetching imap (#{options[:host]}/#{options[:user]} port=#{port},ssl=#{ssl})"

View file

@ -51,8 +51,13 @@ returns
ssl = false ssl = false
port = 110 port = 110
end end
if options.key?(:port) && !options[:port].empty? if options.key?(:port) && options[:port].present?
port = options[:port] port = options[:port]
# disable ssl for non ssl ports
if port == 110 && !options.key?(:ssl)
ssl = false
end
end end
Rails.logger.info "fetching pop3 (#{options[:host]}/#{options[:user]} port=#{port},ssl=#{ssl})" Rails.logger.info "fetching pop3 (#{options[:host]}/#{options[:user]} port=#{port},ssl=#{ssl})"

View file

@ -7,7 +7,14 @@ class Channel::Driver::Sendmail
return if Setting.get('import_mode') return if Setting.get('import_mode')
mail = Channel::EmailBuild.build(attr, notification) mail = Channel::EmailBuild.build(attr, notification)
mail.delivery_method :sendmail mail.delivery_method delivery_method
mail.deliver mail.deliver
end end
private
def delivery_method
return :test if Rails.env.test?
:sendmail
end
end end

View file

@ -30,8 +30,8 @@ class Channel::Driver::Smtp
if !options.key?(:port) || options[:port].empty? if !options.key?(:port) || options[:port].empty?
options[:port] = 25 options[:port] = 25
end end
if !options.key?(:domain)
if !options.key?(:domain)
# set fqdn, if local fqdn - use domain of sender # set fqdn, if local fqdn - use domain of sender
fqdn = Setting.get('fqdn') fqdn = Setting.get('fqdn')
if fqdn =~ /(localhost|\.local^|\.loc^)/i && (attr['from'] || attr[:from]) if fqdn =~ /(localhost|\.local^|\.loc^)/i && (attr['from'] || attr[:from])
@ -58,7 +58,7 @@ class Channel::Driver::Smtp
} }
# add authentication only if needed # add authentication only if needed
if options[:user] && !options[:user].empty? if options[:user].present?
smtp_params[:user_name] = options[:user] smtp_params[:user_name] = options[:user]
smtp_params[:password] = options[:password] smtp_params[:password] = options[:password]
smtp_params[:authentication] = options[:authentication] smtp_params[:authentication] = options[:authentication]

View file

@ -269,13 +269,10 @@ returns
private private
def fetch_search def fetch_search
return if !@sync[:search] return if @sync[:search].blank?
return if @sync[:search].empty?
@sync[:search].each { |search| @sync[:search].each { |search|
next if !search[:term] next if search[:term].blank?
next if search[:term].to_s.empty? next if search[:group_id].blank?
next if !search[:group_id]
next if search[:group_id].to_s.empty?
result_type = search[:type] || 'mixed' result_type = search[:type] || 'mixed'
Rails.logger.debug " - searching for '#{search[:term]}'" Rails.logger.debug " - searching for '#{search[:term]}'"
older_import = 0 older_import = 0
@ -296,10 +293,8 @@ returns
end end
def fetch_mentions def fetch_mentions
return if !@sync[:mentions] return if @sync[:mentions].blank?
return if @sync[:mentions].empty? return if @sync[:mentions][:group_id].blank?
return if !@sync[:mentions][:group_id]
return if @sync[:mentions][:group_id].to_s.empty?
Rails.logger.debug ' - searching for mentions' Rails.logger.debug ' - searching for mentions'
older_import = 0 older_import = 0
older_import_max = 20 older_import_max = 20
@ -318,10 +313,8 @@ returns
end end
def fetch_direct_messages def fetch_direct_messages
return if !@sync[:direct_messages] return if @sync[:direct_messages].blank?
return if @sync[:direct_messages].empty? return if @sync[:direct_messages][:group_id].blank?
return if !@sync[:direct_messages][:group_id]
return if @sync[:direct_messages][:group_id].to_s.empty?
Rails.logger.debug ' - searching for direct_messages' Rails.logger.debug ' - searching for direct_messages'
older_import = 0 older_import = 0
older_import_max = 20 older_import_max = 20

View file

@ -74,9 +74,7 @@ class Channel::EmailParser
mail = Mail.new(msg) mail = Mail.new(msg)
# set all headers # set all headers
mail.header.fields.each { |field| mail.header.fields.select(&:name).each { |field|
next if !field.name
# full line, encode, ready for storage # full line, encode, ready for storage
data[field.name.to_s.downcase.to_sym] = Encode.conv('utf8', field.to_s) data[field.name.to_s.downcase.to_sym] = Encode.conv('utf8', field.to_s)
@ -318,12 +316,10 @@ class Channel::EmailParser
end end
# for some broken sm mail clients (X-MimeOLE: Produced By Microsoft Exchange V6.5) # for some broken sm mail clients (X-MimeOLE: Produced By Microsoft Exchange V6.5)
if !filename filename ||= file.header[:content_location].to_s
filename = file.header[:content_location].to_s
end
# generate file name # generate file name
if !filename || filename.empty? if filename.blank?
attachment_count = 0 attachment_count = 0
(1..1000).each { |count| (1..1000).each { |count|
filename_exists = false filename_exists = false

View file

@ -23,9 +23,9 @@ class Observer::Ticket::Article::CommunicateEmail::BackgroundJob
# send email # send email
if !ticket.group.email_address_id if !ticket.group.email_address_id
log_error(record, "No email address definde for group id '#{ticket.group.id}'!") log_error(record, "No email address defined for group id '#{ticket.group.id}'!")
elsif !ticket.group.email_address.channel_id elsif !ticket.group.email_address.channel_id
log_error(record, "No channel definde for email_address id '#{ticket.group.email_address_id}'!") log_error(record, "No channel defined for email_address id '#{ticket.group.email_address_id}'!")
end end
channel = ticket.group.email_address.channel channel = ticket.group.email_address.channel

View file

@ -7,9 +7,7 @@ class Observer::Ticket::Article::CommunicateFacebook::BackgroundJob
article = Ticket::Article.find(@article_id) article = Ticket::Article.find(@article_id)
# set retry count # set retry count
if !article.preferences['delivery_retry'] article.preferences['delivery_retry'] ||= 0
article.preferences['delivery_retry'] = 0
end
article.preferences['delivery_retry'] += 1 article.preferences['delivery_retry'] += 1
ticket = Ticket.lookup(id: article.ticket_id) ticket = Ticket.lookup(id: article.ticket_id)
@ -24,7 +22,7 @@ class Observer::Ticket::Article::CommunicateFacebook::BackgroundJob
end end
# fill in_reply_to # fill in_reply_to
if !article.in_reply_to || article.in_reply_to.empty? if article.in_reply_to.blank?
article.in_reply_to = ticket.articles.first.message_id article.in_reply_to = ticket.articles.first.message_id
end end

View file

@ -25,8 +25,7 @@ class Organization < ApplicationModel
private private
def domain_cleanup def domain_cleanup
return if !domain return if domain.blank?
return if domain.empty?
domain.gsub!(/@/, '') domain.gsub!(/@/, '')
domain.gsub!(/\s*/, '') domain.gsub!(/\s*/, '')
domain.strip! domain.strip!

View file

@ -163,7 +163,7 @@ returns
} }
} }
config.hours = hours config.hours = hours
if !hours || hours.empty? if hours.blank?
raise "No configured hours found in calendar #{calendar.inspect}" raise "No configured hours found in calendar #{calendar.inspect}"
end end

View file

@ -73,7 +73,7 @@ module Ticket::Number::Date
end end
def check(string) def check(string)
return if !string || string.empty? return if string.blank?
# get config # get config
system_id = Setting.get('system_id') || '' system_id = Setting.get('system_id') || ''

View file

@ -70,7 +70,7 @@ module Ticket::Number::Increment
end end
def check(string) def check(string)
return if !string || string.empty? return if string.blank?
# get config # get config
system_id = Setting.get('system_id') || '' system_id = Setting.get('system_id') || ''

View file

@ -21,7 +21,7 @@ returns
# collect article data # collect article data
# add tags # add tags
tags = Tag.tag_list(object: 'Ticket', o_id: id) tags = Tag.tag_list(object: 'Ticket', o_id: id)
if tags && !tags.empty? if tags.present?
attributes[:tag] = tags attributes[:tag] = tags
end end

View file

@ -154,18 +154,7 @@ returns
=end =end
def role?(role_name) def role?(role_name)
roles.where(name: role_name).any?
result = false
roles.each { |role|
if role_name.class == Array
next if !role_name.include?(role.name)
elsif role.name != role_name
next
end
result = true
break
}
result
end end
=begin =begin
@ -226,16 +215,13 @@ returns
def self.authenticate(username, password) def self.authenticate(username, password)
# do not authenticate with nothing # do not authenticate with nothing
return if !username || username == '' return if username.blank? || password.blank?
return if !password || password == ''
# try to find user based on login # try to find user based on login
user = User.find_by(login: username.downcase, active: true) user = User.find_by(login: username.downcase, active: true)
# try second lookup with email # try second lookup with email
if !user user ||= User.find_by(email: username.downcase, active: true)
user = User.find_by(email: username.downcase, active: true)
end
# check failed logins # check failed logins
max_login_failed = Setting.get('password_max_login_failed').to_i || 10 max_login_failed = Setting.get('password_max_login_failed').to_i || 10
@ -249,7 +235,7 @@ returns
# set login failed +1 # set login failed +1
if !user_auth && user if !user_auth && user
sleep 1 sleep 1
user.login_failed = user.login_failed + 1 user.login_failed += 1
user.save user.save
end end
@ -454,15 +440,13 @@ returns
=end =end
def self.password_reset_new_token(username) def self.password_reset_new_token(username)
return if !username || username == '' return if username.blank?
# try to find user based on login # try to find user based on login
user = User.find_by(login: username.downcase, active: true) user = User.find_by(login: username.downcase, active: true)
# try second lookup with email # try second lookup with email
if !user user ||= User.find_by(email: username.downcase, active: true)
user = User.find_by(email: username.downcase, active: true)
end
# check if email address exists # check if email address exists
return if !user return if !user
@ -737,8 +721,7 @@ returns
end end
def check_preferences_default def check_preferences_default
return if !@preferences_default return if @preferences_default.blank?
return if @preferences_default.empty?
preferences_tmp = @preferences_default.merge(preferences) preferences_tmp = @preferences_default.merge(preferences)
self.preferences = preferences_tmp self.preferences = preferences_tmp
@ -871,8 +854,7 @@ returns
end end
def avatar_for_email_check def avatar_for_email_check
return if !email return if email.blank?
return if email.empty?
return if email !~ /@/ return if email !~ /@/
return if !changes['email'] && updated_at > Time.zone.now - 10.days return if !changes['email'] && updated_at > Time.zone.now - 10.days
@ -900,7 +882,7 @@ returns
def check_password def check_password
# set old password again if not given # set old password again if not given
if password == '' || !password if password.blank?
# get current record # get current record
if id if id

View file

@ -22,9 +22,7 @@ store new device for user if device not already known
def self.add(user_agent, ip, user_id, fingerprint, type) def self.add(user_agent, ip, user_id, fingerprint, type)
# since gem browser 2 is not handling nil for user_agent, set it to '' # since gem browser 2 is not handling nil for user_agent, set it to ''
if user_agent.nil? user_agent ||= ''
user_agent = ''
end
# get location info # get location info
location_details = Service::GeoIp.location(ip) location_details = Service::GeoIp.location(ip)
@ -79,7 +77,7 @@ store new device for user if device not already known
name = browser[:plattform] name = browser[:plattform]
end end
if browser[:name] && browser[:name] != 'Other' if browser[:name] && browser[:name] != 'Other'
if name && !name.empty? if name.present?
name += ', ' name += ', '
end end
name += browser[:name] name += browser[:name]

View file

@ -1,33 +0,0 @@
production:
adapter: mysql2
database: zammad_prod
pool: 50
timeout: 5000
encoding: utf8
username: some_user
password: some_pass
host: 127.0.0.1
development:
adapter: mysql2
database: zammad_development
pool: 50
timeout: 5000
encoding: utf8
username: some_user
password: some_pass
host: 127.0.0.1
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
adapter: mysql2
database: zammad_test
pool: 50
timeout: 5000
encoding: utf8
username: some_user
password: some_pass
host: 127.0.0.1

View file

@ -0,0 +1,11 @@
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
adapter: mysql2
database: zammad_test
pool: 50
timeout: 5000
encoding: utf8
username: some_user
password: some_pass

View file

@ -0,0 +1,11 @@
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
adapter: postgresql
database: zammad_test
pool: 50
timeout: 5000
encoding: utf8
username: postgres
password:

View file

@ -0,0 +1,78 @@
---
# % character in the URL has to be escaped (% => %%)
url: "http://www.google.com/calendar/ical/%{domain}%%23holiday%%40group.v.calendar.google.com/public/basic.ics"
# Mapping from country to domain
countries:
Australia: en.australian
Austria: de.austrian
Argentina: en.ar
Bahamas: en.bs
Belarus: en.by
Brazil: en.brazilian
Bulgaria: en.bulgarian
Canada: en.canadian
China: en.china
Chile: en.cl
Costa Rica: en.cr
Colombia: en.co
Croatia: en.croatian
Cuba: en.cu
Cyprus: de.cy
Switzerland: de.ch
Denmark: da.danish
Netherlands: nl.dutch
Egypt: en.eg
Ethiopia: en.et
Ecuador: en.ec
Estonia: en.ee
Finland: en.finnish
France: en.french
Germany: de.german
Greece: en.greek
Ghana: en.gh
Hong Kong: en.hong_kong
Haiti: en.ht
Hungary: en.hungarian
India: en.indian
Indonesia: en.indonesian
Iran: en.ir
Ireland: en.irish
Italy: it.italian
Israel: en.jewish
Japan: en.japanese
Kuwait: en.kw
Latvia: en.latvian
Liechtenstein: en.li
Lithuania: en.lithuanian
Luxembourg: en.lu
Malaysia: en.malaysia
Mexico: en.mexican
Morocco: en.ma
Mauritius: en.mu
Moldova: en.md
New Zealand: en.new_zealand
Norway: en.norwegian
Philippines: en.philippines
Poland: en.polish
Portugal: en.portuguese
Pakistan: en.pk
Russia: en.russian
Senegal: en.sn
Singapore: en.singapore
South Africa: en.sa
South Korean: en.south_korea
Spain: en.spain
Slovakia: en.slovak
Serbia: en.rs
Slovenia: en.slovenian
Sweden: en.swedish
Taiwan: en.taiwan
Thai: en.th
Turkey: en.turkish
UK: en.uk
US: en.usa
Ukraine: en.ukrainian
Uruguay: en.uy
Vietnam: en.vietnamese
Venezuela: en.ve

View file

@ -0,0 +1,13 @@
#!/bin/bash
#
# packager.io postinstall script config
#
ZAMMAD_DIR="/opt/zammad"
DB="zammad"
DB_USER="zammad"
MY_CNF="/etc/mysql/debian.cnf"
ZAMMAD_WEBS="1"
ZAMMAD_WEBSOCKETS="1"
ZAMMAD_WORKERS="1"
DEBUG_OUTPUT="no"

View file

@ -0,0 +1,201 @@
#!/bin/bash
#
# packager.io postinstall script functions
#
function detect_os () {
. "/etc/os-release"
if [ "${ID}" == "debian" ] || [ "${ID}" == "ubuntu" ]; then
OS="DEBIAN"
elif [ "${ID}" == "centos" ] || [ "${ID}" == "fedora" ] || [ "${ID}" == "rhel" ]; then
OS="REDHAT"
elif [ "${ID}" == "opensuse" ] || [ "${ID}" == "sles" ] || [ "${ID}" == "suse" ]; then
OS="SUSE"
else
OS="UNKNOWN"
fi
if [ "${DEBUG_OUTPUT}" == "yes" ]; then
echo "OS is ${OS} based"
fi
}
function detect_initcmd () {
if [ -n "$(which systemctl 2> /dev/null)" ]; then
INIT_CMD="systemctl"
elif [ -n "$(which initctl 2> /dev/null)" ]; then
INIT_CMD="initctl"
else
function sysvinit () {
service $2 $1
}
INIT_CMD="sysvinit"
fi
if [ "${DEBUG_OUTPUT}" == "yes" ]; then
echo "INIT CMD = ${INIT_CMD}"
fi
}
function detect_database () {
if [ -n "$(which psql 2> /dev/null)" ]; then
ADAPTER="postgresql"
elif [ -n "$(which mysql 2> /dev/null)" ]; then
ADAPTER="mysql2"
fi
if [ "${DEBUG_OUTPUT}" == "yes" ]; then
echo "Use ${ADAPTER} adapter in database.yml"
fi
}
function detect_webserver () {
if [ -n "$(which nginx 2> /dev/null)" ] ; then
WEBSERVER="nginx"
WEBSERVER_CMD="nginx"
if [ "${OS}" == "DEBIAN" ]; then
WEBSERVER_CONF="/etc/nginx/sites-enabled/zammad.conf"
elif [ "${OS}" == "REDHAT" ]; then
WEBSERVER_CONF="/etc/nginx/conf.d/zammad.conf"
elif [ "${OS}" == "SUSE" ]; then
WEBSERVER_CONF="/etc/nginx/vhosts.d/zammad.conf"
fi
elif [ -n "$(which apache2 2> /dev/null)" ]; then
WEBSERVER="apache2"
WEBSERVER_CMD="apache2"
if [ "${OS}" == "DEBIAN" ]; then
WEBSERVER_CONF="/etc/apache2/sites-enabled/zammad.conf"
fi
elif [ -n "$(which httpd 2> /dev/null)" ]; then
WEBSERVER="apache2"
WEBSERVER_CMD="httpd"
if [ "${OS}" == "REDHAT" ]; then
WEBSERVER_CONF="/etc/httpd/conf.d/zammad.conf"
elif [ "${OS}" == "SUSE" ]; then
WEBSERVER_CONF="/etc/apache2/vhosts.d/zammad.conf"
fi
fi
if [ "${DEBUG_OUTPUT}" == "yes" ]; then
echo "Webserver is ${WEBSERVER_CMD}"
fi
}
function create_initscripts () {
echo "# (Re)creating init scripts"
zammad scale web=${ZAMMAD_WEBS} websocket=${ZAMMAD_WEBSOCKETS} worker=${ZAMMAD_WORKERS}
echo "# Enabling Zammad on boot"
${INIT_CMD} enable zammad
}
function start_zammad () {
echo "# Starting Zammad"
${INIT_CMD} start zammad
}
function stop_zammad () {
echo "# Stopping Zammad"
${INIT_CMD} stop zammad
}
function create_database_password () {
DB_PASS="$(tr -dc A-Za-z0-9 < /dev/urandom | head -c10)"
}
function create_postgresql_db () {
if [ -n "$(which postgresql-setup 2> /dev/null)" ]; then
echo "# Preparing postgresql server"
postgresql-setup initdb
fi
echo "# Creating postgresql bootstart"
${INIT_CMD} enable postgresql.service
echo "# Restarting postgresql server"
${INIT_CMD} restart postgresql
echo "# Creating zammad postgresql db"
su - postgres -c "createdb -E UTF8 ${DB}"
echo "# Creating zammad postgresql user"
echo "CREATE USER \"${DB_USER}\" WITH PASSWORD '${DB_PASS}';" | su - postgres -c psql
echo "# Grant privileges to new postgresql user"
echo "GRANT ALL PRIVILEGES ON DATABASE \"${DB}\" TO \"${DB_USER}\";" | su - postgres -c psql
}
function create_mysql_db () {
if [ -f "${MY_CNF}" ]; then
MYSQL_CREDENTIALS="--defaults-file=${MY_CNF}"
else
echo -n "Please enter your MySQL root password:"
read -s MYSQL_ROOT_PASS
MYSQL_CREDENTIALS="-u root -p${MYSQL_ROOT_PASS}"
fi
echo "# Creating zammad mysql db"
mysql ${MYSQL_CREDENTIALS} -e "CREATE DATABASE ${DB} DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;"
echo "# Creating zammad mysql user"
mysql ${MYSQL_CREDENTIALS} -e "CREATE USER \"${DB_USER}\"@\"${DB_HOST}\" IDENTIFIED BY \"${DB_PASS}\";"
echo "# Grant privileges to new mysql user"
mysql ${MYSQL_CREDENTIALS} -e "GRANT ALL PRIVILEGES ON ${DB}.* TO \"${DB_USER}\"@\"${DB_HOST}\"; FLUSH PRIVILEGES;"
}
function update_database_yml () {
if [ "${OS}" == "REDHAT" ] || [ "${OS}" == "SUSE" ]; then
if [ "${ADAPTER}" == "postgresql" ]; then
DB_PASS=""
fi
fi
echo "# Updating database.yml"
sed -e "s/.*adapter:.*/ adapter: ${ADAPTER}/" \
-e "s/.*username:.*/ username: ${DB_USER}/" \
-e "s/.*password:.*/ password: ${DB_PASS}/" \
-e "s/.*database:.*/ database: ${DB}/" < ${ZAMMAD_DIR}/config/database.yml.pkgr > ${ZAMMAD_DIR}/config/database.yml
}
function initialise_database () {
zammad run rake db:migrate
zammad run rake db:seed
}
function update_database () {
echo "# database.yml found. Updating db..."
zammad run rake db:migrate
}
function create_webserver_config () {
if [ "${OS}" == "DEBIAN" ]; then
test -f /etc/${WEBSERVER}/sites-available/zammad.conf || cp ${ZAMMAD_DIR}/contrib/${WEBSERVER}/zammad.conf /etc/${WEBSERVER}/sites-available/zammad.conf
test -h ${WEBSERVER_CONF} || ln -s /etc/${WEBSERVER}/sites-available/zammad.conf ${WEBSERVER_CONF}
else
test -f ${WEBSERVER_CONF} || cp ${ZAMMAD_DIR}/contrib/${WEBSERVER}/zammad.conf ${WEBSERVER_CONF}
fi
echo "# Creating webserver bootstart"
${INIT_CMD} enable ${WEBSERVER_CMD}
echo "# Restarting webserver ${WEBSERVER_CMD}"
${INIT_CMD} restart ${WEBSERVER_CMD}
}
function final_message () {
echo -e "####################################################################################"
echo -e "\nAdd your FQDN to servername directive in ${WEBSERVER_CONF}"
echo -e "and restart your webserver if you're not testing localy"
echo -e "or open http://localhost in your browser to start using Zammad.\n"
if [ "${OS}" == "REDHAT" ]; then
echo -e "\n Remember to enable selinux and firewall rules!\n"
echo -e "Use the follwing commands:"
echo -e " setsebool httpd_can_network_connect on -P"
echo -e " firewall-cmd --zone=public --add-port=80/tcp --permanent"
echo -e " firewall-cmd --zone=public --add-port=443/tcp --permanent"
echo -e " firewall-cmd --reload\n"
fi
echo -e "####################################################################################"
}

View file

@ -5,189 +5,47 @@
PATH=/opt/zammad/bin:/opt/zammad/vendor/bundle/bin:/sbin:/bin:/usr/sbin:/usr/bin: PATH=/opt/zammad/bin:/opt/zammad/vendor/bundle/bin:/sbin:/bin:/usr/sbin:/usr/bin:
ZAMMAD_DIR="/opt/zammad" set -e
DB="zammad_production"
DB_USER="zammad"
MY_CNF="/etc/mysql/debian.cnf"
# check which init system is used # import config
if [ -n "$(which systemctl 2> /dev/null)" ]; then . /opt/zammad/contrib/packager.io/config
INIT_CMD="systemctl"
elif [ -n "$(which initctl 2> /dev/null)" ]; then
INIT_CMD="initctl"
else
function sysvinit () {
service $2 $1
}
INIT_CMD="sysvinit"
fi
echo "# (Re)creating init scripts" # import functions
zammad scale web=1 websocket=1 worker=1 . /opt/zammad/contrib/packager.io/functions
echo "# Enabling Zammad on boot" detect_os
${INIT_CMD} enable zammad
echo "# Stopping Zammad" detect_initcmd
${INIT_CMD} stop zammad
detect_database
detect_webserver
create_initscripts
stop_zammad
# check if database.yml exists # check if database.yml exists
if [ -f ${ZAMMAD_DIR}/config/database.yml ]; then if [ -f ${ZAMMAD_DIR}/config/database.yml ]; then
# db migration update_database
echo "# database.yml found. Updating db..."
zammad run rake db:migrate
else else
echo "# database.yml not found. Creating db..." create_database_password
# create new password if [ "${ADAPTER}" == "postgresql" ]; then
DB_PASS="$(tr -dc A-Za-z0-9 < /dev/urandom | head -c10)"
# postgresql
if [ -n "$(which psql 2> /dev/null)" ]; then
echo "# Installing zammad on postgresql" echo "# Installing zammad on postgresql"
create_postgresql_db
# centos elif [ "${ADAPTER}" == "mysql2" ]; then
if [ -n "$(which postgresql-setup 2> /dev/null)" ]; then
echo "# Preparing postgresql server"
postgresql-setup initdb
echo "# Backuping postgres config"
test -f /var/lib/pgsql/data/pg_hba.conf.bak || cp /var/lib/pgsql/data/pg_hba.conf /var/lib/pgsql/data/pg_hba.conf.bak
echo "# Allow login via username and password in postgresql"
sed 's/ident/trust/g' < /var/lib/pgsql/data/pg_hba.conf.bak > /var/lib/pgsql/data/pg_hba.conf
fi
# centos / ubuntu / sles
echo "# Creating postgresql bootstart"
${INIT_CMD} enable postgresql.service
echo "# Restarting postgresql server"
${INIT_CMD} restart postgresql
echo "# Creating zammad postgresql db"
su - postgres -c "createdb -E UTF8 ${DB}"
echo "# Creating zammad postgresql user"
echo "CREATE USER \"${DB_USER}\" WITH PASSWORD '${DB_PASS}';" | su - postgres -c psql
echo "# Grant privileges to new postgresql user"
echo "GRANT ALL PRIVILEGES ON DATABASE \"${DB}\" TO \"${DB_USER}\";" | su - postgres -c psql
echo "# Updating database.yml"
sed -e "s/.*adapter:.*/ adapter: postgresql/" \
-e "s/.*username:.*/ username: ${DB_USER}/" \
-e "s/.*password:.*/ password: ${DB_PASS}/" \
-e "s/.*database:.*/ database: ${DB}/" < ${ZAMMAD_DIR}/config/database.yml.dist > ${ZAMMAD_DIR}/config/database.yml
# mysql / mariadb
elif [ -n "$(which mysql 2> /dev/null)" ];then
echo "# Installing zammad on mysql" echo "# Installing zammad on mysql"
create_mysql_db
if [ -f "${MY_CNF}" ]; then
MYSQL_CREDENTIALS="--defaults-file=${MY_CNF}"
else
echo -n "Please enter your MySQL root password:"
read -s MYSQL_ROOT_PASS
MYSQL_CREDENTIALS="-u root -p${MYSQL_ROOT_PASS}"
fi fi
echo "# Creating zammad mysql db" update_database_yml
mysql ${MYSQL_CREDENTIALS} -e "CREATE DATABASE ${DB} DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;"
echo "# Creating zammad mysql user" initialise_database
mysql ${MYSQL_CREDENTIALS} -e "CREATE USER \"${DB_USER}\"@\"${DB_HOST}\" IDENTIFIED BY \"${DB_PASS}\";"
echo "# Grant privileges to new mysql user"
mysql ${MYSQL_CREDENTIALS} -e "GRANT ALL PRIVILEGES ON ${DB}.* TO \"${DB_USER}\"@\"${DB_HOST}\"; FLUSH PRIVILEGES;"
echo "# Updating database.yml"
sed -e "s/.*adapter:.*/ adapter: mysql2/" \
-e "s/.*username:.*/ username: ${DB_USER}/" \
-e "s/.*password:.*/ password: ${DB_PASS}/" \
-e "s/.*database:.*/ database: ${DB}/" < ${ZAMMAD_DIR}/config/database.yml.dist > ${ZAMMAD_DIR}/config/database.yml
# sqlite / no local db
elif [ -n "$(which sqlite 2> /dev/null)" ];then
echo "# Installing zammad on sqlite"
echo "# In fact this does nothing at the moment. use this to install zammad without a local database. sqlite should only be used in dev environment anyway."
fi fi
# fill database start_zammad
zammad run rake db:migrate
zammad run rake db:seed
fi create_webserver_config
echo "# Starting Zammad" final_message
${INIT_CMD} start zammad
# on centos, allow nginx to connect to application server
if [ -n "$(which setsebool 2> /dev/null)" ]; then
echo "# Adding SE Linux rules"
setsebool httpd_can_network_connect on -P
fi
# on centos, open port 80 and 443
if [ -n "$(which firewall-cmd 2> /dev/null)" ]; then
echo "# Adding firewall rules"
firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --zone=public --add-port=443/tcp --permanent
firewall-cmd --reload
fi
# copy webserver config
if [ -n "$(which apache2 2> /dev/null)" ] || [ -n "$(which httpd 2> /dev/null)" ] || [ -n "$(which nginx 2> /dev/null)" ] ; then
# Nginx
# debian / ubuntu
if [ -d /etc/nginx/sites-enabled ]; then
WEBSERVER_CONF="/etc/nginx/sites-enabled/zammad.conf"
WEBSERVER_CMD="nginx"
test -f /etc/nginx/sites-available/zammad.conf || cp ${ZAMMAD_DIR}/contrib/nginx/zammad.conf /etc/nginx/sites-available/zammad.conf
test -h ${WEBSERVER_CONF} || ln -s /etc/nginx/sites-available/zammad.conf ${WEBSERVER_CONF}
# centos
elif [ -d /etc/nginx/conf.d ]; then
WEBSERVER_CONF="/etc/nginx/conf.d/zammad.conf"
WEBSERVER_CMD="nginx"
test -f ${WEBSERVER_CONF} || cp ${ZAMMAD_DIR}/contrib/nginx/zammad.conf ${WEBSERVER_CONF}
elif [ -d /etc/YaST2 ]; then
WEBSERVER_CONF="/etc/nginx/vhosts.d/zammad.conf"
WEBSERVER_CMD="nginx"
test -d /etc/nginx/vhosts.d || mkdir -p /etc/nginx/vhosts.d
test -f ${WEBSERVER_CONF} || cp ${ZAMMAD_DIR}/contrib/nginx/zammad.conf ${WEBSERVER_CONF}
# Apache2
# debian / ubuntu
elif [ -d /etc/apache2/sites-enabled ]; then
WEBSERVER_CONF="/etc/apache2/sites-enabled/zammad.conf"
WEBSERVER_CMD="apache2"
test -f /etc/apache2/sites-available/zammad.conf || cp ${ZAMMAD_DIR}/contrib/apache2/zammad.conf /etc/apache2/sites-available/zammad.conf
test -h ${WEBSERVER_CONF} || ln -s /etc/apache2/sites-available/zammad.conf ${WEBSERVER_CONF}
echo "# Activating Apache2 modules"
a2enmod proxy
a2enmod proxy_http
a2enmod proxy_wstunnel
# centos
elif [ -d /etc/httpd/conf.d ]; then
WEBSERVER_CONF="/etc/httpd/conf.d/zammad.conf"
WEBSERVER_CMD="httpd"
test -f ${WEBSERVER_CONF} || cp ${ZAMMAD_DIR}/contrib/apache2/zammad.conf ${WEBSERVER_CONF}
fi
echo "# Creating webserver bootstart"
${INIT_CMD} enable ${WEBSERVER_CMD}
echo "# Restarting webserver ${WEBSERVER_CMD}"
${INIT_CMD} restart ${WEBSERVER_CMD}
echo -e "####################################################################################"
echo -e "\nAdd your FQDN to servername directive in ${WEBSERVER_CONF}"
echo -e "and restart your webserver if you're not testing localy"
echo -e "or open http://localhost in your browser to start using Zammad.\n"
echo -e "####################################################################################"
else
echo -e "####################################################################################"
echo -e "\nOpen http://localhost:3000 in your browser to start using Zammad.\n"
echo -e "####################################################################################"
fi

View file

@ -52,10 +52,14 @@ class FormTest < TestCase
browser: agent, browser: agent,
css: 'body div.zammad-form-modal button[type="submit"]', css: 'body div.zammad-form-modal button[type="submit"]',
) )
exists( watch_for(
browser: agent, browser: agent,
css: 'body div.zammad-form-modal .has-error [name="body"]', css: 'body div.zammad-form-modal .has-error [name="body"]',
) )
watch_for_disappear(
browser: agent,
css: 'body div.zammad-form-modal button[type="submit"][disabled]',
)
set( set(
browser: agent, browser: agent,
css: 'body div.zammad-form-modal [name="body"]', css: 'body div.zammad-form-modal [name="body"]',
@ -70,10 +74,14 @@ class FormTest < TestCase
browser: agent, browser: agent,
css: 'body div.zammad-form-modal button[type="submit"]', css: 'body div.zammad-form-modal button[type="submit"]',
) )
exists( watch_for(
browser: agent, browser: agent,
css: 'body div.zammad-form-modal .has-error [name="email"]', css: 'body div.zammad-form-modal .has-error [name="email"]',
) )
watch_for_disappear(
browser: agent,
css: 'body div.zammad-form-modal button[type="submit"][disabled]',
)
set( set(
browser: agent, browser: agent,
css: 'body div.zammad-form-modal [name="email"]', css: 'body div.zammad-form-modal [name="email"]',
@ -83,10 +91,14 @@ class FormTest < TestCase
browser: agent, browser: agent,
css: 'body div.zammad-form-modal button[type="submit"]', css: 'body div.zammad-form-modal button[type="submit"]',
) )
exists( watch_for(
browser: agent, browser: agent,
css: 'body div.zammad-form-modal .has-error [name="email"]', css: 'body div.zammad-form-modal .has-error [name="email"]',
) )
watch_for_disappear(
browser: agent,
css: 'body div.zammad-form-modal button[type="submit"][disabled]',
)
set( set(
browser: agent, browser: agent,
css: 'body div.zammad-form-modal [name="email"]', css: 'body div.zammad-form-modal [name="email"]',
@ -111,8 +123,7 @@ class FormTest < TestCase
browser: customer, browser: customer,
url: "#{browser_url}/assets/form/form.html", url: "#{browser_url}/assets/form/form.html",
) )
sleep 4 watch_for(
match(
browser: customer, browser: customer,
css: '.js-logDisplay', css: '.js-logDisplay',
value: 'Faild to load form config, feature is disabled', value: 'Faild to load form config, feature is disabled',
@ -143,7 +154,7 @@ class FormTest < TestCase
browser: customer, browser: customer,
css: '#feedback-form-modal', css: '#feedback-form-modal',
) )
exists( watch_for(
browser: customer, browser: customer,
css: 'body div.zammad-form-modal', css: 'body div.zammad-form-modal',
) )
@ -252,10 +263,14 @@ class FormTest < TestCase
browser: customer, browser: customer,
css: 'body div.zammad-form-modal button[type="submit"]', css: 'body div.zammad-form-modal button[type="submit"]',
) )
exists( watch_for(
browser: customer, browser: customer,
css: 'body div.zammad-form-modal .has-error [name="name"]', css: 'body div.zammad-form-modal .has-error [name="name"]',
) )
watch_for_disappear(
browser: customer,
css: 'body div.zammad-form-modal button[type="submit"][disabled]',
)
set( set(
browser: customer, browser: customer,
css: 'body div.zammad-form-modal [name="name"]', css: 'body div.zammad-form-modal [name="name"]',
@ -270,10 +285,14 @@ class FormTest < TestCase
browser: customer, browser: customer,
css: 'body div.zammad-form-modal button[type="submit"]', css: 'body div.zammad-form-modal button[type="submit"]',
) )
exists( watch_for(
browser: customer, browser: customer,
css: 'body div.zammad-form-modal .has-error [name="body"]', css: 'body div.zammad-form-modal .has-error [name="body"]',
) )
watch_for_disappear(
browser: customer,
css: 'body div.zammad-form-modal button[type="submit"][disabled]',
)
set( set(
browser: customer, browser: customer,
css: 'body div.zammad-form-modal [name="body"]', css: 'body div.zammad-form-modal [name="body"]',
@ -288,10 +307,14 @@ class FormTest < TestCase
browser: customer, browser: customer,
css: 'body div.zammad-form-modal button[type="submit"]', css: 'body div.zammad-form-modal button[type="submit"]',
) )
exists( watch_for(
browser: customer, browser: customer,
css: 'body div.zammad-form-modal .has-error [name="email"]', css: 'body div.zammad-form-modal .has-error [name="email"]',
) )
watch_for_disappear(
browser: customer,
css: 'body div.zammad-form-modal button[type="submit"][disabled]',
)
set( set(
browser: customer, browser: customer,
css: 'body div.zammad-form-modal [name="email"]', css: 'body div.zammad-form-modal [name="email"]',
@ -301,10 +324,14 @@ class FormTest < TestCase
browser: customer, browser: customer,
css: 'body div.zammad-form-modal button[type="submit"]', css: 'body div.zammad-form-modal button[type="submit"]',
) )
exists( watch_for(
browser: customer, browser: customer,
css: 'body div.zammad-form-modal .has-error [name="email"]', css: 'body div.zammad-form-modal .has-error [name="email"]',
) )
watch_for_disappear(
browser: customer,
css: 'body div.zammad-form-modal button[type="submit"][disabled]',
)
set( set(
browser: customer, browser: customer,
css: 'body div.zammad-form-modal [name="email"]', css: 'body div.zammad-form-modal [name="email"]',

View file

@ -1240,7 +1240,14 @@ class TestCase < Test::Unit::TestCase
if element #&& element.displayed? if element #&& element.displayed?
begin begin
# watch for selector
if !params[:attribute] && !params[:value]
assert(true, "'#{params[:css]}' found")
sleep 0.5
return true
# match pn attribute # match pn attribute
else
text = if params[:attribute] text = if params[:attribute]
element.attribute(params[:attribute]) element.attribute(params[:attribute])
elsif params[:css] =~ /(input|textarea)/i elsif params[:css] =~ /(input|textarea)/i
@ -1253,6 +1260,7 @@ class TestCase < Test::Unit::TestCase
sleep 0.5 sleep 0.5
return true return true
end end
end
rescue rescue
# try again # try again
end end
@ -1260,7 +1268,10 @@ class TestCase < Test::Unit::TestCase
sleep 0.5 sleep 0.5
} }
screenshot(browser: instance, comment: 'watch_for_failed') screenshot(browser: instance, comment: 'watch_for_failed')
raise "'#{params[:value]}' found in '#{text}'" if !params[:attribute] && !params[:value]
raise "'#{params[:css]}' not found"
end
raise "'#{params[:value]}' not found in '#{text}'"
end end
=begin =begin

View file

@ -548,7 +548,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
assert_equal(result[2][:tickets].class, Array) assert_equal(result[2][:tickets].class, Array)
assert(result[2][:tickets].empty?) assert(result[2][:tickets].empty?)
sleep 1 travel_to Time.zone.now + 1.second # because of mysql millitime issues
ticket3 = Ticket.create( ticket3 = Ticket.create(
title: 'overview test 3', title: 'overview test 3',
group: Group.lookup(name: 'OverviewTest'), group: Group.lookup(name: 'OverviewTest'),
@ -571,6 +571,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
updated_by_id: 1, updated_by_id: 1,
created_by_id: 1, created_by_id: 1,
) )
travel_back
result = Ticket::Overviews.index(agent1) result = Ticket::Overviews.index(agent1)
assert_equal(result[0][:overview][:id], overview1.id) assert_equal(result[0][:overview][:id], overview1.id)