redsync 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2aa4de80baafdcadc5c491f40027c3f8e82be33a
4
+ data.tar.gz: 30a6132b64547025e55dd3c9af86b4b526de9cd3
5
+ SHA512:
6
+ metadata.gz: 8028468044e10c025ec1782cdc240b2266e8a996fd33831eb2211f4ac384647ba643628570045b7c46c439f7d985dae83827e8ea87d21a36ad9f0d77e5c6ce8d
7
+ data.tar.gz: 4aba4790ed8efb2429fa5b29b6d774dad038460bd78e8003b01a7986e0063b40c65de1ef49ad6fc4830559347981ee4cd67676a13178206f797e735664b5c5a9
@@ -4,7 +4,7 @@ h2. What's this?
4
4
 
5
5
  Sync your Redmine's wiki contents to your local filesystem.
6
6
  Edit them while offline, then upsync them to Redmine.
7
- (Requires Ruby 1.9)
7
+ (Requires Ruby 2.0)
8
8
 
9
9
  h2. Install
10
10
 
@@ -16,12 +16,11 @@ gem install redsync
16
16
  h2. Usage
17
17
 
18
18
  <pre>
19
- $ redsync --help
20
19
  Usage: redsync [options]
21
- -v, --[no-]verbose Output verbose logs
20
+ -v, --verbose Output verbose logs
22
21
  -c, --config FILE Use specified config file instead of ~/redsync.yml
23
- -u, --upsync-only Upsync only, don't downsync
24
- -d, --downsync-only Downsync only, don't upsync
22
+ -s, --status Status check. No uploads or downloads will happen
23
+ -i, --interactive Interactive mode (pry)
25
24
  </pre>
26
25
 
27
26
 
