lingohub 0.0.4

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,44 @@
1
+ module Lingohub::Command
2
+ class Collaborator < Base
3
+ def list
4
+ list = project.collaborators
5
+ if list.size > 0
6
+ display "Collaborators:\n"
7
+ list.each { |c| display("- #{c.display_name} | #{c.email} | #{c.permissions}") }
8
+ else
9
+ display "No collaborators found"
10
+ end
11
+ end
12
+
13
+ def invite
14
+ email = extract_email_from_args
15
+ project.invite_collaborator(email)
16
+
17
+ display("Invitation sent to #{email}")
18
+ rescue RestClient::BadRequest
19
+ display("Error sending invitation to '#{email}'")
20
+ end
21
+
22
+ def remove
23
+ email = extract_email_from_args
24
+ collaborator = project.collaborators.find { |c| c.email == email }
25
+
26
+ if collaborator.nil?
27
+ display("Collaborator with email '#{email}' not found")
28
+ else
29
+ collaborator.destroy
30
+ display("Collaborator with email #{email} was removed")
31
+ end
32
+ rescue RestClient::BadRequest
33
+ display("Error removing collaborator with email '#{email}'")
34
+ end
35
+
36
+ private
37
+
38
+ def extract_email_from_args
39
+ email = args.shift
40
+ raise(CommandFailed, "You must specify a invitee email after --email") if email == false
41
+ email
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,101 @@
1
+ module Lingohub::Command
2
+ class Help < Base
3
+ class HelpGroup < Array
4
+
5
+ attr_reader :title
6
+
7
+ def initialize(title)
8
+ @title = title
9
+ end
10
+
11
+ def command(name, description)
12
+ self << [name, description]
13
+ end
14
+
15
+ def space
16
+ self << ['', '']
17
+ end
18
+ end
19
+
20
+ def self.groups
21
+ @groups ||= []
22
+ end
23
+
24
+ def self.group(title, &block)
25
+ groups << begin
26
+ group = HelpGroup.new(title)
27
+ yield group
28
+ group
29
+ end
30
+ end
31
+
32
+ def self.create_default_groups!
33
+ return if @defaults_created
34
+ @defaults_created = true
35
+ group 'General Commands' do |group|
36
+ group.command 'help', 'show this usage'
37
+ group.command 'version', 'show the gem version'
38
+ group.space
39
+ group.command 'login', "let's you (re)login"
40
+ group.command 'logout', 'logs you out by clearing your current credentials'
41
+ end
42
+
43
+ group 'Project Commands' do |group|
44
+ group.command 'project:list', 'list your projects'
45
+ group.command 'project:create <name>', 'create a new project'
46
+ group.command 'project:info --project <name>', 'show project info, like web url and number of translations'
47
+ group.command 'project:open --project <name>', 'open the project in a web browser'
48
+ group.command 'project:rename <oldname> <newname>', 'rename the project'
49
+ group.command 'project:destroy --project <name>', 'destroy the project permanently'
50
+ group.space
51
+ end
52
+
53
+ group 'Collaborator Commands' do |group|
54
+ group.command 'collaborator:list --project <name>', 'list project collaborators'
55
+ group.command 'collaborator:invite <email> --project <name>', 'invite the collaborator'
56
+ group.command 'collaborator:remove <email> --project <name>', 'remove the collaborator'
57
+ group.space
58
+ end
59
+
60
+ group 'Translation Commands' do |group|
61
+ group.command 'translation:down --all --directory <path> --project <name>', 'download all resource files'
62
+ group.command 'translation:down <file1> <file2> ... --directory <path> --project <name>', 'download specific resource files'
63
+ group.command 'translation:down <file> --query <query> --directory <path> --locale <iso2_slug> --project <name>', 'search for translations and download them to file'
64
+ group.command 'translation:up <file1> <file2> ... --locale <iso2_slug> --project <name>', 'upload specific resource files'
65
+ group.space
66
+ end
67
+ end
68
+
69
+ def index
70
+ display usage
71
+ end
72
+
73
+ def version
74
+ display Lingohub::Client.version
75
+ end
76
+
77
+ def usage
78
+ longest_command_length = self.class.groups.map do |group|
79
+ group.map { |g| g.first.length }
80
+ end.flatten.max
81
+
82
+ self.class.groups.inject(StringIO.new) do |output, group|
83
+ output.puts "=== %s" % group.title
84
+ output.puts
85
+
86
+ group.each do |command, description|
87
+ if command.empty?
88
+ output.puts
89
+ else
90
+ output.puts "%-*s # %s" % [longest_command_length, command, description]
91
+ end
92
+ end
93
+
94
+ output.puts
95
+ output
96
+ end.string
97
+ end
98
+ end
99
+ end
100
+
101
+ Lingohub::Command::Help.create_default_groups!
@@ -0,0 +1,66 @@
1
+ require 'readline'
2
+ require 'launchy'
3
+
4
+ module Lingohub::Command
5
+ class Project < Base
6
+ def login
7
+ Lingohub::Command.run_internal "auth:reauthorize", args.dup
8
+ end
9
+
10
+ def logout
11
+ Lingohub::Command.run_internal "auth:delete_credentials", args.dup
12
+ display "Local credentials cleared."
13
+ end
14
+
15
+ def list
16
+ list = lingohub.projects.all
17
+ if list.size > 0
18
+ display "Projects:\n" + list.keys.map { |name|
19
+ "- #{name}"
20
+ }.join("\n")
21
+ else
22
+ display "You have no projects."
23
+ end
24
+ end
25
+
26
+ def create
27
+ title = args.shift.strip rescue nil
28
+ title ||= extract_from_dir_name
29
+ lingohub.projects.create title
30
+ display("Created #{title}")
31
+ end
32
+
33
+ def rename
34
+ oldtitle = args[0].strip rescue raise(CommandFailed, "Invalid old project name")
35
+ newtitle = args[1].strip rescue raise(CommandFailed, "Invalid new project name")
36
+
37
+ project(oldtitle).update(:title => newtitle)
38
+ display("Project renamed from #{oldtitle} to #{newtitle}")
39
+ end
40
+
41
+ def info
42
+ display "=== #{project.title}"
43
+ display "Web URL: #{project.weburl}"
44
+ display "Owner: #{project.owner}"
45
+ display "Number of translation: #{project.translations_count}"
46
+ end
47
+
48
+ def open
49
+ Launchy.open project.weburl
50
+ end
51
+
52
+ def destroy
53
+ display "=== #{project.title}"
54
+ display "Web URL: #{project.weburl}"
55
+ display "Owner: #{project.owner}"
56
+
57
+ if confirm_command(project.title)
58
+ redisplay "Destroying #{project.title} ... "
59
+ project.destroy
60
+ display "done"
61
+ end
62
+ end
63
+
64
+ end
65
+
66
+ end
@@ -0,0 +1,97 @@
1
+ module Lingohub::Command
2
+ class Translation < Base
3
+ def down
4
+ project #project validation
5
+
6
+ directory = File.join(Dir.pwd, extract_directory_from_args || "")
7
+ raise(CommandFailed, "Error downloading translations. Path #{directory} does not exist") unless File.directory?(directory)
8
+
9
+ if extract_query_from_args
10
+ pull_search_results(directory)
11
+ else
12
+ pull_resources(directory)
13
+ end
14
+ end
15
+
16
+ def up
17
+ project #project validation
18
+
19
+ push_resources(args)
20
+ end
21
+
22
+ private
23
+
24
+ def rails_environment?
25
+ true #TODO
26
+ end
27
+
28
+ def rails_locale_dir
29
+ Dir.pwd + "/conf/locales"
30
+ end
31
+
32
+ def extract_directory_from_args
33
+ return @directory if defined? @directory
34
+ @directory = extract_option('--directory', false)
35
+ raise(CommandFailed, "You must specify a directory after --directory") if @directory == false
36
+ @directory
37
+ end
38
+
39
+ def extract_locale_from_args
40
+ return @locale if defined? @locale
41
+ @locale = extract_option('--locale', false)
42
+ raise(CommandFailed, "You must specify a locale after --locale") if @locale == false
43
+ @locale
44
+ end
45
+
46
+ def extract_all_from_args
47
+ return @all if defined? @all
48
+ @all = extract_option('--all', true)
49
+ raise(CommandFailed, "You have not specify anything after --all") unless @all == true or @all.nil?
50
+ @all
51
+ end
52
+
53
+ def extract_query_from_args
54
+ return @query if defined? @query
55
+ @query = extract_option('--query', false)
56
+ raise(CommandFailed, "You have not specify anything after --query") if @query == false
57
+ @query
58
+ end
59
+
60
+ def pull_search_results(directory)
61
+ query = extract_query_from_args
62
+ locale = extract_locale_from_args
63
+ filename = args.first
64
+
65
+ begin
66
+ project.pull_search_results(directory, filename, query, locale)
67
+ display("Search results for '#{query}' saved to #{filename}")
68
+ rescue
69
+ display "Error saving search results for '#{query}'. Response: #{$!.response || $!.message}"
70
+ end
71
+ end
72
+
73
+ def pull_resources(directory)
74
+ files_source = extract_all_from_args ? project.resources.keys : args
75
+ files_source.each do |file_name|
76
+ begin
77
+ project.pull_resource(directory, file_name)
78
+ display("#{file_name} downloaded")
79
+ rescue
80
+ display "Error downloading #{file_name}. Response: #{$!.response || $!.message}"
81
+ end
82
+ end
83
+ end
84
+
85
+ def push_resources(resources)
86
+ resources.each do |file_name|
87
+ begin
88
+ path = File.expand_path(file_name, Dir.pwd)
89
+ project.push_resource(path, extract_locale_from_args)
90
+ display("#{file_name} uploaded")
91
+ rescue
92
+ display "Error uploading #{file_name}. Response: #{$!.response || $!.message}"
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,7 @@
1
+ module Lingohub::Command
2
+ class Version < Base
3
+ def index
4
+ display Lingohub::Client.gem_version_string
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,121 @@
1
+ module Lingohub
2
+ module Helpers
3
+ def home_directory
4
+ running_on_windows? ? ENV['USERPROFILE'] : ENV['HOME']
5
+ end
6
+
7
+ def running_on_windows?
8
+ RUBY_PLATFORM =~ /mswin32|mingw32/
9
+ end
10
+
11
+ def running_on_a_mac?
12
+ RUBY_PLATFORM =~ /-darwin\d/
13
+ end
14
+
15
+ def display(msg, newline=true)
16
+ if newline
17
+ puts(msg)
18
+ else
19
+ print(msg)
20
+ STDOUT.flush
21
+ end
22
+ end
23
+
24
+ def redisplay(line, line_break = false)
25
+ display("\r\e[0K#{line}", line_break)
26
+ end
27
+
28
+ def deprecate(version)
29
+ display "!!! DEPRECATION WARNING: This command will be removed in version #{version}"
30
+ display ""
31
+ end
32
+
33
+ def error(msg)
34
+ STDERR.puts(msg)
35
+ exit 1
36
+ end
37
+
38
+ def confirm(message="Are you sure you wish to continue? (y/n)?")
39
+ display("#{message} ", false)
40
+ ask == 'y'
41
+ end
42
+
43
+ def confirm_command(app)
44
+ # if extract_option('--force')
45
+ # display("Warning: The --force switch is deprecated, and will be removed in a future release. Use --confirm #{app} instead.")
46
+ # return true
47
+ # end
48
+
49
+ raise(Lingohub::Command::CommandFailed, "No app specified.\nRun this command from app folder or set it adding --app <app name>") unless app
50
+
51
+ confirmed_app = extract_option('--confirm', false)
52
+ if confirmed_app
53
+ unless confirmed_app == app
54
+ raise(Lingohub::Command::CommandFailed, "Confirmed app #{confirmed_app} did not match the selected app #{app}.")
55
+ end
56
+ return true
57
+ else
58
+ display ""
59
+ display " ! WARNING: Potentially Destructive Action"
60
+ display " ! This command will affect the app: #{app}"
61
+ display " ! To proceed, type \"#{app}\" or re-run this command with --confirm #{app}"
62
+ display ""
63
+ display "> ", false
64
+ if ask != app
65
+ display " ! Input did not match #{app}. Aborted."
66
+ false
67
+ else
68
+ true
69
+ end
70
+ end
71
+ end
72
+
73
+ def format_date(date)
74
+ date = Time.parse(date) if date.is_a?(String)
75
+ date.strftime("%Y-%m-%d %H:%M %Z")
76
+ end
77
+
78
+ def ask
79
+ gets.strip
80
+ end
81
+
82
+ def shell(cmd)
83
+ FileUtils.cd(Dir.pwd) {|d| return `#{cmd}`}
84
+ end
85
+
86
+ def run_command(command, args=[])
87
+ Lingohub::Command.run_internal(command, args)
88
+ end
89
+
90
+ def retry_on_exception(*exceptions)
91
+ retry_count = 0
92
+ begin
93
+ yield
94
+ rescue *exceptions => ex
95
+ raise ex if retry_count >= 3
96
+ sleep 3
97
+ retry_count += 1
98
+ retry
99
+ end
100
+ end
101
+
102
+ def has_git?
103
+ %x{ git --version }
104
+ $?.success?
105
+ end
106
+
107
+ def git(args)
108
+ return "" unless has_git?
109
+ flattened_args = [args].flatten.compact.join(" ")
110
+ %x{ git #{flattened_args} 2>&1 }.strip
111
+ end
112
+ end
113
+ end
114
+
115
+ unless String.method_defined?(:shellescape)
116
+ class String
117
+ def shellescape
118
+ empty? ? "''" : gsub(/([^A-Za-z0-9_\-.,:\/@\n])/n, '\\\\\\1').gsub(/\n/, "'\n'")
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,25 @@
1
+ module Lingohub
2
+ module Models
3
+ class Collaborator
4
+ attr_accessor :email, :display_name, :roles
5
+
6
+ ROLES_NAMES = { "project_admin" => "Project admin", "developer" => "Developer" }
7
+
8
+ def initialize(client, link)
9
+ @client = client
10
+ @link = link
11
+ end
12
+
13
+ def destroy
14
+ @client.delete @link
15
+ end
16
+
17
+ def permissions
18
+ return "None" if self.roles.nil? or self.roles.empty?
19
+
20
+ self.roles.find_all { |role| ROLES_NAMES.has_key?(role) }.join(", ")
21
+ end
22
+
23
+ end
24
+ end
25
+ end