smc-get 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,81 @@
1
+ #Encoding: UTF-8
2
+ ################################################################################
3
+ # This file is part of smc-get.
4
+ # Copyright (C) 2010-2011 Entertaining Software, Inc.
5
+ # Copyright (C) 2011 Marvin Gülker
6
+ #
7
+ # This program is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (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, see <http://www.gnu.org/licenses/>.
19
+ ################################################################################
20
+
21
+ module SmcGet
22
+
23
+ module CUICommands
24
+
25
+ #Class for invalid command-line argument errors.
26
+ class InvalidCommandline < Errors::SmcGetError
27
+ end
28
+
29
+ #This is the superclass of all CUI commands. To make your own command,
30
+ #subclass it an overwrite ::help, ::summary, #parse and #execute.
31
+ class Command
32
+
33
+ #The string returned from this method will be displayed to the
34
+ #user if he issues <tt>smc-get help YOURCOMMAND</tt>.
35
+ def self.help
36
+ "(nothing known)"
37
+ end
38
+
39
+ #One-line summary of the command that shows up in the COMMANDS
40
+ #section of <tt>smc-get help</tt>. Should not be longer than 78
41
+ #characters due to automatic indentation. You may have to insert
42
+ #tabs to make it displaycorrectly; make sure to check the result by
43
+ #issueing <tt>smc-get help</tt>.
44
+ def self.summary
45
+ ""
46
+ end
47
+
48
+ #Creates a new instance of this command. Do not override this, or
49
+ #call at least +super+.
50
+ def initialize(args)
51
+ parse(args)
52
+ end
53
+
54
+ #This method gets all commandline options relevant for this subcommand
55
+ #passed in the +args+ array. You should parse them destructively, i.e.
56
+ #after you finished parsing, +args+ should be an empty array.
57
+ #Set instance variables to save data.
58
+ #
59
+ #Note that SmcGet is not set up when this method is called, so you
60
+ #cannot to things like <tt>Package.new</tt>.
61
+ def parse(args)
62
+ raise(NotImplementedError, "#{__method__} has to be overriden in a subclass!")
63
+ end
64
+
65
+ #Execute the command. You can use the instance variables set in #parse.
66
+ #The method gets passed the parsed contents of smc-get's configuration
67
+ #files and commandline parameters; you can use this to make your command
68
+ #configurable via the configuration file, but make sure that
69
+ #1. The keys you use for your configuration don't already exist,
70
+ #2. options specified on the commandline take precedence over values
71
+ # set in the configuration file and
72
+ #3. you <b>do not alter</b> the hash.
73
+ def execute(config)
74
+ raise(NotImplementedError, "#{__method__} has to be overriden in a subclass!")
75
+ end
76
+
77
+ end
78
+
79
+ end
80
+
81
+ end
@@ -0,0 +1,91 @@
1
+ #Encoding: UTF-8
2
+ ################################################################################
3
+ # This file is part of smc-get.
4
+ # Copyright (C) 2010-2011 Entertaining Software, Inc.
5
+ # Copyright (C) 2011 Marvin Gülker
6
+ #
7
+ # This program is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (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, see <http://www.gnu.org/licenses/>.
19
+ ################################################################################
20
+
21
+ module SmcGet
22
+
23
+ module CUICommands
24
+
25
+ class GetinfoCommand < Command
26
+
27
+ def self.help
28
+ <<HELP
29
+ USAGE: #{File.basename($0)} getinfo [-r] PACKAGE
30
+
31
+ Retrieves information about PACKAGE.
32
+
33
+ OPTIONS:
34
+ \r-r\t--remote\tForces getinfo to do a remote lookup.
35
+
36
+ The default behaviour is to do a local lookup if the
37
+ package is already installed.
38
+ HELP
39
+ end
40
+
41
+ def self.summary
42
+ "getinfo\tGet information on a package."
43
+ end
44
+
45
+ def parse(args)
46
+ CUI.debug("Parsing #{args.count} args for getinfo.")
47
+ raise(InvalidCommandline, "No package given.") if args.empty?
48
+ @force_remote = false
49
+
50
+ while args.count > 1
51
+ arg = args.shift
52
+ case arg
53
+ when "-r", "--remote" then @force_remote = true
54
+ else
55
+ raise(InvalidCommandline, "Invalid argument #{arg}.")
56
+ end
57
+ end
58
+ #The last command-line arg is the package
59
+ @pkg_name = args.shift
60
+ end
61
+
62
+ def execute(config)
63
+ CUI.debug("Executing getinfo.")
64
+ pkg = Package.new(@pkg_name)
65
+ #Get the information
66
+ info = if pkg.installed? and !@force_remote
67
+ puts "[LOCAL PACKAGE]"
68
+ pkg.spec
69
+ else
70
+ puts "[REMOTE PACKAGE]"
71
+ pkg.getinfo
72
+ end
73
+ #Now output the information
74
+ puts "Title: #{info['title']}"
75
+ if info['authors'].count == 1
76
+ puts "Author: #{info['authors'][0]}"
77
+ else
78
+ puts 'Authors:'
79
+ info['authors'].each do |author|
80
+ puts " - #{author}"
81
+ end
82
+ end
83
+ puts "Difficulty: #{info['difficulty']}"
84
+ puts "Description: #{info['description']}"
85
+ end
86
+
87
+ end
88
+
89
+ end
90
+
91
+ end
@@ -0,0 +1,64 @@
1
+ #Encoding: UTF-8
2
+ ################################################################################
3
+ # This file is part of smc-get.
4
+ # Copyright (C) 2010-2011 Entertaining Software, Inc.
5
+ # Copyright (C) 2011 Marvin Gülker
6
+ #
7
+ # This program is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (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, see <http://www.gnu.org/licenses/>.
19
+ ################################################################################
20
+
21
+ module SmcGet
22
+
23
+ module CUICommands
24
+
25
+ class HelpCommand < Command
26
+
27
+ def self.help
28
+ <<EOF
29
+ USAGE: #{File.basename($0)} help [SUBCOMMAND]
30
+
31
+ Shows help for a special SUBCOMMAND or for #{File.basename($0)} in general.
32
+ EOF
33
+ end
34
+
35
+ def self.summary
36
+ "help\t\tGet help on a specific command."
37
+ end
38
+
39
+ def parse(args)
40
+ CUI.debug("Parsing #{args.count} args for help.")
41
+ raise(InvalidCommandline, "Too many arguments.") if args.count > 1
42
+ @command = args.shift #nil if not given
43
+ end
44
+
45
+ def execute(config)
46
+ CUI.debug("Executing help.")
47
+ if @command
48
+ sym = :"#{@command.capitalize}Command"
49
+ if CUICommands.const_defined?(sym)
50
+ puts CUICommands.const_get(sym).help
51
+ else
52
+ puts "#{@command} is not a valid command."
53
+ return 2
54
+ end
55
+ else
56
+ puts CUI::GENERAL_HELP
57
+ end
58
+ end
59
+
60
+ end
61
+
62
+ end
63
+
64
+ end
@@ -0,0 +1,91 @@
1
+ #Encoding: UTF-8
2
+ ################################################################################
3
+ # This file is part of smc-get.
4
+ # Copyright (C) 2010-2011 Entertaining Software, Inc.
5
+ # Copyright (C) 2011 Marvin Gülker
6
+ #
7
+ # This program is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (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, see <http://www.gnu.org/licenses/>.
19
+ ################################################################################
20
+
21
+ module SmcGet
22
+
23
+ module CUICommands
24
+
25
+ class InstallCommand < Command
26
+
27
+ def self.help
28
+ <<HELP
29
+ USAGE: #{File.basename($0)} install [-r] PACKAGES
30
+
31
+ Installs one or more packages.
32
+
33
+ OPTIONS:
34
+ -r\t--reinstall\tForces a reinstallation of the package.
35
+ HELP
36
+ end
37
+
38
+ def self.summary
39
+ "install\tInstall one or more packages."
40
+ end
41
+
42
+ def parse(args)
43
+ CUI.debug("Parsing #{args.count} args for install.")
44
+ raise(InvalidCommandline, "No package given.") if args.empty?
45
+ @reinstall = false
46
+ @pkg_names = []
47
+
48
+ until args.empty?
49
+ arg = args.shift
50
+ case arg
51
+ when "--reinstall", "-r" then @reinstall = true
52
+ else
53
+ @pkg_names << arg
54
+ $stderr.puts("Unknown argument #{arg}. Treating it as a package.") if arg.start_with?("-")
55
+ end
56
+ end
57
+ end
58
+
59
+ def execute(config)
60
+ CUI.debug("Executing install.")
61
+ @pkg_names.each do |pkg_name|
62
+ pkg = Package.new(pkg_name)
63
+ if pkg.installed?
64
+ if @reinstall
65
+ puts "Reinstalling #{pkg}."
66
+ else
67
+ puts "#{pkg} is already installed. Maybe you want --reinstall?."
68
+ next
69
+ end
70
+ end
71
+ puts "Installing #{pkg}."
72
+ #Windows doesn't understand ANSI escape sequences, so we have to
73
+ #use the carriage return and reprint the whole line.
74
+ base_str = "\rDownloading %s... (%.2f%%)"
75
+ pkg.install(config[:max_tries]) do |filename, percent_filename, retrying|
76
+ if retrying
77
+ puts "#{retrying.message} Retrying."
78
+ else
79
+ print "\r", " " * 80 #Clear everything written before
80
+ printf(base_str, filename, percent_filename)
81
+ end
82
+ end
83
+ puts
84
+ end
85
+ end
86
+
87
+ end
88
+
89
+ end
90
+
91
+ end
@@ -0,0 +1,80 @@
1
+ #Encoding: UTF-8
2
+ ################################################################################
3
+ # This file is part of smc-get.
4
+ # Copyright (C) 2010-2011 Entertaining Software, Inc.
5
+ # Copyright (C) 2011 Marvin Gülker
6
+ #
7
+ # This program is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (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, see <http://www.gnu.org/licenses/>.
19
+ ################################################################################
20
+
21
+ module SmcGet
22
+
23
+ module CUICommands
24
+
25
+ class ListCommand < Command
26
+
27
+ def self.help
28
+ <<EOF
29
+ USAGE: #{File.basename($0)} list [PACKAGE]
30
+
31
+ If PACKAGE is given, lists all files installed by PACKAGE. Otherwise,
32
+ all installed packages are listed accompanied by their installation
33
+ date in the format YY-MM-DD HH:MM, where the time is given on a
34
+ 24-hour clock.
35
+ EOF
36
+ end
37
+
38
+ def self.summary
39
+ "list\t\tLists all installed packages or files installed by a package. "
40
+ end
41
+
42
+ def parse(args)
43
+ CUI.debug("Parsing #{args.count} args for list.")
44
+ raise(InvalidCommandline, "Too many arguments.") if args.count > 1
45
+ @pkg_name = args.shift #nil if not specified
46
+ end
47
+
48
+ def execute(config)
49
+ CUI.debug("Executing help.")
50
+ if Package.installed_packages.empty?
51
+ puts "No packages installed."
52
+ else
53
+ if @pkg_name
54
+ pkg = Package.new(@pkg_name)
55
+ puts "Files installed for #{pkg}:"
56
+ info = pkg.spec
57
+ puts
58
+ puts "Levels:"
59
+ puts info["levels"].join("\n")
60
+ puts
61
+ puts "Music:"
62
+ puts info.has_key?("music") ? info["music"].join("\n") : "(None)"
63
+ puts
64
+ puts "Graphics:"
65
+ puts info.has_key?("graphics") ? info["graphics"].join("\n") : "(None)"
66
+ else
67
+ printf("%-38s | %-38s\n", "Package", "Installation date")
68
+ print("-" * 39, "+", "-" * 40, "\n")
69
+ Package.installed_packages.each do |pkg|
70
+ printf("%-38s | %-38s\n", pkg.name, pkg.spec_file.mtime.strftime("%d-%m-%Y %H:%M"))
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ end
77
+
78
+ end
79
+
80
+ end
@@ -0,0 +1,109 @@
1
+ #Encoding: UTF-8
2
+ ################################################################################
3
+ # This file is part of smc-get.
4
+ # Copyright (C) 2010-2011 Entertaining Software, Inc.
5
+ # Copyright (C) 2011 Marvin Gülker
6
+ #
7
+ # This program is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (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, see <http://www.gnu.org/licenses/>.
19
+ ################################################################################
20
+
21
+ module SmcGet
22
+
23
+ module CUICommands
24
+
25
+ class SearchCommand < Command
26
+
27
+ def self.help
28
+ <<HELP
29
+ USAGE: #{File.basename($0)} search [-a][-d][-D][-l][-L][-p][-t] QUERY
30
+
31
+ Searches the local or remote repository for packages. QUERY is assumed
32
+ to be a regular expression.
33
+
34
+ OPTIONS:
35
+ -a\t--authors\tSearch the author list.
36
+ -d\t--description\tSearch the package descriptions.
37
+ -D\t--difficulty\tSearch the 'difficulty' fields.
38
+ -l\t--only-local\tOnly search local packages. Default is to search remotely.
39
+ -L\t--levels\tSearch for specific level names.
40
+ -p\t--pkgname\tSearch the package files' names.
41
+ -t\t--title\t\tSearch the packages' full titles.
42
+
43
+
44
+ If you don't specify which fields to use, --pkgname is assumed as it performs
45
+ best if used alone.
46
+ HELP
47
+ end
48
+
49
+ def self.summary
50
+ "search\tSearch for a package."
51
+ end
52
+
53
+ def parse(args)
54
+ CUI.debug("Parsing #{args.count} args for search.")
55
+ raise(InvalidCommandline, "No query given.") if args.empty?
56
+ @search_fields = []
57
+ @only_local = false
58
+
59
+ while args.count > 1
60
+ arg = args.shift
61
+ case arg
62
+ when "-l", "--only-local" then @only_local = true
63
+ when "-t", "--title" then @search_fields << :title
64
+ when "-d", "--description" then @search_fields << :description
65
+ when "-a", "--authors" then @search_fields << :authors
66
+ when "-D", "--difficulty" then @search_fields << :difficulty
67
+ when "-L", "--levels" then @search_fields << :levels
68
+ when "-p", "--pkgname" then @search_fields << :pkgname
69
+ else
70
+ raise(InvalidCommandline, "Invalid argument #{arg}.")
71
+ end
72
+ end
73
+ #If no search fields were specified, default to :pkgname, because
74
+ #it causes the least network traffic.
75
+ @search_fields << :pkgname if @search_fields.empty?
76
+ #The last command-line arg is the search query
77
+ @query = Regexp.new(args.shift)
78
+ end
79
+
80
+ def execute(config)
81
+ CUI.debug("Executing search.")
82
+ result = SmcGet::Package.search(@query, @search_fields, @only_local)
83
+ return 2 if result.empty?
84
+ result.each do |pkg|
85
+ #We need to check the only_local option here, because the level
86
+ #version in the repository may be newer than that one installed
87
+ #locally. pkg.installed? wouldn't have telled us that.
88
+ spec = if @only_local
89
+ puts "[LOCAL PACKAGE]"
90
+ pkg.spec
91
+ else
92
+ puts "[REMOTE PACKAGE]"
93
+ pkg.getinfo
94
+ end
95
+ puts "Package title: #{spec["title"]}"
96
+ puts "Real package name: #{pkg.name}"
97
+ puts "Authors: #{spec["authors"].join(",")}"
98
+ puts "Difficulty: #{spec["difficulty"]}"
99
+ puts "Description:"
100
+ puts spec["description"]
101
+ puts
102
+ end
103
+ end
104
+
105
+ end
106
+
107
+ end
108
+
109
+ end