@@ -36,11 +35,6 @@ This software has NOT BEEN TESTED :(
36
35
  Use it at your own risk.
37
36
  Please beware that it may not work on all versions of Redmine (it's working fine with my installation of 1.2-stable)
38
37
 
39
- h3. Time zones
40
-
41
- Redsync assumes that your local timezone is the same as your Redmine timezone.
42
- Sign in and go to "My Account" to change it.
43
-
44
38
  h3. Conflicts
45
39
 
46
40
  Redsync does not deal with conflicts well.
@@ -48,12 +42,6 @@ In fact, it does not deal with conflics AT ALL.
48
42
  A default run of redsync will downsync first, overwriting any local changes if pages are updated on Redmine.
49
43
  Then it will upsync any remaining changes.
50
44
 
51
- h3. Deletions
52
-
53
- Redsy does not delete anything.
54
- It doesn't delete local files when remote wiki pages are gone.
55
- It doesn't delete remote wiki pages when local files are gone either.
56
-
57
45
 
58
46
  h2. License
59
47
 
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
  # -*- vim: filetype=ruby
3
3
 
4
- if RUBY_VERSION < '1.9'
5
- puts "Redsync requires Ruby >= 1.9.0"
4
+ if RUBY_VERSION < '2.0'
5
+ puts "Redsync requires Ruby >= 2.0"
6
6
  exit
7
7
  end
8
8
 
@@ -1,8 +1,7 @@
1
1
  ---
2
- :url: "http://your.redmine.url/"
2
+ :url: "http://your.redmine.url/"
3
3
  :projects:
4
4
  - "project_one"
5
5
  - "project_two"
6
- :username: "username"
7
- :password: "password"
6
+ :api_key: "your_redmine_api_key"
8
7
  :data_dir: "~/redsync"
@@ -1,18 +1,13 @@
1
1
  # encoding:UTF-8
2
2
 
3
- require 'rubygems'
4
3
  require 'fileutils'
5
4
  require 'uri'
6
5
  require 'yaml'
7
- require 'date'
8
- require 'iconv'
9
6
  require 'mechanize'
10
- require 'active_support/all'
11
- require 'ir_b'
7
+ require 'pry'
12
8
 
13
9
  require 'redsync/cli'
14
- require 'redsync/wiki'
15
- require 'redsync/wiki_page'
10
+ require 'redsync/project'
16
11
 
17
12
 
18
13
  class Redsync
@@ -32,101 +27,35 @@ class Redsync
32
27
  # :data_dir => Directory to read/write. Required.
33
28
  # :extension => Filename extensions. Defaults to "txt"
34
29
  def initialize(options)
35
- options = {
36
- :extension => "txt",
37
- }.merge(options)
38
-
39
- @url = options[:url].match(/(.*?)\/?$/)[1]
40
- @projects = options[:projects]
41
- @username = options[:username]
42
- @password = options[:password]
43
- @data_dir = File.expand_path(options[:data_dir])
44
- @extension = options[:extension]
45
-
46
- @login_url = @url + "/login"
47
-
48
- initialize_system_files
49
-
50
- @agent = Mechanize.new
51
- end
52
-
53
-
54
- def initialize_system_files
55
- if File.exist? @data_dir
56
- puts "Using data dir: #{@data_dir}"
57
- else
58
- puts "Creating #{@data_dir}"
59
- FileUtils.mkdir(@data_dir)
30
+ @projects = options[:projects].map do |pj|
31
+ Project.new(
32
+ :url => options[:url].sub(/^(.*?)\/?$/, '\1') + "/projects/#{pj}/wiki",
33
+ :api_key => options[:api_key],
34
+ :data_dir => File.join(options[:data_dir], pj),
35
+ :extension => options[:extension]
36
+ )
60
37
  end
61
- end
62
38
 
63
-
64
- def login
65
- puts "Logging in as #{@username} to #{@login_url}..."
66
- page = @agent.get(@login_url)
67
- login_form = page.form_with(:action => "/login")
68
- login_form.field_with(:name => "username").value = @username
69
- login_form.field_with(:name => "password").value = @password
70
- result_page = login_form.submit
71
- if result_page.search("a.logout").any?
72
- puts "Logged in successfully."
73
- instantiate_wikis
74
- return true
75
- else
76
- puts "Login failed."
77
- return false
78
- end
79
- end
80
-
81
-
82
- def instantiate_wikis
83
- @wikis = @projects.inject({}) do |sum, project_identifier|
84
- sum[project_identifier] = Wiki.new({
85
- :url => @url + "/projects/" + project_identifier + "/wiki",
86
- :cookies => @agent.cookie_jar.cookies(URI.parse(@url)),
87
- :data_dir => File.join(@data_dir, project_identifier),
88
- :extension => @extension
89
- })
90
- sum
91
- end
39
+ @agent = Mechanize.new
92
40
  end
93
41
 
94
42
 
95
43
  def status_check
96
- @projects.each do |project_identifier|
97
- wiki = @wikis[project_identifier]
98
- wiki.load_pages_cache
99
- wiki.scan
100
-
101
- puts "#{wiki.pages_to_download.length} pages to download"
102
- puts "#{wiki.pages_to_create.length} pages to create"
103
- puts "#{wiki.pages_to_upload.length} pages to upload"
44
+ @projects.each do |pj|
45
+ pj.status_check
104
46
  end
105
47
  end
106
48
 
107
49
 
108
50
  def sync_all
109
- @projects.each do |project_identifier|
110
- sync(project_identifier)
51
+ @projects.each do |pj|
52
+ pj.sync
111
53
  end
112
54
  end
113
55
 
114
56
 
115
- def sync(project_identifier)
116
- wiki = @wikis[project_identifier]
117
- wiki.load_pages_cache
118
- wiki.scan
119
- wiki.downsync
120
- wiki.upsync
121
- end
122
-
123
-
124
57
  def interactive
125
- wikis.each do |project_identifier, wiki|
126
- wiki.load_pages_cache
127
- wiki.scan
128
- end
129
- ir b
58
+ binding.pry
130
59
  end
131
60
 
132
61
 
@@ -11,7 +11,6 @@ class Redsync
11
11
  check_config_file
12
12
 
13
13
  redsync = Redsync.new(YAML.load_file(@options.delete(:config_file)).merge(@options))
14
- exit unless redsync.login
15
14
 
16
15
  case @options[:run_mode]
17
16
  when :full_sync
@@ -43,12 +42,9 @@ class Redsync
43
42
  opts.on("-s", "--status", "Status check. No uploads or downloads will happen") do |v|
44
43
  @options[:run_mode] = :status_check
45
44
  end
46
- opts.on("-i", "--interactive", "Interactive mode (irb)") do |v|
45
+ opts.on("-i", "--interactive", "Interactive mode (pry)") do |v|
47
46
  @options[:run_mode] = :interactive
48
47
  end
49
- opts.on("-D", "--debugger", "Debug mode. Requires ruby-debug19") do |v|
50
- @options[:debug] = v
51
- end
52
48
  end.parse!
53
49
 
54
50
  if @options[:debug]
@@ -0,0 +1,53 @@
1
+ class Redsync
2
+ class LocalWiki
3
+
4
+ def initialize(options)
5
+ @data_dir = options[:data_dir]
6
+ @extension = options[:extension]
7
+ end
8
+
9
+
10
+ def list
11
+ unless @pages
12
+ @pages = {}
13
+ Dir["#{@data_dir}/**/*.#{@extension}"].each do |file|
14
+ name = File.basename(file, "." + @extension)
15
+ name = name.encode("UTF-8", "UTF-8-MAC", :invalid => :replace, :undef => :replace) if RUBY_PLATFORM =~ /darwin/
16
+ @pages[name] = WikiPage.new(
17
+ :name => name,
18
+ :mtime => File.mtime(file)
19
+ )
20
+ end
21
+ end
22
+
23
+ @pages.values
24
+ end
25
+
26
+
27
+ def get(name)
28
+ list unless @pages
29
+
30
+ return nil if @pages[name].nil?
31
+
32
+ unless @pages[name].content
33
+ @pages[name].content = File.read(path_for(name))
34
+ end
35
+
36
+ @pages[name]
37
+ end
38
+
39
+
40
+ def write(name, content)
41
+ File.open(path_for(name), "w+:UTF-8") do |f|
42
+ f.write(content)
43
+ end
44
+ end
45
+
46
+
47
+ def path_for(name)
48
+ name = name.encode("UTF-8-MAC", "UTF-8", :invalid => :replace, :undef => :replace) if RUBY_PLATFORM =~ /darwin/
49
+ File.join(@data_dir, name + "." + @extension)
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,139 @@
1
+ require 'yaml'
2
+ require 'fileutils'
3
+ require 'redsync/local_wiki'
4
+ require 'redsync/remote_wiki'
5
+ require 'redsync/wiki_page'
6
+
7
+ class Redsync
8
+ class Project
9
+
10
+ def initialize(options)
11
+ @url = options[:url]
12
+ @api_key = options[:api_key]
13
+ @data_dir = File.expand_path(options[:data_dir])
14
+ @extension = options[:extension] || "txt"
15
+
16
+ initialize_system_files
17
+
18
+ @syncstat = {}
19
+ @syncdone = {}
20
+ @syncstat_file = File.join(@data_dir, "__redsync_syncstat.yml")
21
+ load_syncstat
22
+
23
+ @remote_wiki = RemoteWiki.new(url: @url, api_key: @api_key)
24
+ @local_wiki = LocalWiki.new(data_dir: @data_dir, extension: @extension)
25
+ end
26
+
27
+
28
+ def initialize_system_files
29
+ unless File.exist? @data_dir
30
+ puts "Creating #{@data_dir}"
31
+ FileUtils.mkdir_p(@data_dir)
32
+ end
33
+ end
34
+
35
+
36
+ def load_syncstat
37
+ @syncstat = {}
38
+ @syncdone = {}
39
+ return unless File.exist? @syncstat_file
40
+ @syncstat = YAML.load_file(@syncstat_file)
41
+ end
42
+
43
+
44
+ def save_syncstat
45
+ File.open(@syncstat_file, "w+:UTF-8") do |f|
46
+ f.write(@syncstat.to_yaml)
47
+ end
48
+ end
49
+
50
+
51
+ def status_check
52
+ end
53
+
54
+
55
+ def sync
56
+ downsync
57
+ upsync
58
+ cleanup
59
+ end
60
+
61
+
62
+ def downsync
63
+ @remote_wiki.list.each do |page|
64
+ next if @syncdone[page.name]
65
+ if @syncstat[page.name].nil? || page.mtime > @syncstat[page.name] && page.mtime > @local_wiki.get(page.name).mtime
66
+ download(page.name)
67
+ end
68
+ end
69
+ end
70
+
71
+
72
+ def upsync
73
+ @local_wiki.list.each do |page|
74
+ next if @syncdone[page.name]
75
+ if @syncstat[page.name].nil? || page.mtime > @syncstat[page.name] && page.mtime > @remote_wiki.get(page.name).mtime
76
+ upload(page.name)
77
+ end
78
+ end
79
+ end
80
+
81
+
82
+ def cleanup
83
+ @syncstat.each do |name, timestamp|
84
+ next if @syncdone[name]
85
+ if @local_wiki.get(name).nil? && @remote_wiki.get(name)
86
+ delete_remote(name)
87
+ end
88
+
89
+ if @local_wiki.get(name) && @remote_wiki.get(name).nil?
90
+ delete_local(name)
91
+ end
92
+
93
+ if @local_wiki.get(name).nil? && @remote_wiki.get(name).nil?
94
+ @syncstat.delete(name)
95
+ save_syncstat
96
+ end
97
+ end
98
+ end
99
+
100
+
101
+ def download(name)
102
+ puts "Downloading:\t#{name}"
103
+ @local_wiki.write(name, @remote_wiki.get(name).content)
104
+ @syncstat[name] = Time.new
105
+ @syncdone[name] = true
106
+ save_syncstat
107
+ end
108
+
109
+
110
+ def upload(name)
111
+ puts "Uploading:\t#{name}"
112
+ @remote_wiki.write(name, @local_wiki.get(name).content)
113
+ @syncstat[name] = Time.new
114
+ @syncdone[name] = true
115
+ save_syncstat
116
+ end
117
+
118
+
119
+ def delete_local(name)
120
+ puts "Deleted on redmine:\t#{name}"
121
+ end
122
+
123
+
124
+ def delete_remote(name)
125
+ puts "Deleted locally:\t#{name}"
126
+ end
127
+
128
+
129
+ def to_s
130
+ str = "#<Redsync::Project"
131
+ str << " url = \"#{@url}\"\n"
132
+ str << " data_dir = \"#{@data_dir}\"\n"
133
+ str << " extension = \"#{@extension}\"\n"
134
+ str << " pages = #{@syncstat.count}\n"
135
+ str << ">"
136
+ end
137
+
138
+ end
139
+ end
@@ -0,0 +1,61 @@
1
+ require 'mechanize'
2
+ require 'uri'
3
+
4
+ class Redsync
5
+ class RemoteWiki
6
+ def initialize(options)
7
+ @url = options[:url]
8
+ @api_key = options[:api_key]
9
+ @agent = Mechanize.new
10
+ end
11
+
12
+ def list
13
+ unless @pages
14
+ @pages = {}
15
+
16
+ index = @agent.get(@url + "/index.xml?key=#{@api_key}")
17
+ index.xml.at("wiki_pages").children.each do |node|
18
+ name = node.at("title").text
19
+ @pages[name] = WikiPage.new(
20
+ :name => name,
21
+ :mtime => Time.parse(node.at("updated_on").text),
22
+ )
23
+ end
24
+ end
25
+
26
+ @pages.values
27
+ end
28
+
29
+ def get(name)
30
+ list unless @pages
31
+
32
+ return nil if @pages[name].nil?
33
+
34
+ unless @pages[name].content
35
+ page = @agent.get(@url + "/#{URI.encode(name)}.xml?key=#{@api_key}")
36
+ @pages[name].content = page.at("text").text
37
+ end
38
+
39
+ @pages[name]
40
+ end
41
+
42
+
43
+ def write(name, content)
44
+ doc = Nokogiri::XML::Document.new
45
+ wiki_page = Nokogiri::XML::Node.new("wiki_page", doc)
46
+
47
+ text = Nokogiri::XML::Node.new("text", doc)
48
+ text.content = content
49
+
50
+ comments = Nokogiri::XML::Node.new("comments", doc)
51
+ comments.content = "Uploaded by Redsync"
52
+
53
+ doc << wiki_page
54
+ wiki_page << text
55
+ wiki_page << comments
56
+
57
+ @agent.put(@url + "/#{URI.encode(name)}.xml?key=#{@api_key}", doc.to_s, 'Content-Type' => "text/xml")
58
+ end
59
+ end
60
+ end
61
+
@@ -1,12 +1,12 @@
1
1
  require 'uri'
2
2
  require 'mechanize'
3
3
  require 'yaml'
4
- require 'iconv'
5
4
 
6
5
  class Redsync
7
6
  class Wiki
8
7
 
9
8
  attr_reader :url,
9
+ :api_key,
10
10
  :data_dir,
11
11
  :extension
12
12
 
@@ -17,13 +17,11 @@ class Redsync
17
17
  # :extension => File extensions for page files. Defaults to "txt"
18
18
  def initialize(options)
19
19
  @url = options[:url].match(/(.*?)\/?$/)[1]
20
+ @api_key = options[:api_key]
20
21
  @data_dir = File.expand_path(options[:data_dir])
21
22
  @extension = options[:extension]
22
23
 
23
24
  @agent = Mechanize.new
24
- options[:cookies].each do |cookie|
25
- @agent.cookie_jar.add(URI.parse(@url), cookie)
26
- end
27
25
 
28
26
  @pages_cache = {}
29
27
  @pages_cache_file = File.join(@data_dir, "__redsync_pages_cache.yml")
@@ -32,10 +30,6 @@ class Redsync
32
30
  end
33
31
 
34
32
 
35
- def cookies
36
- @agent.cookie_jar.cookies(URI.parse(@url))
37
- end
38
-
39
33
  def initialize_system_files
40
34
  unless File.exist? @data_dir
41
35
  puts "Creating #{@data_dir}"
@@ -107,7 +101,6 @@ class Redsync
107
101
 
108
102
  def scan_remote
109
103
  webpage = @agent.get(@url + "/date_index")
110
- now = DateTime.now
111
104
 
112
105
  # Get remote and local update times using remote list
113
106
  webpage.search("#content h3").each do |h3|
@@ -127,7 +120,7 @@ class Redsync
127
120
  next if File.directory? file
128
121
  next if file =~ /^__redsync_/
129
122
  page_name = file.match(/([^\/\\]+?)\.#{@extension}$/)[1]
130
- page_name = Iconv.iconv("UTF-8", "UTF-8-MAC", page_name).first if RUBY_PLATFORM =~ /darwin/
123
+ page_name = page_name.encode("UTF-8-MAC", "UTF-8", :invalid => :replace, :undef => :replace) if RUBY_PLATFORM =~ /darwin/
131
124
  next if pages[page_name]
132
125
  pp file
133
126
  wiki_page = WikiPage.new(self, page_name)
@@ -1,189 +1,11 @@
1
- require 'fileutils'
2
- require 'date'
3
- require 'active_support/all'
4
- require 'redsync/wiki'
5
-
6
1
  class Redsync
7
2
  class WikiPage
8
- attr_reader :name,
9
- :local_file,
10
- :url,
11
- :local_updated_at
12
- attr_accessor :remote_updated_at,
13
- :synced_at
14
-
15
-
16
- def initialize(wiki, name_or_url_or_fullpath)
17
- @wiki = wiki
18
-
19
- if name_or_url_or_fullpath =~ /^#{@wiki.data_dir}\/(.*)$/
20
- @local_file = name_or_url_or_fullpath
21
- @name = $1
22
- @url = @wiki.url + "/" + @name
23
- elsif name_or_url_or_fullpath =~ /^#{@wiki.url}\/(.*)$/
24
- @url = name_or_url_or_fullpath
25
- @name = URI.decode($1)
26
- @local_file = File.join(@wiki.data_dir, "#{@name}.#{@wiki.extension}")
27
- else
28
- @name = name_or_url_or_fullpath
29
- @local_file = File.join(@wiki.data_dir, "#{@name}.#{@wiki.extension}")
30
- @url = @wiki.url + "/" + URI.encode(@name)
31
- end
32
-
33
- @agent = Mechanize.new
34
- @wiki.cookies.each do |cookie|
35
- @agent.cookie_jar.add(URI.parse(@url), cookie)
36
- end
37
- end
38
-
39
-
40
- # Returns one of :remote_only, :local_only, :both or :nowhere
41
- # (:nowhere should never happen...)
42
- def exists_in
43
- if self.local_exists? && self.remote_exists?
44
- return :both
45
- elsif self.local_exists?
46
- return :local_only
47
- elsif self.remote_exists?
48
- return :remote_only
49
- else
50
- return :nowhere
51
- end
52
- end
3
+ attr_accessor :name, :mtime, :content
53
4
 
54
-
55
- def local_exists?
56
- File.exist? @local_file
57
- end
58
-
59
-
60
- def local_updated_at
61
- if local_exists?
62
- File.stat(@local_file).mtime.to_datetime
63
- else
64
- nil
65
- end
66
- end
67
-
68
-
69
- def remote_exists?
70
- !remote_updated_at.nil?
71
- end
72
-
73
-
74
- def remote_updated_at
75
- at = @remote_updated_at
76
- now = DateTime.now
77
- if at && ([at.year, at.month, at.day, at.hour, at.minute, at.second] == [now.year, now.month, now.day, 0, 0, 0])
78
- return @remote_updated_at = history[0][:timestamp]
79
- else
80
- return at
81
- end
82
- end
83
-
84
-
85
- def remote_updated_at=(value)
86
- if value
87
- value = DateTime.parse(value.to_s)
88
- value = DateTime.parse(value.to_s(:db) + DateTime.now.zone) if value.utc?
89
- @remote_updated_at = value
90
- end
91
- end
92
-
93
-
94
- def synced_at
95
- @synced_at
96
- end
97
-
98
-
99
- def synced_at=(value)
100
- if value
101
- value = DateTime.parse(value.to_s)
102
- value = DateTime.parse(value.to_s(:db) + DateTime.now.zone) if value.utc?
103
- @synced_at = value
104
- end
105
- end
106
-
107
-
108
- def history
109
- puts "--Getting page history for #{@name}"
110
- now = DateTime.now
111
- history = []
112
- page = @agent.get(@url + "/history")
113
- page.search("table.wiki-page-versions tbody tr").each do |tr|
114
- timestamp = DateTime.parse(tr.search("td")[3].text + now.zone)
115
- author_name = tr.search("td")[4].text.strip
116
- history << {
117
- :timestamp => timestamp,
118
- :author_name => author_name
119
- }
120
- end
121
- history
122
- end
123
-
124
- def read
125
- page = @agent.get(@url + "/edit")
126
- page.search("textarea")[0].text
5
+ def initialize(options)
6
+ @name = options[:name]
7
+ @mtime = options[:mtime]
8
+ @content = options[:content]
127
9
  end
128
-
129
-
130
- def download_to(file)
131
- File.open(file, "w+:UTF-8") { |f| f.write(self.read) }
132
- end
133
-
134
-
135
- def download
136
- download_to(@local_file)
137
- self.synced_at = self.local_updated_at
138
- end
139
-
140
-
141
- def write(text)
142
- now = DateTime.now
143
- page = @agent.get(@url + "/edit")
144
- form = page.form_with(:id=>"wiki_form")
145
- form.field_with(:name=>"content[text]").value = text
146
- result_page = form.submit
147
- errors = result_page.search("#errorExplanation li").map{ |li| li.text}
148
- end
149
-
150
-
151
- def write_from_file(file)
152
- write(File.open(file, "r:UTF-8").read)
153
- end
154
-
155
-
156
- def upload
157
- write_from_file(@local_file)
158
- self.synced_at = self.remote_updated_at = DateTime.now
159
- end
160
-
161
-
162
- def to_hash
163
- {
164
- :name => @name,
165
- :url => @url,
166
- :local_file => @local_file,
167
- :remote_updated_at => @remote_updated_at,
168
- :local_exists => local_exists?,
169
- :synced_at => @synced_at,
170
- }
171
- end
172
-
173
-
174
- def to_s
175
- str = "#<Redsync::WikiPage"
176
- str << " name = \"#{name}\"\n"
177
- str << " url = \"#{url}\"\n"
178
- str << " local_file = \"#{local_file}\"\n"
179
- str << " remote_exists? = #{remote_exists?}\n"
180
- str << " remote_updated_at = #{@remote_updated_at ? @remote_updated_at : "<never>"}\n"
181
- str << " local_exists? = #{local_exists?}\n"
182
- str << " local_updated_at = #{local_updated_at ? local_updated_at : "<never>"}\n"
183
- str << " synced_at = #{@synced_at ? @synced_at : "<never>"}\n"
184
- str << ">"
185
- end
186
-
187
-
188
10
  end
189
11
  end
metadata CHANGED
@@ -1,49 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redsync
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
5
- prerelease:
4
+ version: 0.3.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - merikonjatta
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2011-12-09 00:00:00.000000000Z
11
+ date: 2014-03-15 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: mechanize
16
- requirement: &2155972500 !ruby/object:Gem::Requirement
17
- none: false
15
+ requirement: !ruby/object:Gem::Requirement
18
16
  requirements:
19
- - - ~>
17
+ - - "~>"
20
18
  - !ruby/object:Gem::Version
21
- version: '2.0'
19
+ version: 2.7.3
22
20
  type: :runtime
23
21
  prerelease: false
24
- version_requirements: *2155972500
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.7.3
25
27
  - !ruby/object:Gem::Dependency
26
- name: activesupport
27
- requirement: &2155972080 !ruby/object:Gem::Requirement
28
- none: false
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
- - - ! '>='
31
+ - - ">="
31
32
  - !ruby/object:Gem::Version
32
33
  version: '0'
33
34
  type: :runtime
34
35
  prerelease: false
35
- version_requirements: *2155972080
36
- - !ruby/object:Gem::Dependency
37
- name: ir_b
38
- requirement: &2155971560 !ruby/object:Gem::Requirement
39
- none: false
36
+ version_requirements: !ruby/object:Gem::Requirement
40
37
  requirements:
41
- - - ! '>='
38
+ - - ">="
42
39
  - !ruby/object:Gem::Version
43
40
  version: '0'
44
- type: :runtime
45
- prerelease: false
46
- version_requirements: *2155971560
47
41
  description: Sync Redmine's wiki pages to your local filesystem. Edit as you like,
48
42
  then upsync.
49
43
  email: merikonjatta@gmail.com
@@ -52,37 +46,38 @@ executables:
52
46
  extensions: []
53
47
  extra_rdoc_files: []
54
48
  files:
55
- - lib/datetime_nil_compare.rb
49
+ - README.textile
50
+ - bin/redsync
51
+ - config.yml.dist
52
+ - lib/redsync.rb
56
53
  - lib/redsync/cli.rb
54
+ - lib/redsync/local_wiki.rb
55
+ - lib/redsync/project.rb
56
+ - lib/redsync/remote_wiki.rb
57
57
  - lib/redsync/sync_stat.rb
58
58
  - lib/redsync/wiki.rb
59
59
  - lib/redsync/wiki_page.rb
60
- - lib/redsync.rb
61
- - README.textile
62
- - config.yml.dist
63
- - bin/redsync
64
60
  homepage: http://github.com/merikonjatta/redsync
65
61
  licenses: []
62
+ metadata: {}
66
63
  post_install_message:
67
64
  rdoc_options: []
68
65
  require_paths:
69
66
  - lib
70
67
  required_ruby_version: !ruby/object:Gem::Requirement
71
- none: false
72
68
  requirements:
73
- - - ! '>='
69
+ - - ">="
74
70
  - !ruby/object:Gem::Version
75
71
  version: '0'
76
72
  required_rubygems_version: !ruby/object:Gem::Requirement
77
- none: false
78
73
  requirements:
79
- - - ! '>='
74
+ - - ">="
80
75
  - !ruby/object:Gem::Version
81
76
  version: '0'
82
77
  requirements: []
83
78
  rubyforge_project:
84
- rubygems_version: 1.8.6
79
+ rubygems_version: 2.2.2
85
80
  signing_key:
86
- specification_version: 3
81
+ specification_version: 4
87
82
  summary: Sync Redmine's wiki pages to your local filesystem.
88
83
  test_files: []
@@ -1,7 +0,0 @@
1
- require 'date'
2
-
3
- class << nil
4
- def to_datetime
5
- DateTime.civil
6
- end
7
- end