Revision 1297:0a574315af3e .svn/pristine/99

View differences:

.svn/pristine/99/99427a60ba43ee192719046d5e81ce5c2ae0e96f.svn-base
1
# Redmine - project management software
2
# Copyright (C) 2006-2012  Jean-Philippe Lang
3
#
4
# FileSystem adapter
5
# File written by Paul Rivier, at Demotera.
6
#
7
# This program is free software; you can redistribute it and/or
8
# modify it under the terms of the GNU General Public License
9
# as published by the Free Software Foundation; either version 2
10
# of the License, or (at your option) any later version.
11
#
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with this program; if not, write to the Free Software
19
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20

  
21
require 'redmine/scm/adapters/abstract_adapter'
22
require 'find'
23

  
24
module Redmine
25
  module Scm
26
    module Adapters
27
      class FilesystemAdapter < AbstractAdapter
28

  
29
        class << self
30
          def client_available
31
            true
32
          end
33
        end
34

  
35
        def initialize(url, root_url=nil, login=nil, password=nil,
36
                       path_encoding=nil)
37
          @url = with_trailling_slash(url)
38
          @path_encoding = path_encoding.blank? ? 'UTF-8' : path_encoding
39
        end
40

  
41
        def path_encoding
42
          @path_encoding
43
        end
44

  
45
        def format_path_ends(path, leading=true, trailling=true)
46
          path = leading ? with_leading_slash(path) :
47
            without_leading_slash(path)
48
          trailling ? with_trailling_slash(path) :
49
            without_trailling_slash(path)
50
        end
51

  
52
        def info
53
          info = Info.new({:root_url => target(),
54
                            :lastrev => nil
55
                          })
56
          info
57
        rescue CommandFailed
58
          return nil
59
        end
60

  
61
        def entries(path="", identifier=nil, options={})
62
          entries = Entries.new
63
          trgt_utf8 = target(path)
64
          trgt = scm_iconv(@path_encoding, 'UTF-8', trgt_utf8)
65
          Dir.new(trgt).each do |e1|
66
            e_utf8 = scm_iconv('UTF-8', @path_encoding, e1)
67
            next if e_utf8.blank?
68
            relative_path_utf8 = format_path_ends(
69
                (format_path_ends(path,false,true) + e_utf8),false,false)
70
            t1_utf8 = target(relative_path_utf8)
71
            t1 = scm_iconv(@path_encoding, 'UTF-8', t1_utf8)
72
            relative_path = scm_iconv(@path_encoding, 'UTF-8', relative_path_utf8)
73
            e1 = scm_iconv(@path_encoding, 'UTF-8', e_utf8)
74
            if File.exist?(t1) and # paranoid test
75
                  %w{file directory}.include?(File.ftype(t1)) and # avoid special types
76
                  not File.basename(e1).match(/^\.+$/) # avoid . and ..
77
              p1         = File.readable?(t1) ? relative_path : ""
78
              utf_8_path = scm_iconv('UTF-8', @path_encoding, p1)
79
              entries <<
80
                Entry.new({ :name => scm_iconv('UTF-8', @path_encoding, File.basename(e1)),
81
                          # below : list unreadable files, but dont link them.
82
                          :path => utf_8_path,
83
                          :kind => (File.directory?(t1) ? 'dir' : 'file'),
84
                          :size => (File.directory?(t1) ? nil : [File.size(t1)].pack('l').unpack('L').first),
85
                          :lastrev =>
86
                              Revision.new({:time => (File.mtime(t1)) })
87
                        })
88
            end
89
          end
90
          entries.sort_by_name
91
        rescue  => err
92
          logger.error "scm: filesystem: error: #{err.message}"
93
          raise CommandFailed.new(err.message)
94
        end
95

  
96
        def cat(path, identifier=nil)
97
          p = scm_iconv(@path_encoding, 'UTF-8', target(path))
98
          File.new(p, "rb").read
99
        rescue  => err
100
          logger.error "scm: filesystem: error: #{err.message}"
