lingohub 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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