refactored postinstall.sh
This commit is contained in:
parent
abe5a9cc8b
commit
7a8559e678
40 changed files with 764 additions and 440 deletions
|
@ -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
2
.csslintrc
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
--exclude-exts=.min.css
|
||||||
|
--ignore=adjoining-classes,box-model,ids,order-alphabetical,unqualified-attributes
|
1
.eslintignore
Normal file
1
.eslintignore
Normal file
|
@ -0,0 +1 @@
|
||||||
|
**/*{.,-}min.js
|
213
.eslintrc
Normal file
213
.eslintrc
Normal 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
|
|
@ -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
|
||||||
|
|
33
.travis.yml
33
.travis.yml
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 = [
|
||||||
|
|
|
@ -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': %>
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% if item.navheader: %>
|
<% if item.navheader: %>
|
||||||
<li class="dropdown-header"><%- @T( item.navheader ) %></li>
|
<li class="dropdown-header"><%- @T(item.navheader) %></li>
|
||||||
<% end %>
|
<% end %>
|
||||||
<li>
|
<li>
|
||||||
<a href="<%= item.target %>" class="horizontal center">
|
<a href="<%= item.target %>" class="horizontal center">
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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!
|
||||||
|
|
|
@ -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}')
|
||||||
|
|
|
@ -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})"
|
||||||
|
|
|
@ -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})"
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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!
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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') || ''
|
||||||
|
|
|
@ -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') || ''
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
11
config/database.yml.test-mysql
Normal file
11
config/database.yml.test-mysql
Normal 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
|
11
config/database.yml.test-postgresql
Normal file
11
config/database.yml.test-postgresql
Normal 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:
|
78
config/holiday_calendars.yml
Normal file
78
config/holiday_calendars.yml
Normal 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
|
13
contrib/packager.io/config
Normal file
13
contrib/packager.io/config
Normal 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"
|
201
contrib/packager.io/functions
Normal file
201
contrib/packager.io/functions
Normal 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 "####################################################################################"
|
||||||
|
}
|
|
@ -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 "# Installing zammad on mysql"
|
||||||
echo "# Preparing postgresql server"
|
create_mysql_db
|
||||||
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"
|
|
||||||
|
|
||||||
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;"
|
|
||||||
|
|
||||||
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
|
update_database_yml
|
||||||
zammad run rake db:migrate
|
|
||||||
zammad run rake db:seed
|
|
||||||
|
|
||||||
|
initialise_database
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "# Starting Zammad"
|
start_zammad
|
||||||
${INIT_CMD} start zammad
|
|
||||||
|
|
||||||
# on centos, allow nginx to connect to application server
|
create_webserver_config
|
||||||
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
|
final_message
|
||||||
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
|
|
||||||
|
|
|
@ -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"]',
|
||||||
|
|
|
@ -1240,18 +1240,26 @@ class TestCase < Test::Unit::TestCase
|
||||||
if element #&& element.displayed?
|
if element #&& element.displayed?
|
||||||
begin
|
begin
|
||||||
|
|
||||||
# match pn attribute
|
# watch for selector
|
||||||
text = if params[:attribute]
|
if !params[:attribute] && !params[:value]
|
||||||
element.attribute(params[:attribute])
|
assert(true, "'#{params[:css]}' found")
|
||||||
elsif params[:css] =~ /(input|textarea)/i
|
|
||||||
element.attribute('value')
|
|
||||||
else
|
|
||||||
element.text
|
|
||||||
end
|
|
||||||
if text =~ /#{params[:value]}/i
|
|
||||||
assert(true, "'#{params[:value]}' found in '#{text}'")
|
|
||||||
sleep 0.5
|
sleep 0.5
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
# match pn attribute
|
||||||
|
else
|
||||||
|
text = if params[:attribute]
|
||||||
|
element.attribute(params[:attribute])
|
||||||
|
elsif params[:css] =~ /(input|textarea)/i
|
||||||
|
element.attribute('value')
|
||||||
|
else
|
||||||
|
element.text
|
||||||
|
end
|
||||||
|
if text =~ /#{params[:value]}/i
|
||||||
|
assert(true, "'#{params[:value]}' found in '#{text}'")
|
||||||
|
sleep 0.5
|
||||||
|
return true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
rescue
|
rescue
|
||||||
# try again
|
# try again
|
||||||
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue