Git Product home page Git Product logo

fac's Introduction

fac

Fac is a command-line mod manager for Factorio >=0.13 written in Python 3.

You'll need Python 3, which can be obtained through your distribution's package manager or downloaded from https://www.python.org/ (for Windows users).

Installation can be easilly done using pip:

$ pip3 install fac-cli

Or directly from git:

$ pip3 install -e "git+https://github.com/mickael9/fac.git#egg=fac-cli"

Or from an existing clone:

$ pip3 install -e .

NOTE (linux users): By default, these commands will require you to be root unless you run pip from a virtualenv or you use the --user flag.

If you run pip with the --user flag, make sure ~/.local/bin is in your PATH or the fac command will not work.

fac needs to be able to know the location of:

  • The Factorio data directory, eg /usr/share/factorio/
  • The Factorio configuration directory, eg ~/.factorio

Normally, it should be able to detect these automatically assuming you have a standard setup (eg. Steam). It will also look in the current working directory and its parent.

If for some reason these paths can't be found automatically, you'll have to specify them in fac's config file, which is located at:

  • ~/.config/fac/config.ini on Linux
  • C:\Users\<username>\AppData\Local\fac\config.ini on Windows
  • ~/Library/Application Support/fac/config.ini on Mac OS X
[paths]
data-path = /home/me/my_factorio/data
write-path = /home/me/my_factorio

You can display the currently detected locations using fac -v:

$ fac -v
DEBUG:fac.main:Factorio write path: /home/mickael/.factorio
DEBUG:fac.main:Factorio game path: /usr/share/factorio
DEBUG:fac.main:Factorio version: 0.13.9
usage: fac COMMAND [options...]
[...]

fac can be run using the fac command. It is further divided into several subcommands:

usage: fac COMMAND [options...]

Mod manager for Factorio

  COMMAND
    list                List installed mods and their status.
    enable              Enable mods.
    disable             Disable mods.
    search              Search the mods database.
    show                Show details about specific mods.
    install             Install (or update) mods.
    update              Update installed mods.
    remove              Remove mods.
    hold                Hold mods (show held mods with no argument).
    unhold              Unhold mods.
    pack                Pack mods.
    unpack              Unpack mods.
    fetch               Fetch a mod from the mod portal.
    make-compatible     Change the supported factorio version of mods.

general options:
  -g GAME_VERSION, --game-version GAME_VERSION
                        force a specific game version
  -m MODS_DIRECTORY, --mods-directory MODS_DIRECTORY
                        use the specified mods directory
  -i, --ignore-game-ver
                        ignore game version when selecting packages
  -v, --verbose         show more detailled output
  -h, --help            show this help message and exit

Below are simple examples of what you can do for each command.

$ fac list
Installed mods:
    Warehousing 0.0.10
    YARM 0.7.105
    advanced-logistics-system 0.3.0 (unpacked, incompatible)
    creative-mode 0.1.4 (disabled, unpacked)
$ fac disable YARM
YARM is now disabled

$ fac list
    YARM 0.7.105 (disabled)

$ fac enable YARM
YARM is now enabled

$ fac list
    YARM 0.7.105
$ fac search 5dim

5dim's Mod - Core
    Name: 5dim_core
    Tags: big-mods

    Core of all 5dim's mod

5dim's Mod - Automatization
    Name: 5dim_automatization
    Tags: big-mods

    Automatization for 5dim's mod

5dim's Mod - Energy
    Name: 5dim_energy
    Tags: big-mods

    Energy for 5dim's mod

[...]
$ fac show 5dim_logistic
Name: 5dim_logistic
Author: McGuten
Title: 5dim's Mod - Logistic
Summary: logistic of all 5dim's mod
Description:
    logistic of all 5dim's mod
Tags: big-mods
Homepage: http://www.5dim.es
License: MIT
Game versions: 0.13
Releases:
    Version: 0.13.1    Game version: 0.13
    Version: 0.13.0    Game version: 0.13
$ fac install Foreman 5dim_logistic
Adding dependency: 5dim_core 0.13.1
Installing: Foreman 0.2.5...
Downloading: https://mods.factorio.com/api/downloads/data/mods/308/Foreman_0.2.5.zip...
Installing: 5dim_core 0.13.1...
Downloading: https://mods.factorio.com/api/downloads/data/mods/191/5dim_core_0.13.1.zip...
Installing: 5dim_logistic 0.13.1...
Downloading: https://mods.factorio.com/api/downloads/data/mods/196/5dim_logistic_0.13.1.zip...

$ fac install Foreman==0.2.2
Foreman==0.2.5 is already installed. Use -R to reinstall it.

Foreman is already installed in a more recent version. Use -D to downgrade it.

$ fac install Foreman==0.2.2 -D
Installing: Foreman 0.2.2...
Downloading: https://mods.factorio.com/api/downloads/data/mods/308/Foreman_0.2.2.zip...
Removing: /home/mickael/.factorio/mods/Foreman_0.2.5.zip

The fetch command can be used to download a mod into a specified directory.

$ fac update
Checking: Foreman
Checking: 5dim_logistic
Checking: 5dim_core
Checking: YARM
Found 1 update:
    Foreman 0.2.2 -> 0.2.3
Continue? [Y/n]
Downloading: https://mods.factorio.com/api/downloads/data/mods/308/Foreman_0.2.3.zip...
Removing: /home/mickael/.factorio/mods/Foreman_0.2.2.zip

Use this to keep mods from being automatically updated when using the update command.

$ fac install Foreman==0.2.2
Installing: Foreman 0.2.2...
Downloading: https://mods.factorio.com/api/downloads/data/mods/308/Foreman_0.2.2.zip...

$ fac hold Foreman
Foreman will not be updated automatically anymore

$ fac update
Checking: Foreman
Found update: Foreman 0.2.5
Foreman is held. Use -H to update it anyway.
No updates were found

$ fac unhold Foreman
Foreman will now be updated automatically.

$ fac update
Checking: YARM
Found 1 update:
    Foreman 0.2.2 -> 0.2.5
Continue? [Y/n]
Downloading: https://mods.factorio.com/api/downloads/data/mods/308/Foreman_0.2.5.zip...
Removing: /home/mickael/.factorio/mods/Foreman_0.2.2.zip
$ fac remove Foreman
The following files will be removed:
    /home/mickael/.factorio/mods/Foreman_0.2.3.zip
Continue? [Y/n]
Removing: /home/mickael/.factorio/mods/Foreman_0.2.3.zip

Mods can be either packed (name_0.1.zip) or unpacked (name_0.1/) and the game will accept both of them.

Keep in mind that the game will refuse to start if there is both a packed and unpacked version of a mod, or if there are multiple installed versions for any given mod.

$ fac unpack yarm
Unpacking: /home/mickael/.factorio/mods/YARM_0.7.105.zip
Removing file: /home/mickael/.factorio/mods/YARM_0.7.105.zip
YARM is now unpacked

$ fac pack yarm
Packing: /home/mickael/.factorio/mods/YARM_0.7.105/
Removing directory: /home/mickael/.factorio/mods/YARM_0.7.105/
YARM is now packed

Commands that work on locally installed mods can accept wildcards, eg:

$ fac remove '5dim_*'
The following files will be removed:
    /home/mickael/.factorio/mods/5dim_logistic_0.13.1.zip
    /home/mickael/.factorio/mods/5dim_core_0.13.1.zip
Continue? [Y/n]
Removing: /home/mickael/.factorio/mods/5dim_logistic_0.13.1.zip
Removing: /home/mickael/.factorio/mods/5dim_core_0.13.1.zip

$ fac enable '*'
advanced-logistics-system was already enabled
Warehousing was already enabled
YARM was already enabled
Foreman is now enabled

Note the presence of quotes around filters to prevent the shell from interpreting them.

Most commands will try to guess the correct name when given inexact mod names.

If the name is a filter (eg 5dim_*), no attempt to autocorrect will be made.

The following attempts are made to find a match for a given mod name:

  • Exact match
  • Case-insensitive match
  • Partial case-insensitive match if there is no ambiguity.
  • For remote commands (install, update...), the search result if there is only one.

For remote commands, a local match will first be attempted at each step.

For instance:

  • yarm will be converted to YARM via the Case-insensitive match strategy
  • ya will either be converted to YARM if you have YARM installed or fail because there is more than one result to the fac search ya command.

Mods are tied to a specific factorio version (eg 0.13, 0.14) and can only work with that version. A 0.14 game will refuse to load a mod made for 0.13.

By default, fac will autodetect your installed factorio version and use that to filter the available commands to compatible mods.

In some cases, you might want to disable this filtering using the -i option. You can also override the detected game version using -g 0.13 for instance.

A make-compatible command is provided. It will automatically unpack a mod and change its factorio_version field to the currently set game version (autodetected or provided by the -g option).

Usage scenario

You're currently running Factorio 0.14 and want to install your favorite mod, YARM:

$ fac search YARM
Note: 1 mods were hidden because they have no compatible game versions. Use -i to show them.

$ fac search YARM -i
Yet Another Resource Monitor Fork
    Name: YARM
    Tags: incompatible, info

This mod helps you to keep track of your mining sites.

Feeling courageous, you want to try it anyway:

$ fac install -i YARM
[...]

$ fac make-compatible YARM
Unpacking: /home/mickael/.factorio/mods/YARM_0.7.105.zip
Removing file: /home/mickael/.factorio/mods/YARM_0.7.105.zip
Game version changed to 0.14 for YARM 0.7.105.

You can now use the mod as if it was made for Factorio 0.14.

If you're using ZSH (and you should be!) you can install the provided completion script for a better experience.

You'll need to add the zsh directory to your fpath using something like this in your .zshrc :

fpath+=(/path/to/fac/zsh)

If you installed fac using pip as root, the script should automatically be installed in the right place (/usr/share/zsh/site-functions).

With pip --user, you'll need to add this in your .zshrc :

fpath+=(~/.local/share/zsh/site-functions)

Note: compinit must be called after fpath is changed so you must either put your changes before compinit or add another compinit call after changing fpath.

0.9
  • Known issues:
    • search command will list all existing mods regardless of the search critera. This shall be addressed in a future release.
  • Compatibility with the new mod portal
  • Fix mod install failure across filesystems
  • Search for Factorio installation in lowercase steamapps directory as well
  • Don't follow symbolic links when packing/unpacking mods
0.8
  • Added automatic retries of network requests to the API
  • Added pagination options to search command:
    • -p, --page: starting page number for the API calls
    • -s, --page-size: maximum number of returned results per page
    • -c, --page-count: maximum number of pages to fetch
  • Fixed Factorio 0.15 compatibility (use booleans in mod-list.json)
  • Fixed -m, --mods-directory being ignored when loading mod-list.json
0.7
  • Added more friendly error messages when the user doesn't own the game
  • Fixed "AttributeError: 'ZippedMod' object has no attribute 'factorio_version'" (#8)
0.6
  • Added -F, --format to list and show commands.
  • Added -I, --include and -E, --exclude to list commands.
  • Added -m, --mods-directory option to use a specific mods directory.
  • Added fac version to output when using -v, --verbose.
  • Improved ZSH completion script.
  • Fixed write-path and data-path being ignored from config.ini
  • Fixed search command format string argument.
  • Fixed options parsing to allow general options anywhere in the command line.
0.5
  • Added workaround for 0.14 mods being considered as 0.13 mods.
  • Added a ZSH completion script.
  • Added -F, --format option to search command to customize the output format using format strings.
  • Various bug fixes.
0.4
  • New pack and unpack commands to work on unpacked mods.
  • New fetch command to fetch a mod without installing it.
  • New make-compatible command to bump the factorio_version of an installed mod.
  • New -l, --limit option to the search command.
  • New -g, --game-version option to override the detected game version.
  • New -i, --ignore-game-ver flag to ignore the current game version.
  • Removed --force flag in favor of the more specfic -R, --reinstall, -D, --downgrade, -H, --held.
  • Accept patterns in enable, pack, hold commands.
  • Resolve partial mod names.
  • Various bug fixes.
0.3
  • Support for mods with spaces in their names.
0.2
  • Add -y flag to update and remove commands.
  • Recursively create config directory.
  • PyPI packaging.
0.1
  • Initial version.

fac's People

Contributors

csmith avatar mickael9 avatar zopieux avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

fac's Issues

Unable to install mods with spaces in the name

I can't seem to make fac install a mod with spaces in the name (such as Orbital Ion Cannon).

$ fac install "Orbital Ion Cannon"
Traceback (most recent call last):
File "/usr/local/bin/fac", line 9, in
load_entry_point('fac-cli==0.2', 'console_scripts', 'fac')()
File "/home/factorio/fac-cli/fac/main.py", line 57, in main
args.run(args)
File "/home/factorio/fac-cli/fac/commands/install.py", line 43, in run
req = list(parse_requirements(req))[0]
File "/usr/lib/python3/dist-packages/pkg_resources/init.py", line 2930, in parse_requirements
"version spec")
File "/usr/lib/python3/dist-packages/pkg_resources/init.py", line 2895, in scan_list
raise RequirementParseError(msg, line, "at", line[p:])
pkg_resources.RequirementParseError: Expected version spec in Orbital Ion Cannon at Ion Cannon

Unable to find write path

 >fac -v
Traceback (most recent call last):
  File "/usr/bin/fac", line 11, in <module>
    sys.exit(main())
  File "/usr/lib/python3.5/site-packages/fac/main.py", line 44, in main
    manager = ModManager(api=api, config=config)
  File "/usr/lib/python3.5/site-packages/fac/mods.py", line 296, in __init__
    self.config.mods_path,
  File "/usr/lib/python3.5/site-packages/fac/files.py", line 178, in mods_path
    return os.path.join(self.factorio_write_path, 'mods')
  File "/usr/lib/python3.5/site-packages/fac/files.py", line 143, in factorio_write_path
    self.config_file
Exception: Can not find the factorio write path.
Please set the write-path variable in /home/steam/.config/fac/config.ini
> cat ~/.config/fac/config.ini                                                                                                                                                   
[paths]
data-path = /home/steam/factorio/data
write-path = /home/steam/factorio

> pwd
/home/steam/factorio

Handle newlines in mod names in list and update

fac list

Installed mods:
    A Sea Block Config 0.3.0

fac hold

Mods currently held:
    A
    Sea
    Block
    Config

config.ini

[mods]
hold = A
        Sea
        Block
        Config

List command doesn't show "held" or other status as the internal config doesn't handle newlines.

Update similarly cannot read held status of mods with newlines and asks to update them.

Suggestion for a modpack feauture

Hey! I think it would be amazing for a feauture that stores away a certain set of mods, maybe in a folder within the mods folder, which then is considered a modpack. Then the program could list the different modpacks by just listing the folders in the mods folder with mods in them, and the user could switch between by mv all zipfiles into the current modpack folder and cp the ones from the desired modpack.
example of usage:
fac listmodpacks
solocampaign
lazyman
privateserver
arumbas

fac chmodpack solocampaign
saving current modpack: lazyman...
loading modpack: solocampaign...

I hope this could be in the scope of the program.

Enable (only) mods used by a savegame

One thing that would be handy is to have the ability to enable the mods that are used in a specific savegame and disable all others. This way the savegame can be loaded immediately once Factorio is started instead of having to examine the savegame in Factorio to determine the mods used, shut down Factorio, and then use fac-cli to enable the appropriate mods.

"SteamApps" directory in Linux is in lowercase

Under Linux (at least on my system) the "SteamApps" directory is actually "steamapps", so fac-cli won't find the Factorio directory by default.

--- fac/files.py.steam	2017-05-26 16:26:49.141140930 -0400
+++ fac/files.py	2017-05-26 16:28:47.932448438 -0400
@@ -20,6 +20,10 @@
         user_data_dir('Steam', appauthor=False),
         os.path.join('SteamApps', 'common', 'Factorio'),
     ),
+    os.path.join(
+        user_data_dir('Steam', appauthor=False),
+        os.path.join('steamapps', 'common', 'Factorio'),
+    ),
 ]
 
 if sys.platform.startswith('win32'):

[RFC] Things to include in a prefix PR

I've been managing multiple instances of factorio for a while (for multiple servers with different versions and mod packs), and recently discovered this tool. While super-awesome (and having quite high-quality code, kudos to @mickael9), it doesn't quite fit my use case. I want to write a PR to manage multiple instances of factorio (call it prefixes, environments, modpacks, whatever), but anything this sweeping should involve some input from the original devs and community, not just having me vomit code everywhere (and having this wall of text under a comment seemed bad). If the response here is negative, I will try to oblige users' opinions or else keep a separate fork under a different name.

Desired features:

  • Support switching prefixes, which each have a completely different set of mods, but may or may not share game versions. This is selected by one of eg. fac activate <prefix> or fac -p <prefix> <command> (discussed below). The specification of a game version is optional, so prefixes can follow the default version to update many prefixes at once.
  • Some automated way of creating prefixes, including potentially downloading a specific version of factorio.
  • (Pipe dream) fac clone <server-url> to automatically generate or update a prefix and download the server's version of factorio and all mods that it is running. I've reverse-engineered enough of the factorio wire protocol to actually make this feasible, but the previous points must be addressed before this.

Points of Debate:

Selecting a Prefix:

  1. Command line flag fac -p <prefix> <command>
    This is the easiest to implement by far, but involves using a flag for every invocation of fac. This must be added every time, and missing the flag will result in applying the command to the default prefix. It is, however, very obvious and requires no magic or bash/zsh wizardry.

  2. Prefix activation via shell fac activate <prefix>
    This is the most convenient, but relies on the user having a compatible shell and involves additional setup. We'd need to force users to include the zsh script (and probably introduce a bash equivalent for compatibility). The active prefix is stored in an environment variable, and is unique per shell session. We also lose all hope of including windows users in a convenient fashion.

  3. Prefix activation via file fac activate <prefix>
    Like 2, but doesn't use shell functions but rather saves the current prefix to the config file. Far more compatible, but it introduces some non-obvious behavior since the prefix is global (per-user) rather than session-specific.

I am personally in favor of implementing both 1 and 2. Comments welcome!

Storing prefix configuration

Python's ConfigParser (what's currently used) has some really nice features for default and fallback values that can be used very well for prefixes..... but the current config file layout won't work well for this, since it wasn't designed with this in mind.

Note: things of the syntax ${foo} are left as-is in the config.ini and are handled automatically since Python is awesome.

Current Layout

[mods]
hold =

[paths]
data-path =
write-path =
  1. Tack it on and handle defaults manually
[mods]
hold =

[paths]
data-path =
write-path =

[some_prefix]
write-path = 
hold =
# data-path is noted to be missing, and manually read from [paths]

Each prefix gets a new section, and the old sections (mods/paths) stay. We'd need to manually handle fallbacks to default, though, which means special-casing each current variable. Alternatively, require all variables in every prefix (defaults looking like data-path=${paths:data-path})

  1. Change to let ConfigParser handle everything

New:

# auto-generated during first run.  
[DEFAULTS]
hold =
data-path =
write-path =

[some_prefix]
write-path = 
hold =
# data-path falls back to DEFAULTS

Migrated:

# From previous version
[mods]
hold =

[paths]
data-path =
write-path =

# auto-generated during migration.  
[DEFAULTS]
hold = ${mods:hold}
data-path = ${paths:data-path}
write-path = ${paths:write-path}


[some_prefix]
write-path = 
hold =
# data-path falls back to DEFAULTS, which points to [paths]

Each prefix gets a new section, and the old sections (mods/paths) stay. More future-proof and less code bloat, but we'd need to add the DEFAULT section with pointers to migrate existing config files.

What should be shared between prefixes?

Should settings be different between them (ie, separate write-path?). If factorio introduces another breaking change in config/ (last was 0.14 -> 0.15, last I checked), things will get migrated without warning and older versions won't be happy. Factorio is backwards-compatible, but not always forwards-compatible. Ditto for save files, although those should only occur on opening the save. Presumably, this should be able to be manually selected (ie. separate mod-path from write-path), but should the default be separate or combined?

New variables and defaults

No matter the defaults above, some new variables should be included:

  • executable-path: Path to factorio binary (since we have to have a run-from-prefix option, yeah?). Optionally overridden per prefix. Default: ${data-path}/../bin/x64/factorio[.exe]
  • mod-path: Path to mods directory. Should definitely be overridden per prefix. Default: ${prefix-base-path}/[prefix-name]/mods
  • prefix-base-path: Prefix storage directory, relative to fac config directory. Global. Default prefixes/
  • game-base-path: Factorio version storage directory, relative to fac config directory. Useful if you want to store it on a different drive. Global. Default game_versions/
  • username: Factorio credentials, used for game downloads. Global and optional.
  • password: Factorio credentials, used for game downloads. Global and optional. Also insecure, but hey, it's convenient.
  • password_cmd: Command to obtain the factorio password, presumably through some password manager or the system keychain. Mac users may get a default using /usr/bin/security, but someone will have to help testing there, since I don't own one.

This leaves the following directory layout. Thoughts?

 FAC_DIR/
  |--- config.ini
  |--- prefixes/ (default prefix-base-path)
  |        |--- prefix_1/ (separate game config)
  |        |         |--- mods/
  |        |         |--- player_data.json
  |        |         |--- config/
  |        |--- prefix_2/ (combined game config)
  |                  |--- mods/
  |--- game_versions/ (default game-base-path)
          |--- 0.15.4/
          |--- 0.16.20/
          |--- 0.16.20-headless/

Commands

The PR is going to add a lot of subcommands:

  • Creating prefixes
  • Listing prefixes
  • Removing prefixes
  • Switching to prefixes (depending on answers above)
  • Running the game in a prefix
  • Downloading/Updating current factorio version
  • Listing installed factorio versions
  • Removing a factorio version (or all unused)
  • (Eventually) syncing prefix from multiplayer server

That leaves a whopping 23 subcommands, and things like 'install' will get pretty ambiguous pretty quick. Is a restructure necessary ("fac mods enable modname", "fac game update 0.14", "fac prefix create prefixname", etc?). If so, this is a very breaking change. I'm going to use commands assuming no restructure like "fac makeprefix" in the meantime, but this should be considered.

ProgressWidget.error() <newbie here>

Hello,

I just want to preface this by saying I am new to GitHub, and rusty with coding so sorry if my question is dumb or the wrong format. I am trying to use your fantastic tool to easily update my server when able.

It works for the most part. One issue I'm having trouble with is the update command. My factorio path is in the root folder -> srv/FactorioServer/factorio. The install command has the same error

Your tool is installed in /srv/FactorioServer/factorio/src/fac-cli...

I tried to make sure the folder is owned by my user, as it didn't work by default (all child folders/files as well). Not sure where to start with your code to try and fix/alter for the error. If I don't run with sudo I get a permission error. What do I need to do to make it work? Anything I can clarify?

The error:
david@David-Server:/srv/FactorioServer/factorio$ sudo fac update
Downloading mod database... 100 %
Building search index...
Updated mods database (10473 mods)
Checking: Mechanicus
Checking: WaterWell
Checking: Factorissimo2
Checking: AtomicArtillery
Checking: MaxRateCalculator
Checking: space-exploration-graphics-3
Checking: textplates
Checking: EpicArtillerySounds
Checking: stdlib
Checking: Milestones
Found update: Milestones 1.3.12
Found 1 update:
Milestones 1.3.8 -> 1.3.12
Continue? [Y/n] Y
Downloading: Milestones_1.3.12.zip... error
Traceback (most recent call last):
File "/usr/local/bin/fac", line 33, in
sys.exit(load_entry_point('fac-cli', 'console_scripts', 'fac')())
File "/srv/FactorioServer/factorio/src/fac-cli/fac/main.py", line 88, in main
args.run(args)
File "/srv/FactorioServer/factorio/src/fac-cli/fac/commands/update.py", line 88, in run
self.manager.install_mod(local_mod.name, release)
File "/srv/FactorioServer/factorio/src/fac-cli/fac/mods.py", line 508, in install_mod
self.download_mod(release, tmp_file)
File "/srv/FactorioServer/factorio/src/fac-cli/fac/mods.py", line 545, in download_mod
progress.error()
TypeError: ProgressWidget.error() missing 1 required positional argument: 'exc'