101
          raise CommandFailed.new(err.message)
102
        end
103

  
104
        private
105

  
106
        # AbstractAdapter::target is implicitly made to quote paths.
107
        # Here we do not shell-out, so we do not want quotes.
108
        def target(path=nil)
109
          # Prevent the use of ..
110
          if path and !path.match(/(^|\/)\.\.(\/|$)/)
111
            return "#{self.url}#{without_leading_slash(path)}"
112
          end
113
          return self.url
114
        end
115
      end
116
    end
117
  end
118
end
.svn/pristine/99/997184000368211e968189a862af8cf1d5978fee.svn-base
1
<%= error_messages_for 'time_entry' %>
2
<%= back_url_hidden_field_tag %>
3

  
4
<div class="box tabular">
5
	<% if @time_entry.new_record? %>
6
	  <% if params[:project_id] || @time_entry.issue %>
7
	    <%= f.hidden_field :project_id %>
8
	  <% else %>
9
	    <p><%= f.select :project_id, project_tree_options_for_select(Project.allowed_to(:log_time).all, :selected => @time_entry.project), :required => true %></p>
10
	  <% end %>
11
	<% end %>
12
	<p><%= f.text_field :issue_id, :size => 6 %> <em><%= h("#{@time_entry.issue.tracker.name} ##{@time_entry.issue.id}: #{@time_entry.issue.subject}") if @time_entry.issue %></em></p>
13
	<p><%= f.text_field :spent_on, :size => 10, :required => true %><%= calendar_for('time_entry_spent_on') %></p>
14
	<p><%= f.text_field :hours, :size => 6, :required => true %></p>
15
	<p><%= f.text_field :comments, :size => 100 %></p>
16
	<p><%= f.select :activity_id, activity_collection_for_select_options(@time_entry), :required => true %></p>
17
	<% @time_entry.custom_field_values.each do |value| %>
18
	  <p><%= custom_field_tag_with_label :time_entry, value %></p>
19
	<% end %>
20
	<%= call_hook(:view_timelog_edit_form_bottom, { :time_entry => @time_entry, :form => f }) %>
21
</div>
22

  
23
<%= javascript_tag "observeAutocompleteField('time_entry_issue_id', '#{escape_javascript auto_complete_issues_path(:project_id => @project, :scope => (@project ? nil : 'all'))}')" %>
.svn/pristine/99/998dc4f658daf9b604937796605070d71a9c3bd4.svn-base
1
# Redmine - project management software
2
# Copyright (C) 2006-2012  Jean-Philippe Lang
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17

  
18
class TimeEntryActivity < Enumeration
19
  has_many :time_entries, :foreign_key => 'activity_id'
20

  
21
  OptionName = :enumeration_activities
22

  
23
  def option_name
24
    OptionName
25
  end
26

  
27
  def objects_count
28
    time_entries.count
29
  end
30

  
31
  def transfer_relations(to)
32
    time_entries.update_all("activity_id = #{to.id}")
33
  end
34
end
.svn/pristine/99/999fdff2052b71cf3f29b97c581e2f895bcdf162.svn-base
1
require 'SVG/Graph/Plot'
2

  
3
module SVG
4
  module Graph
5
    # === For creating SVG plots of scalar temporal data
6
    # 
7
    # = Synopsis
8
    # 
9
    #   require 'SVG/Graph/TimeSeriess'
10
    # 
11
    #   # Data sets are x,y pairs
12
    #   data1 = ["6/17/72", 11,    "1/11/72", 7,    "4/13/04 17:31", 11, 
13
    #           "9/11/01", 9,    "9/1/85", 2,    "9/1/88", 1,    "1/15/95", 13]
14
    #   data2 = ["8/1/73", 18,    "3/1/77", 15,    "10/1/98", 4, 
15
    #           "5/1/02", 14,    "3/1/95", 6,    "8/1/91", 12,    "12/1/87", 6, 
16
    #           "5/1/84", 17,    "10/1/80", 12]
17
    #
18
    #   graph = SVG::Graph::TimeSeries.new( {
19
    #     :width => 640,
20
    #     :height => 480,
21
    #     :graph_title => title,
22
    #     :show_graph_title => true,
23
    #     :no_css => true,
24
    #     :key => true,
25
    #     :scale_x_integers => true,
26
    #     :scale_y_integers => true,
27
    #     :min_x_value => 0,
28
    #     :min_y_value => 0,
29
    #     :show_data_labels => true,
30
    #     :show_x_guidelines => true,
31
    #     :show_x_title => true,
32
    #     :x_title => "Time",
33
    #     :show_y_title => true,
34
    #     :y_title => "Ice Cream Cones",
35
    #     :y_title_text_direction => :bt,
36
    #     :stagger_x_labels => true,
37
    #     :x_label_format => "%m/%d/%y",
38
    #   })
39
    #   
40
    #   graph.add_data({
41
    #   	:data => projection
42
    # 	  :title => 'Projected',
43
    #   })
44
    # 
45
    #   graph.add_data({
46
    #   	:data => actual,
47
    # 	  :title => 'Actual',
48
    #   })
49
    #   
50
    #   print graph.burn()
51
    #
52
    # = Description
53
    # 
54
    # Produces a graph of temporal scalar data.
55
    # 
56
    # = Examples
57
    #
58
    # http://www.germane-software/repositories/public/SVG/test/timeseries.rb
59
    # 
60
    # = Notes
61
    # 
62
    # The default stylesheet handles upto 10 data sets, if you
63
    # use more you must create your own stylesheet and add the
64
    # additional settings for the extra data sets. You will know
65
    # if you go over 10 data sets as they will have no style and
66
    # be in black.
67
    #
68
    # Unlike the other types of charts, data sets must contain x,y pairs:
69
    #
70
    #   [ "12:30", 2 ]          # A data set with 1 point: ("12:30",2)
71
    #   [ "01:00",2, "14:20",6] # A data set with 2 points: ("01:00",2) and 
72
    #                           #                           ("14:20",6)  
73
    #
74
    # Note that multiple data sets within the same chart can differ in length, 
75
    # and that the data in the datasets needn't be in order; they will be ordered
76
    # by the plot along the X-axis.
77
    # 
78
    # The dates must be parseable by ParseDate, but otherwise can be
79
    # any order of magnitude (seconds within the hour, or years)
80
    # 
81
    # = See also
82
    # 
83
    # * SVG::Graph::Graph
84
    # * SVG::Graph::BarHorizontal
85
    # * SVG::Graph::Bar
86
    # * SVG::Graph::Line
87
    # * SVG::Graph::Pie
88
    # * SVG::Graph::Plot
89
    #
90
    # == Author
91
    #
92
    # Sean E. Russell <serATgermaneHYPHENsoftwareDOTcom>
93
    #
94
    # Copyright 2004 Sean E. Russell
95
    # This software is available under the Ruby license[LICENSE.txt]
96
    #
97
    class TimeSeries < Plot
98
      # In addition to the defaults set by Graph::initialize and
99
      # Plot::set_defaults, sets:
100
      # [x_label_format] '%Y-%m-%d %H:%M:%S'
101
      # [popup_format]  '%Y-%m-%d %H:%M:%S'
102
      def set_defaults
103
        super
104
        init_with(
105
          #:max_time_span     => '',
106
          :x_label_format     => '%Y-%m-%d %H:%M:%S',
107
          :popup_format       => '%Y-%m-%d %H:%M:%S'
108
        )
109
      end
110

  
111
      # The format string use do format the X axis labels.
112
      # See Time::strformat
113
      attr_accessor :x_label_format
114
      # Use this to set the spacing between dates on the axis.  The value
115
      # must be of the form 
116
      # "\d+ ?(days|weeks|months|years|hours|minutes|seconds)?"
117
      # 
118
      # EG:
119
      #
120
      #   graph.timescale_divisions = "2 weeks"
121
      #
122
      # will cause the chart to try to divide the X axis up into segments of
123
      # two week periods.
124
      attr_accessor :timescale_divisions
125
      # The formatting used for the popups.  See x_label_format
126
      attr_accessor :popup_format
127

  
128
      # Add data to the plot.
129
      #
130
      #   d1 = [ "12:30", 2 ]          # A data set with 1 point: ("12:30",2)
131
      #   d2 = [ "01:00",2, "14:20",6] # A data set with 2 points: ("01:00",2) and 
132
      #                                #                           ("14:20",6)  
133
      #   graph.add_data( 
134
      #     :data => d1,
135
      #     :title => 'One'
136
      #   )
137
      #   graph.add_data(
138
      #     :data => d2,
139
      #     :title => 'Two'
140
      #   )
141
      #
142
      # Note that the data must be in time,value pairs, and that the date format
143
      # may be any date that is parseable by ParseDate.
144
      def add_data data
145
        @data = [] unless @data
146
       
147
        raise "No data provided by #{@data.inspect}" unless data[:data] and
148
                                                    data[:data].kind_of? Array
149
        raise "Data supplied must be x,y pairs!  "+
150
          "The data provided contained an odd set of "+
151
          "data points" unless data[:data].length % 2 == 0
152
        return if data[:data].length == 0
153

  
154

  
155
        x = []
156
        y = []
157
        data[:data].each_index {|i|
158
          if i%2 == 0
159
            t = DateTime.parse( data[:data][i] ).to_time
160
            x << t.to_i
161
          else
162
            y << data[:data][i]
163
          end
164
        }
165
        sort( x, y )
166
        data[:data] = [x,y]
167
        @data << data
168
      end
169

  
170

  
171
      protected
172

  
173
      def min_x_value=(value)
174
        @min_x_value = DateTime.parse( value ).to_time
175
      end
176

  
177

  
178
      def format x, y
179
        Time.at( x ).strftime( popup_format )
180
      end
181

  
182
      def get_x_labels
183
        get_x_values.collect { |v| Time.at(v).strftime( x_label_format ) }
184
      end
185
      
186
      private
187
      def get_x_values
188
        rv = []
189
        min, max, scale_division = x_range
190
        if timescale_divisions
191
          timescale_divisions =~ /(\d+) ?(day|week|month|year|hour|minute|second)?/
192
          division_units = $2 ? $2 : "day"
193
          amount = $1.to_i
194
          if amount
195
            step =  nil
196
            case division_units
197
            when "month"
198
              cur = min
199
              while cur < max
200
                rv << cur
201
                arr = Time.at( cur ).to_a
202
                arr[4] += amount
203
                if arr[4] > 12
204
                  arr[5] += (arr[4] / 12).to_i
205
                  arr[4] = (arr[4] % 12)
206
                end
207
                cur = Time.local(*arr).to_i
208
              end
209
            when "year"
210
              cur = min
211
              while cur < max
212
                rv << cur
213
                arr = Time.at( cur ).to_a
214
                arr[5] += amount
215
                cur = Time.local(*arr).to_i
216
              end
217
            when "week"
218
              step = 7 * 24 * 60 * 60 * amount
219
            when "day"
220
              step = 24 * 60 * 60 * amount
221
            when "hour"
222
              step = 60 * 60 * amount
223
            when "minute"
224
              step = 60 * amount
225
            when "second"
226
              step = amount
227
            end
228
            min.step( max, step ) {|v| rv << v} if step
229

  
230
            return rv
231
          end
232
        end
233
        min.step( max, scale_division ) {|v| rv << v}
234
        return rv
235
      end
236
    end
237
  end
238
end
.svn/pristine/99/99e2701a14c4f2125c8873be0b1ded74098d370b.svn-base
1
#!/usr/bin/env ruby
2

  
3
require File.dirname(__FILE__) + '/../config/boot'
4
require File.dirname(__FILE__) + '/../config/environment'
5

  
6
class Rack::PathInfoRewriter
7
  def initialize(app)
8
    @app = app
9
  end
