smc-get 0.1.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,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