david@David-Server:/srv/FactorioServer/factorio/src/fac-cli$ ll
total 76
drwxrwxr-x 7 david david 4096 Nov 25 11:02 ./
drwxrwxr-x 3 david david 4096 Nov 25 11:02 ../
drwxrwxr-x 4 david david 4096 Nov 25 11:24 fac/
drwxrwxr-x 2 david david 4096 Nov 25 11:17 fac_cli.egg-info/
drwxrwxr-x 8 david david 4096 Nov 25 11:17 .git/
-rw-rw-r-- 1 david david 47 Nov 25 11:02 .gitignore
-rw-rw-r-- 1 david david 1082 Nov 25 11:02 LICENSE
-rw-rw-r-- 1 david david 74 Nov 25 11:02 MANIFEST.in
-rw-rw-r-- 1 david david 13841 Nov 25 11:02 README.bbcode
-rw-rw-r-- 1 david david 14390 Nov 25 11:02 README.rst
-rw-rw-r-- 1 david david 1113 Nov 25 11:02 setup.py
drwxrwxr-x 2 david david 4096 Nov 25 11:02 test/
drwxrwxr-x 2 david david 4096 Nov 25 11:02 zsh/
david@David-Server:/srv/FactorioServer/factorio/src/fac-cli$

Update PyPi release

I'm aware that there is an warning in that the search does not work. I thought I'd make an issue to be able to collect and discuss the information regarding this.

Why can't we just search ourselves? ie, get the full list of mods available and filter them client side?

The version on PyPi is not the latest one (even though it is 0.9, the same as the current one) and it does not include a working search implementation. Could we bump this version and upload it to PyPi?

Update loop stops on first held mod that is updatable

Held mods update block uses break where it should use continue like the unpacked block.

                if not args.held and local_mod.name in self.config.hold:
                    print("%s is held. "
                          "Use -H to update it anyway." %
                          local_mod.name)
                    break

The above should use break like the on below does. Links above link to the relevant lines.

                if not args.unpacked and not local_mod.packed:
                    print(
                        "%s is unpacked. "
                        "Use -U to update it anyway." % (
                            local_mod.name
                        )
                    )
                    continue

AttributeError: 'ZippedMod' object has no attribute 'factorio_version'

From clean start (fac remove '*'):

fac install boblogistics
fac install bobwarfare

The second one fails with

Traceback (most recent call last):
  File "c:\programdata\chocolatey\lib\python3-x86_32\tools\lib\runpy.py", line 184, in _run_module_as_main
    "__main__", mod_spec)
  File "c:\programdata\chocolatey\lib\python3-x86_32\tools\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\gtk-build\python-3.5\Win32\Scripts\fac.exe\__main__.py", line 9, in <module>
  File "c:\programdata\chocolatey\lib\python3-x86_32\tools\lib\site-packages\fac\main.py", line 84, in main
    args.run(args)
  File "c:\programdata\chocolatey\lib\python3-x86_32\tools\lib\site-packages\fac\commands\install.py", line 124, in run
    ignore_game_ver=args.ignore_game_ver):
  File "c:\programdata\chocolatey\lib\python3-x86_32\tools\lib\site-packages\fac\mods.py", line 370, in resolve_local_requirement
    res = [mod for mod in self.find_mods(req.name)
  File "c:\programdata\chocolatey\lib\python3-x86_32\tools\lib\site-packages\fac\mods.py", line 372, in <listcomp>
    (ignore_game_ver or mod.factorio_version == game_ver)]
AttributeError: 'ZippedMod' object has no attribute 'factorio_version'

mod.factorio_version should be mod.game_version ?

Make compatible does not work

For example:

C:\Users\User>fac install UPS-up -i
Installing: UPS-up 0.2.2...
Downloading: UPS-up_0.2.2.zip... 100 %

C:\Users\User>fac make-compatible UPS-up
Unpacking: C:\Users\User\AppData\Roaming\Factorio\mods\UPS-up_0.2.2.zip
Removing file: C:\Users\User\AppData\Roaming\Factorio\mods\UPS-up_0.2.2.zip
Game version changed to 0.16 for UPS-up 0.2.2.
Traceback (most recent call last):
  File "c:\python\lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "c:\python\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Python\Scripts\fac.exe\__main__.py", line 9, in <module>
  File "c:\python\lib\site-packages\fac\main.py", line 88, in main
    args.run(args)
  File "c:\python\lib\site-packages\fac\commands\make_compatible.py", line 39, in run
    mod.info.save()
  File "c:\python\lib\site-packages\fac\files.py", line 252, in save
    json.dump(self.data, f, indent=4)
  File "c:\python\lib\json\__init__.py", line 179, in dump
    for chunk in iterable:
  File "c:\python\lib\json\encoder.py", line 431, in _iterencode
    yield from _iterencode_dict(o, _current_indent_level)
  File "c:\python\lib\json\encoder.py", line 405, in _iterencode_dict
    yield from chunks
  File "c:\python\lib\json\encoder.py", line 438, in _iterencode
    o = _default(o)
  File "c:\python\lib\json\encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Version is not JSON serializable

and the contents of C:\Users\User\AppData\Roaming\Factorio\mods\UPS-up_0.2.2\info.json:

{
    "name": "UPS-up",
    "version": "0.2.2",
    "factorio_version": 

It's strange that it doesn't even have the closing bracket, and this is happening with all my incompatible mods.

Prefix Feature

I seem to recall something like this available in Wine (Windows compatibility layer for Linux). Essentially, a core of factorio but the ability to swap out the currently active one. So you may have one called "design" which may include mods like Creative Mode where you design your blueprints, one called "fourteen" for a series you are busy completing for YouTube on the 0.14 release and one called "Bleeding" on the bleeding edge of 0.15 where you have some fun. Each has it's own set of active mods.

fac activate bleeding

Now you can use fac as usual and its operations apply to the active version.

If ~/.local.bin/factorio is a symbolic link to the binary, the active prefix will always run as expected.

Should check status code from requests.get() first in download_mod()

I ran fac install hacked-splitters and it failed with:

Traceback (most recent call last):
  File "c:\programdata\chocolatey\lib\python3-x86_32\tools\lib\runpy.py", line 184, in _run_module_as_main
    "__main__", mod_spec)
  File "c:\programdata\chocolatey\lib\python3-x86_32\tools\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\gtk-build\python-3.5\Win32\Scripts\fac.exe\__main__.py", line 9, in <module>
  File "c:\programdata\chocolatey\lib\python3-x86_32\tools\lib\site-packages\fac\main.py", line 84, in main
    args.run(args)
  File "c:\programdata\chocolatey\lib\python3-x86_32\tools\lib\site-packages\fac\commands\install.py", line 158, in run
    self.manager.install_mod(release, unpack=args.unpack)
  File "c:\programdata\chocolatey\lib\python3-x86_32\tools\lib\site-packages\fac\mods.py", line 476, in install_mod
    self.download_mod(release, tmp_file)
  File "c:\programdata\chocolatey\lib\python3-x86_32\tools\lib\site-packages\fac\mods.py", line 515, in download_mod
    len(data), release.file_size
Exception: Downloaded file has incorrect size (0), expected 40119.

I added a print('%s' % req) in download_mod and get <Response [403]>. So basically the download request returned a 0-byte 403 response. You should probably also verify that the response status code is 200 before data = req.content, etc

(I'm still investigating why I'm getting a 403 there at all... The 403 is because this is a new account and I haven't connected it to my Steam account yet. Logging in to mods.factorio.com in a web browser gives me This account doesn't have a sufficient membership. If you bought the game on Steam, you need to connect your Steam account to your factorio.com account.)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.