10

  
11
  def call(env)
12
    env.delete('SCRIPT_NAME')
13
    parts = env['REQUEST_URI'].split('?')
14
    env['PATH_INFO'] = parts[0]
15
    env['QUERY_STRING'] = parts[1].to_s
16
    @app.call(env)
17
  end
18
end
19

  
20
Rack::Handler::FastCGI.run Rack::PathInfoRewriter.new(RedmineApp::Application)
.svn/pristine/99/99facf87c9773fe164f63d4ddf92909973ba997e.svn-base
1
<%= error_messages_for 'query' %>
2

  
3
<div class="box">
4
<div class="tabular">
5
<p><label for="query_name"><%=l(:field_name)%></label>
6
<%= text_field 'query', 'name', :size => 80 %></p>
7

  
8
<% if User.current.admin? || User.current.allowed_to?(:manage_public_queries, @project) %>
9
<p><label for="query_is_public"><%=l(:field_is_public)%></label>
10
<%= check_box 'query', 'is_public',
11
      :onchange => (User.current.admin? ? nil : 'if (this.checked) {$("#query_is_for_all").removeAttr("checked"); $("#query_is_for_all").attr("disabled", true);} else {$("#query_is_for_all").removeAttr("disabled");}') %></p>
12
<% end %>
13

  
14
<p><label for="query_is_for_all"><%=l(:field_is_for_all)%></label>
15
<%= check_box_tag 'query_is_for_all', 1, @query.project.nil?,
16
      :disabled => (!@query.new_record? && (@query.project.nil? || (@query.is_public? && !User.current.admin?))) %></p>
17

  
18
<p><label for="query_default_columns"><%=l(:label_default_columns)%></label>
19
<%= check_box_tag 'default_columns', 1, @query.has_default_columns?, :id => 'query_default_columns',
20
      :onclick => 'if (this.checked) {$("#columns").hide();} else {$("#columns").show();}' %></p>
21

  
22
<p><label for="query_group_by"><%= l(:field_group_by) %></label>
23
<%= select 'query', 'group_by', @query.groupable_columns.collect {|c| [c.caption, c.name.to_s]}, :include_blank => true %></p>
24

  
25
<p><label><%= l(:button_show) %></label>
26
<%= available_block_columns_tags(@query) %></p>
27
</div>
28

  
29
<fieldset id="filters"><legend><%= l(:label_filter_plural) %></legend>
30
<%= render :partial => 'queries/filters', :locals => {:query => query}%>
31
</fieldset>
32

  
33
<fieldset><legend><%= l(:label_sort) %></legend>
34
<% 3.times do |i| %>
35
<%= i+1 %>: 
36
<%= label_tag "query_sort_criteria_attribute_" + i.to_s,
37
              l(:description_query_sort_criteria_attribute), :class => "hidden-for-sighted" %>
38
<%= select_tag("query[sort_criteria][#{i}][]",
39
               options_for_select([[]] + query.available_columns.select(&:sortable?).collect {|column| [column.caption, column.name.to_s]}, @query.sort_criteria_key(i)),
40
               :id => "query_sort_criteria_attribute_" + i.to_s)%>
41
<%= label_tag "query_sort_criteria_direction_" + i.to_s,
42
              l(:description_query_sort_criteria_direction), :class => "hidden-for-sighted" %>
43
<%= select_tag("query[sort_criteria][#{i}][]",
44
                options_for_select([[], [l(:label_ascending), 'asc'], [l(:label_descending), 'desc']], @query.sort_criteria_order(i)),
45
                :id => "query_sort_criteria_direction_" + i.to_s) %>
46
<br />
47
<% end %>
48
</fieldset>
49

  
50
<%= content_tag 'fieldset', :id => 'columns', :style => (query.has_default_columns? ? 'display:none;' : nil) do %>
51
<legend><%= l(:field_column_names) %></legend>
52
<%= render :partial => 'queries/columns', :locals => {:query => query}%>
53
<% end %>
54

  
55
</div>

Also available in: Unified diff